<commit_before>/* Copyright (c) 2011, NEC Europe Ltd, Consorzio Nazionale
 * Interuniversitario per le Telecomunicazioni. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *    * Redistributions of source code must retain the above copyright
 *      notice, this list of conditions and the following disclaimer.
 *    * Redistributions in binary form must reproduce the above copyright
 *      notice, this list of conditions and the following disclaimer in the
 *      documentation and/or other materials provided with the distribution.
 *    * Neither the names of NEC Europe Ltd, Consorzio Nazionale
 *      Interuniversitario per le Telecomunicazioni nor the names of its contributors
 *      may be used to endorse or promote products derived from this software
 *      without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT
 * HOLDERBE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
 */

#include <Block.hpp>
#include <BlockFactory.hpp>
#include <cstdio>
#include <Tweet.hpp>
#include <vector>
#include <WordRecord.hpp>

#include <boost/algorithm/string.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/algorithm/string.hpp>

#ifdef _USE_JSMN_LIBRARY
#include <jsmn.h>
#endif
#include <stdlib.h>
#include <string.h>

namespace blockmon
{

     /**
      * Implements a block that receives tweets
      */
     class TweetFinder: public Block
     {
     private:
        int m_msg_recv;
        unsigned int m_reset;
        uint32_t m_msg_type;
        int num_gates;
        long sentMessages;
        long sentTuple;
        long ignored;
        int m_ingate_id;
        int *m_outgate_ids;
        std::vector<std::shared_ptr< WordRecord > > hashtag_batch;
        struct timeval lasttime;
        std::hash<std::string> hash_fn;
        long receivedTweets;
        timeval firsttime;
    #define ALLOC_TOKEN 10
        int allocated_tokens;
        #ifdef _USE_JSMN_LIBRARY
        jsmn_parser parser;
        jsmntok_t *tokens;
        #endif
        long hashtag_found;
        long tweet_found;
     public:

        /**
        * @brief Constructor
        * @param name         The name of the packet counter block
        * @param invocation   Invocation type of the block (Indirect, Direct, Async)
        */
        TweetFinder(const std::string &name, invocation_type invocation)
            : Block(name, invocation),
            m_ingate_id(register_input_gate("in_word")),
            receivedTweets(0),
            allocated_tokens(0),
            #ifdef /* Copyright (c) 2011, NEC Europe Ltd, Consorzio Nazionale
 * Interuniversitario per le Telecomunicazioni, Institut
 * Telecom/Telecom Bretagne, ETH Zürich, INVEA-TECH a.s. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *    * Redistributions of source code must retain the above copyright
 *      notice, this list of conditions and the following disclaimer.
 *    * Redistributions in binary form must reproduce the above copyright
 *      notice, this list of conditions and the following disclaimer in the
 *      documentation and/or other materials provided with the distribution.
 *    * Neither the names of NEC Europe Ltd, Consorzio Nazionale
 *      Interuniversitario per le Telecomunicazioni, Institut Telecom/Telecom
 *      Bretagne, ETH Zürich, INVEA-TECH a.s. nor the names of its contributors
 *      may be used to endorse or promote products derived from this software
 *      without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT
 * HOLDERBE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
 */_USE_JSMN_LIBRARY
            tokens(NULL),
            #endif
            hashtag_found(0),
            tweet_found(0)
        {
            m_reset = 0;
            m_msg_type = type_to_id<Tweet>::id();
        }

       /**
        * @brief Destructor
        */
        ~TweetFinder()  {}

        /**
        * @brief Configures the block.
        * @param n The configuration parameters
        */
        void _configure(const pugi::xml_node&  n)
        {
            #ifndef _USE_JSMN_LIBRARY
            throw std::runtime_error("Twitter Trending was compiled without JSMN parser");
            #endif

            pugi::xml_node gates_node=n.child("gates");
            if(!gates_node)
                throw std::runtime_error("TweetFinder: missing node gates");
            std::string gates_s=gates_node.attribute("number").value();
            if(!gates_s.length())
                throw std::runtime_error("TweetFinder: missing attribute number");

            num_gates = atoi(gates_s.c_str());
            std::string outgate_basename = "out_hash";
            m_outgate_ids = new int[num_gates];
            for(int i=0; i<num_gates; i++) {
                std::string ogate = outgate_basename + boost::lexical_cast<std::string>(i);
                m_outgate_ids[i] = register_output_gate(ogate.c_str());
                std::shared_ptr< WordRecord > m(new WordRecord());
                hashtag_batch.push_back(m);
            }
        }

        /**
        * @brief Initialize the block
        */
        void _initialize()
        {}

        /**
        * If the message received is not of type RawPacket throw an exception,
        * otherwise count it
        * @param m The message
        * @param index The index of the gate the message came on
        */
        void _receive_msg(std::shared_ptr<const Msg>&& m, int /* index */)
        {
            if(m->type() != m_msg_type ) {
                throw std::runtime_error("TweetFinder::wrong message type");
            }

            if(receivedTweets == 0) {
                gettimeofday(&firsttime, NULL);
            }

            #ifdef _USE_JSMN_LIBRARY
            const Tweet* msg_ptr = static_cast<const Tweet *>(m.get());

            // Parse the tweet
            jsmn_init(&parser);
            while(1) {
                const char* buf = msg_ptr->get_tweet().c_str();
                int r = jsmn_parse(&parser, buf, tokens, allocated_tokens);
                if(r == JSMN_SUCCESS) {
                    // now loop to find the "text" part
                    // we check one token over two, for every JSMN_STRING check if it
                    // contains "text"
                    if(tokens[0].type != JSMN_OBJECT) {
                        ignored++;
                        //std::cerr << "No object found in tweet" << std::endl;
                        break;
                    }

                    int size = tokens[0].size;

                    int jj;
                    for(jj = 0; jj < size; jj += 2) {
                        if(tokens[1 + jj].type == JSMN_STRING && tokens[2 + jj].type == JSMN_STRING) {
                            if(!strncmp(buf + tokens[1 + jj].start, "text", 4)) {
                                tweet_found++;
                                char tmpbuf[16384];
                                int jcn;
                                for(jcn = tokens[2 + jj].start; jcn < tokens[2 + jj].end; jcn++) {
                                    if(buf[jcn] == '#') {
                                        break;
                                    }
                                }
                                if(jcn < tokens[2 + jj].end) {
                                    hashtag_found++;
                                    int jcn_start = jcn;
                                    jcn++;
                                    int hashtag_len = 1;
                                    while(jcn < tokens[2 + jj].end) {
                                        if(!isalnum(buf[jcn]))
                                            break;
                                        jcn++;
                                        hashtag_len++;
                                    }
                                    strncpy(tmpbuf, buf + jcn_start, hashtag_len);
                                    tmpbuf[hashtag_len] = 0;
                                    size_t val_hash = hash_fn((tmpbuf));
                                    int ogate = val_hash % num_gates;
                                    hashtag_batch[ogate]->add_word(std::string(tmpbuf));
#define BATH_SIZE 200
                                    if(hashtag_batch[ogate]->get_word_number() >= BATH_SIZE) {
                                        sentTuple++;
                                        sentMessages += BATH_SIZE;
                                        send_out_through(move(hashtag_batch[ogate]), m_outgate_ids[ogate]);
                                        std::shared_ptr< WordRecord > m(new WordRecord());
                                        hashtag_batch.at(ogate) = m;
                                    }

                                }
                                break;
                            }
                        }
                    }
                        break;
                } else if(r == JSMN_ERROR_NOMEM) {
                    std::cerr << "Reallocating tokens" << std::endl;
                    allocated_tokens += ALLOC_TOKEN;
                    tokens = (jsmntok_t*) realloc(tokens, sizeof(jsmntok_t) * allocated_tokens);
                    if(tokens == NULL) {
                        throw std::runtime_error("Can not allocate memory\n");
                    }
                    continue;
                } else if(r == JSMN_ERROR_INVAL) {
                    break;
                } else if(r == JSMN_ERROR_PART) {
                    break;
                } else {
                    throw std::runtime_error("Unknown error from jsmn\n");
                }
            }
            #endif

            receivedTweets++;
            m_msg_recv++;
        }
     };
     REGISTER_BLOCK(TweetFinder, "TweetFinder");
}
<commit_msg>Cleanup<commit_after>/* Copyright (c) 2011, NEC Europe Ltd, Consorzio Nazionale
 * Interuniversitario per le Telecomunicazioni. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *    * Redistributions of source code must retain the above copyright
 *      notice, this list of conditions and the following disclaimer.
 *    * Redistributions in binary form must reproduce the above copyright
 *      notice, this list of conditions and the following disclaimer in the
 *      documentation and/or other materials provided with the distribution.
 *    * Neither the names of NEC Europe Ltd, Consorzio Nazionale
 *      Interuniversitario per le Telecomunicazioni nor the names of its contributors
 *      may be used to endorse or promote products derived from this software
 *      without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT
 * HOLDERBE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
 */

#include <Block.hpp>
#include <BlockFactory.hpp>
#include <cstdio>
#include <Tweet.hpp>
#include <vector>
#include <WordRecord.hpp>

#include <boost/algorithm/string.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/algorithm/string.hpp>

#ifdef _USE_JSMN_LIBRARY
#include <jsmn.h>
#endif
#include <stdlib.h>
#include <string.h>

namespace blockmon
{

     /**
      * Implements a block that receives tweets
      */
     class TweetFinder: public Block
     {
     private:
        int m_msg_recv;
        unsigned int m_reset;
        uint32_t m_msg_type;
        int num_gates;
        long sentMessages;
        long sentTuple;
        long ignored;
        int m_ingate_id;
        int *m_outgate_ids;
        std::vector<std::shared_ptr< WordRecord > > hashtag_batch;
        struct timeval lasttime;
        std::hash<std::string> hash_fn;
        long receivedTweets;
        timeval firsttime;
    #define ALLOC_TOKEN 10
        int allocated_tokens;
        #ifdef _USE_JSMN_LIBRARY
        jsmn_parser parser;
        jsmntok_t *tokens;
        #endif
        long hashtag_found;
        long tweet_found;
     public:

        /**
        * @brief Constructor
        * @param name         The name of the packet counter block
        * @param invocation   Invocation type of the block (Indirect, Direct, Async)
        */
        TweetFinder(const std::string &name, invocation_type invocation)
            : Block(name, invocation),
            m_ingate_id(register_input_gate("in_word")),
            receivedTweets(0),
            allocated_tokens(0),
            #ifdef _USE_JSMN_LIBRARY
            tokens(NULL),
            #endif
            hashtag_found(0),
            tweet_found(0)
        {
            m_reset = 0;
            m_msg_type = type_to_id<Tweet>::id();
        }

       /**
        * @brief Destructor
        */
        ~TweetFinder()  {}

        /**
        * @brief Configures the block.
        * @param n The configuration parameters
        */
        void _configure(const pugi::xml_node&  n)
        {
            #ifndef _USE_JSMN_LIBRARY
            throw std::runtime_error("Twitter Trending was compiled without JSMN parser");
            #endif

            pugi::xml_node gates_node=n.child("gates");
            if(!gates_node)
                throw std::runtime_error("TweetFinder: missing node gates");
            std::string gates_s=gates_node.attribute("number").value();
            if(!gates_s.length())
                throw std::runtime_error("TweetFinder: missing attribute number");

            num_gates = atoi(gates_s.c_str());
            std::string outgate_basename = "out_hash";
            m_outgate_ids = new int[num_gates];
            for(int i=0; i<num_gates; i++) {
                std::string ogate = outgate_basename + boost::lexical_cast<std::string>(i);
                m_outgate_ids[i] = register_output_gate(ogate.c_str());
                std::shared_ptr< WordRecord > m(new WordRecord());
                hashtag_batch.push_back(m);
            }
        }

        /**
        * @brief Initialize the block
        */
        void _initialize()
        {}

        /**
        * If the message received is not of type RawPacket throw an exception,
        * otherwise count it
        * @param m The message
        * @param index The index of the gate the message came on
        */
        void _receive_msg(std::shared_ptr<const Msg>&& m, int /* index */)
        {
            if(m->type() != m_msg_type ) {
                throw std::runtime_error("TweetFinder::wrong message type");
            }

            if(receivedTweets == 0) {
                gettimeofday(&firsttime, NULL);
            }

            #ifdef _USE_JSMN_LIBRARY
            const Tweet* msg_ptr = static_cast<const Tweet *>(m.get());

            // Parse the tweet
            jsmn_init(&parser);
            while(1) {
                const char* buf = msg_ptr->get_tweet().c_str();
                int r = jsmn_parse(&parser, buf, tokens, allocated_tokens);
                if(r == JSMN_SUCCESS) {
                    // now loop to find the "text" part
                    // we check one token over two, for every JSMN_STRING check if it
                    // contains "text"
                    if(tokens[0].type != JSMN_OBJECT) {
                        ignored++;
                        //std::cerr << "No object found in tweet" << std::endl;
                        break;
                    }

                    int size = tokens[0].size;

                    int jj;
                    for(jj = 0; jj < size; jj += 2) {
                        if(tokens[1 + jj].type == JSMN_STRING && tokens[2 + jj].type == JSMN_STRING) {
                            if(!strncmp(buf + tokens[1 + jj].start, "text", 4)) {
                                tweet_found++;
                                char tmpbuf[16384];
                                int jcn;
                                for(jcn = tokens[2 + jj].start; jcn < tokens[2 + jj].end; jcn++) {
                                    if(buf[jcn] == '#') {
                                        break;
                                    }
                                }
                                if(jcn < tokens[2 + jj].end) {
                                    hashtag_found++;
                                    int jcn_start = jcn;
                                    jcn++;
                                    int hashtag_len = 1;
                                    while(jcn < tokens[2 + jj].end) {
                                        if(!isalnum(buf[jcn]))
                                            break;
                                        jcn++;
                                        hashtag_len++;
                                    }
                                    strncpy(tmpbuf, buf + jcn_start, hashtag_len);
                                    tmpbuf[hashtag_len] = 0;
                                    size_t val_hash = hash_fn((tmpbuf));
                                    int ogate = val_hash % num_gates;
                                    hashtag_batch[ogate]->add_word(std::string(tmpbuf));
#define BATH_SIZE 200
                                    if(hashtag_batch[ogate]->get_word_number() >= BATH_SIZE) {
                                        sentTuple++;
                                        sentMessages += BATH_SIZE;
                                        send_out_through(move(hashtag_batch[ogate]), m_outgate_ids[ogate]);
                                        std::shared_ptr< WordRecord > m(new WordRecord());
                                        hashtag_batch.at(ogate) = m;
                                    }

                                }
                                break;
                            }
                        }
                    }
                        break;
                } else if(r == JSMN_ERROR_NOMEM) {
                    std::cerr << "Reallocating tokens" << std::endl;
                    allocated_tokens += ALLOC_TOKEN;
                    tokens = (jsmntok_t*) realloc(tokens, sizeof(jsmntok_t) * allocated_tokens);
                    if(tokens == NULL) {
                        throw std::runtime_error("Can not allocate memory\n");
                    }
                    continue;
                } else if(r == JSMN_ERROR_INVAL) {
                    break;
                } else if(r == JSMN_ERROR_PART) {
                    break;
                } else {
                    throw std::runtime_error("Unknown error from jsmn\n");
                }
            }
            #endif

            receivedTweets++;
            m_msg_recv++;
        }
     };
     REGISTER_BLOCK(TweetFinder, "TweetFinder");
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: frmdir.hxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: vg $ $Date: 2007-04-11 15:54:47 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef _SVX_FRMDIR_HXX
#define _SVX_FRMDIR_HXX

// ----------------------------------------------------------------------------

/** Defines possible text directions in frames. */
enum SvxFrameDirection
{
    /** Horizontal, from left to right, from top to bottom
        (typical for western languages). */
    FRMDIR_HORI_LEFT_TOP,

    /** Horizontal, from right to left, from top to bottom
        (typical for ararbic/hebrew languages). */
    FRMDIR_HORI_RIGHT_TOP,

    /** Vertical, from top to bottom, from right to left
        (typical for asian languages). */
    FRMDIR_VERT_TOP_RIGHT,

    /** Vertical, from top to bottom, from left to right
        (typical for mongol language). */
    FRMDIR_VERT_TOP_LEFT,

    /** Use the value from the environment, can only be used in frames. */
    FRMDIR_ENVIRONMENT
};

// ----------------------------------------------------------------------------

#endif // #ifndef _SVX_FRMDIR_HXX

<commit_msg>INTEGRATION: CWS changefileheader (1.2.466); FILE MERGED 2008/03/31 14:18:12 rt 1.2.466.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: frmdir.hxx,v $
 * $Revision: 1.3 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#ifndef _SVX_FRMDIR_HXX
#define _SVX_FRMDIR_HXX

// ----------------------------------------------------------------------------

/** Defines possible text directions in frames. */
enum SvxFrameDirection
{
    /** Horizontal, from left to right, from top to bottom
        (typical for western languages). */
    FRMDIR_HORI_LEFT_TOP,

    /** Horizontal, from right to left, from top to bottom
        (typical for ararbic/hebrew languages). */
    FRMDIR_HORI_RIGHT_TOP,

    /** Vertical, from top to bottom, from right to left
        (typical for asian languages). */
    FRMDIR_VERT_TOP_RIGHT,

    /** Vertical, from top to bottom, from left to right
        (typical for mongol language). */
    FRMDIR_VERT_TOP_LEFT,

    /** Use the value from the environment, can only be used in frames. */
    FRMDIR_ENVIRONMENT
};

// ----------------------------------------------------------------------------

#endif // #ifndef _SVX_FRMDIR_HXX

<|endoftext|>


<commit_before>/*
 * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Affero General Public License as published by the
 * Free Software Foundation; either version 3 of the License, or (at your
 * option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for
 * more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program. If not, see <http://www.gnu.org/licenses/>.
 */

#include "dire_maul.h"
#include "InstanceScript.h"
#include "ScriptMgr.h"

class instance_dire_maul : public InstanceMapScript
{
public:
    instance_dire_maul() : InstanceMapScript("instance_dire_maul", 429) { }

    struct instance_dire_maul_InstanceMapScript : public InstanceScript
    {
        instance_dire_maul_InstanceMapScript(Map* map) : InstanceScript(map) { }

        void Initialize() override
        {
            _eastWingProgress = 0;
            _westWingProgress = 0;
            _pylonsState = 0;
            _northWingProgress = 0;
            _northWingBosses = 0;
        }

        void OnCreatureCreate(Creature* creature) override
        {
            switch (creature->GetEntry())
            {
                case NPC_IMMOL_THAR:
                    _immoltharGUID = creature->GetGUID();
                    break;
                case NPC_HIGHBORNE_SUMMONER:
                    if (_pylonsState == ALL_PYLONS_OFF)
                        creature->DespawnOrUnsummon(5000);
                    break;
            }
        }

        void OnGameObjectCreate(GameObject* gameobject) override
        {
            switch (gameobject->GetEntry())
            {
                case GO_DIRE_MAUL_FORCE_FIELD:
                    if (_pylonsState == ALL_PYLONS_OFF)
                        gameobject->SetGoState(GO_STATE_ACTIVE);
                    break;
                case GO_GORDOK_TRIBUTE:
                    {
                        uint32 fullLootMode = 0x3F;
                        for (uint32 i = 0; i < _northWingBosses; ++i)
                            fullLootMode >>= 1;

                        gameobject->SetLootMode(fullLootMode);
                        break;
                    }
            }
        }

        void SetData(uint32 type, uint32 data) override
        {
            switch (type)
            {
                case TYPE_EAST_WING_PROGRESS:
                    _eastWingProgress = data;
                    instance->LoadGrid(-56.59f, -269.12f);
                    break;
                case TYPE_WEST_WING_PROGRESS:
                    _westWingProgress = data;
                    instance->LoadGrid(132.626f, 625.913f);
                    break;
                case TYPE_NORTH_WING_PROGRESS:
                    _northWingProgress = data;
                    break;
                case TYPE_NORTH_WING_BOSSES:
                    _northWingBosses |= (1 << _northWingBosses);
                    break;
                case TYPE_PYLONS_STATE:
                    if (_pylonsState & data)
                        return;
                    _pylonsState |= data;
                    if (_pylonsState == ALL_PYLONS_OFF) // all five active, 31
                    {
                        instance->LoadGrid(-38.08f, 812.44f);
                        if (Creature* immol = instance->GetCreature(_immoltharGUID))
                        {
                            immol->setActive(true);
                            immol->GetAI()->SetData(1, 1);
                        }
                    }
                    break;
            }

            SaveToDB();
        }

        uint32 GetData(uint32 type) const override
        {
            if (type == TYPE_EAST_WING_PROGRESS)
                return _eastWingProgress;
            else if (type == TYPE_WEST_WING_PROGRESS)
                return _westWingProgress;
            else if (type == TYPE_NORTH_WING_PROGRESS)
                return _northWingProgress;

            return 0;
        }

        std::string GetSaveData() override
        {
            std::ostringstream saveStream;
            saveStream << "D M " << _eastWingProgress << ' ' << _westWingProgress << ' ' << _pylonsState << ' ' << _northWingProgress << ' ' << _northWingBosses;
            return saveStream.str();
        }

        void Load(const char* in) override
        {
            if (!in)
                return;

            char dataHead1, dataHead2;
            std::istringstream loadStream(in);
            loadStream >> dataHead1 >> dataHead2;
            if (dataHead1 == 'D' && dataHead2 == 'M')
            {
                loadStream >> _eastWingProgress;
                loadStream >> _westWingProgress;
                loadStream >> _pylonsState;
                loadStream >> _northWingProgress;
                loadStream >> _northWingBosses;
            }
        }

    private:
        uint32 _eastWingProgress;
        uint32 _westWingProgress;
        uint32 _pylonsState;
        uint32 _northWingProgress;
        uint32 _northWingBosses;

        ObjectGuid _immoltharGUID;
    };

    InstanceScript* GetInstanceScript(InstanceMap* map) const override
    {
        return new instance_dire_maul_InstanceMapScript(map);
    }
};

void AddSC_instance_dire_maul()
{
    new instance_dire_maul();
}
<commit_msg>fix(Scripts/DireMaul): immolthar and adds are now immune to combat until the pylons are activated (#9007)<commit_after>/*
 * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Affero General Public License as published by the
 * Free Software Foundation; either version 3 of the License, or (at your
 * option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for
 * more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program. If not, see <http://www.gnu.org/licenses/>.
 */

#include "dire_maul.h"
#include "InstanceScript.h"
#include "ScriptMgr.h"

class instance_dire_maul : public InstanceMapScript
{
public:
    instance_dire_maul() : InstanceMapScript("instance_dire_maul", 429) { }

    struct instance_dire_maul_InstanceMapScript : public InstanceScript
    {
        instance_dire_maul_InstanceMapScript(Map* map) : InstanceScript(map) { }

        void Initialize() override
        {
            _eastWingProgress = 0;
            _westWingProgress = 0;
            _pylonsState = 0;
            _northWingProgress = 0;
            _northWingBosses = 0;
            HighborneSummoners.clear();
        }

        void OnCreatureCreate(Creature* creature) override
        {
            switch (creature->GetEntry())
            {
                case NPC_IMMOL_THAR:
                    _immoltharGUID = creature->GetGUID();
                    if (_pylonsState == ALL_PYLONS_OFF)
                    {
                        creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
                    }
                    else
                    {
                        creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
                    }
                    break;
                case NPC_HIGHBORNE_SUMMONER:
                    if (_pylonsState == ALL_PYLONS_OFF)
                    {
                        creature->DespawnOrUnsummon(5000);
                    }
                    else
                    {
                        creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
                    }
                    HighborneSummoners.push_back(creature->GetGUID());
                    break;
            }
        }

        void OnGameObjectCreate(GameObject* gameobject) override
        {
            switch (gameobject->GetEntry())
            {
                case GO_DIRE_MAUL_FORCE_FIELD:
                    if (_pylonsState == ALL_PYLONS_OFF)
                        gameobject->SetGoState(GO_STATE_ACTIVE);
                    break;
                case GO_GORDOK_TRIBUTE:
                    {
                        uint32 fullLootMode = 0x3F;
                        for (uint32 i = 0; i < _northWingBosses; ++i)
                            fullLootMode >>= 1;

                        gameobject->SetLootMode(fullLootMode);
                        break;
                    }
            }
        }

        void SetData(uint32 type, uint32 data) override
        {
            switch (type)
            {
                case TYPE_EAST_WING_PROGRESS:
                    _eastWingProgress = data;
                    instance->LoadGrid(-56.59f, -269.12f);
                    break;
                case TYPE_WEST_WING_PROGRESS:
                    _westWingProgress = data;
                    instance->LoadGrid(132.626f, 625.913f);
                    break;
                case TYPE_NORTH_WING_PROGRESS:
                    _northWingProgress = data;
                    break;
                case TYPE_NORTH_WING_BOSSES:
                    _northWingBosses |= (1 << _northWingBosses);
                    break;
                case TYPE_PYLONS_STATE:
                    if (_pylonsState & data)
                        return;
                    _pylonsState |= data;
                    if (_pylonsState == ALL_PYLONS_OFF) // all five active, 31
                    {
                        instance->LoadGrid(-38.08f, 812.44f);
                        if (Creature* immol = instance->GetCreature(_immoltharGUID))
                        {
                            immol->setActive(true);
                            immol->GetAI()->SetData(1, 1);
                            immol->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
                        }
                        for (const auto& guid : HighborneSummoners)
                        {
                            if (Creature* summoner = instance->GetCreature(guid))
                            {
                                summoner->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
                            }
                        }
                    }
                    break;
            }

            SaveToDB();
        }

        uint32 GetData(uint32 type) const override
        {
            if (type == TYPE_EAST_WING_PROGRESS)
                return _eastWingProgress;
            else if (type == TYPE_WEST_WING_PROGRESS)
                return _westWingProgress;
            else if (type == TYPE_NORTH_WING_PROGRESS)
                return _northWingProgress;

            return 0;
        }

        std::string GetSaveData() override
        {
            std::ostringstream saveStream;
            saveStream << "D M " << _eastWingProgress << ' ' << _westWingProgress << ' ' << _pylonsState << ' ' << _northWingProgress << ' ' << _northWingBosses;
            return saveStream.str();
        }

        void Load(const char* in) override
        {
            if (!in)
                return;

            char dataHead1, dataHead2;
            std::istringstream loadStream(in);
            loadStream >> dataHead1 >> dataHead2;
            if (dataHead1 == 'D' && dataHead2 == 'M')
            {
                loadStream >> _eastWingProgress;
                loadStream >> _westWingProgress;
                loadStream >> _pylonsState;
                loadStream >> _northWingProgress;
                loadStream >> _northWingBosses;
            }
        }

    private:
        uint32 _eastWingProgress;
        uint32 _westWingProgress;
        uint32 _pylonsState;
        uint32 _northWingProgress;
        uint32 _northWingBosses;

        ObjectGuid _immoltharGUID;
        std::vector<ObjectGuid> HighborneSummoners;
    };

    InstanceScript* GetInstanceScript(InstanceMap* map) const override
    {
        return new instance_dire_maul_InstanceMapScript(map);
    }
};

void AddSC_instance_dire_maul()
{
    new instance_dire_maul();
}
<|endoftext|>


<commit_before>// Copyright 2018 The GraphicsFuzz Project Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Entry point on Android

#include <android_native_app_glue.h>
#include "vulkan_worker.h"
#include "platform.h"

#include <assert.h>
#include <string>
#include <sstream>
#include <iostream>

typedef struct AppData {
  VulkanWorker *vulkan_worker;
  PlatformData *platform_data;
  FILE *vertex_file;
  FILE *fragment_file;
  FILE *uniform_file;
} AppData;

void ProcessAppCmd (struct android_app *app, int32_t cmd) {
  AppData *app_data = (AppData *)app->userData;
  switch (cmd) {
    case APP_CMD_INIT_WINDOW:
      if (FLAGS_info) {
        log("DUMP INFO");
        VulkanWorker::DumpWorkerInfo("/sdcard/graphicsfuzz/worker_info.json");
        ANativeActivity_finish(app->activity);
        break;
      }

      if (app_data->vulkan_worker == NULL) {
        log("Create vulkan worker");
        assert(app->window != nullptr);
        app_data->platform_data->window = app->window;
        app_data->vulkan_worker = new VulkanWorker(app_data->platform_data);
        assert(app_data->vertex_file != nullptr);
        assert(app_data->fragment_file != nullptr);
        assert(app_data->uniform_file != nullptr);
        app_data->vulkan_worker->Render(app_data->vertex_file, app_data->fragment_file, app_data->uniform_file, FLAGS_skip_render);
        ANativeActivity_finish(app->activity);
      }
      break;

    case APP_CMD_PAUSE:
    case APP_CMD_STOP:
    case APP_CMD_DESTROY:
      ANativeActivity_finish(app->activity);
      break;
  }
  return;
}

int32_t ProcessInputEvent (struct android_app *app, AInputEvent *event) {
  return 0;
}

// Extract command line arguments from the extra of Android intent:
//   adb shell am start -n <...> -e gfz "'list of arguments to be extracted'"
// Note the quoting: from host terminal adb command, we need to double-escape
// the extra args string, as it is first quoted by host terminal emulator
// (e.g. bash), then it must be quoted for the on-device shell.
void GetGflagsArgs(struct android_app* state, int *argc, char ***argv) {
  assert(argc != nullptr);
  assert(argv != nullptr);
  assert(*argv == nullptr);

  // The extra flag to indicate GraphicsFuzz arguments
  const char *intent_flag = "gfz";

  JavaVM* java_vm = state->activity->vm;
  JNIEnv* jni_env;
  assert(java_vm->AttachCurrentThread(&jni_env, nullptr) == JNI_OK);
  jobject activity_clazz = state->activity->clazz;
  jmethodID get_intent_method_id = jni_env->GetMethodID(jni_env->GetObjectClass(activity_clazz), "getIntent", "()Landroid/content/Intent;");
  jobject intent = jni_env->CallObjectMethod(activity_clazz, get_intent_method_id);
  jmethodID get_string_extra_method_id = jni_env->GetMethodID(jni_env->GetObjectClass(intent), "getStringExtra", "(Ljava/lang/String;)Ljava/lang/String;");
  jvalue get_string_extra_args;
  get_string_extra_args.l = jni_env->NewStringUTF(intent_flag);
  jstring extra_jstring = static_cast<jstring>(jni_env->CallObjectMethodA(intent, get_string_extra_method_id, &get_string_extra_args));

  std::string extra_string;
  if (extra_jstring) {
    const char* extra_cstr = jni_env->GetStringUTFChars(extra_jstring, nullptr);
    log("EXTRA_CSTR: %s", extra_cstr);
    extra_string = extra_cstr;
    jni_env->ReleaseStringUTFChars(extra_jstring, extra_cstr);
    jni_env->DeleteLocalRef(extra_jstring);
  }

  jni_env->DeleteLocalRef(get_string_extra_args.l);
  jni_env->DeleteLocalRef(intent);
  java_vm->DetachCurrentThread();

  // Prepare arguments with a value for argv[0], as gflags expects
  std::vector<std::string> args;
  args.push_back("android_vkworker"); // required but ignored by gflags

  // Split extra_string
  std::stringstream ss(extra_string);
  std::string arg;
  while (std::getline(ss, arg, ' ')) {
    if (!arg.empty()) {
      args.push_back(arg);
    }
  }

  // Convert to argc/argv, as gflags expects
  *argc = (int)(args.size());
  *argv = (char **)malloc(*argc * sizeof(char *));
  assert(*argv != nullptr);
  for (int i = 0; i < *argc; i++) {
    (*argv)[i] = strdup(args[i].c_str());
  }
}

void FreeGflagsArgs(int argc, char **argv) {
  for (int i = 0; i < argc; i++) {
    free(argv[i]);
  }
  free(argv);
}

void android_main(struct android_app* state) {

  // New default values
  FLAGS_sanity_before = "/sdcard/graphicsfuzz/sanity_before.png";
  FLAGS_sanity_after = "/sdcard/graphicsfuzz/sanity_after.png";
  FLAGS_png_template = "/sdcard/graphicsfuzz/image";

  int argc = 0;
  char **argv = nullptr;
  GetGflagsArgs(state, &argc, &argv);
  gflags::SetUsageMessage("GraphicsFuzz Vulkan worker http://github.com/google/graphicsfuzz");
  gflags::ParseCommandLineFlags(&argc, &argv, true);

  AppData *app_data = new AppData;
  app_data->vulkan_worker = nullptr;
  state->userData = (void *)app_data;

  PlatformData platform_data = {};
  // state->window will be ready later, when processing APP_CMD_INIT_WINDOW in processAppCmd()
  app_data->platform_data = &platform_data;

  // Android: setup main callbacks
  state->onAppCmd = ProcessAppCmd;
  state->onInputEvent = ProcessInputEvent;

  if (!FLAGS_info) {
    log("NOT DUMP INFO");
    app_data->vertex_file = fopen("/sdcard/graphicsfuzz/test.vert.spv", "r");
    assert(app_data->vertex_file != nullptr);

    app_data->fragment_file = fopen("/sdcard/graphicsfuzz/test.frag.spv", "r");
    assert(app_data->fragment_file != nullptr);

    app_data->uniform_file = fopen("/sdcard/graphicsfuzz/test.json", "r");
    assert(app_data->uniform_file != nullptr);
  }

  // Android: loop on things to do
  while (1) {
    int events;
    int timeoutMillis = 0;
    struct android_poll_source *source;

    while ((ALooper_pollOnce(timeoutMillis, nullptr, &events, (void **)&source)) >= 0) {

      if (source != nullptr) {
        source->process(state, source);
      }

      if (state->destroyRequested != 0) {
        // Terminate
        if (app_data->vulkan_worker != nullptr) {
          delete app_data->vulkan_worker;
        }
        if (app_data->vertex_file != nullptr) {
          fclose(app_data->vertex_file);
        }
        if (app_data->fragment_file != nullptr) {
        fclose(app_data->fragment_file);
        }
        if (app_data->uniform_file != nullptr) {
          fclose(app_data->uniform_file);
        }
        delete app_data;

        log("\nANDROID TERMINATE OK\n");

        FILE *done = fopen("/sdcard/graphicsfuzz/DONE", "w");
        assert(done != nullptr);
        fprintf(done, "DONE\n");
        fclose(done);

        FreeGflagsArgs(argc, argv);

        return;
      }
    }
  }
}
<commit_msg>Reset command line flags default values in Android (#128)<commit_after>// Copyright 2018 The GraphicsFuzz Project Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Entry point on Android

#include <android_native_app_glue.h>
#include "vulkan_worker.h"
#include "platform.h"

#include <assert.h>
#include <string>
#include <sstream>
#include <iostream>

typedef struct AppData {
  VulkanWorker *vulkan_worker;
  PlatformData *platform_data;
  FILE *vertex_file;
  FILE *fragment_file;
  FILE *uniform_file;
} AppData;

void ProcessAppCmd (struct android_app *app, int32_t cmd) {
  AppData *app_data = (AppData *)app->userData;
  switch (cmd) {
    case APP_CMD_INIT_WINDOW:
      if (FLAGS_info) {
        log("DUMP INFO");
        VulkanWorker::DumpWorkerInfo("/sdcard/graphicsfuzz/worker_info.json");
        ANativeActivity_finish(app->activity);
        break;
      }

      if (app_data->vulkan_worker == NULL) {
        log("Create vulkan worker");
        assert(app->window != nullptr);
        app_data->platform_data->window = app->window;
        app_data->vulkan_worker = new VulkanWorker(app_data->platform_data);
        assert(app_data->vertex_file != nullptr);
        assert(app_data->fragment_file != nullptr);
        assert(app_data->uniform_file != nullptr);
        app_data->vulkan_worker->Render(app_data->vertex_file, app_data->fragment_file, app_data->uniform_file, FLAGS_skip_render);
        ANativeActivity_finish(app->activity);
      }
      break;

    case APP_CMD_PAUSE:
    case APP_CMD_STOP:
    case APP_CMD_DESTROY:
      ANativeActivity_finish(app->activity);
      break;
  }
  return;
}

int32_t ProcessInputEvent (struct android_app *app, AInputEvent *event) {
  return 0;
}

// Extract command line arguments from the extra of Android intent:
//   adb shell am start -n <...> -e gfz "'list of arguments to be extracted'"
// Note the quoting: from host terminal adb command, we need to double-escape
// the extra args string, as it is first quoted by host terminal emulator
// (e.g. bash), then it must be quoted for the on-device shell.
void GetGflagsArgs(struct android_app* state, int *argc, char ***argv) {
  assert(argc != nullptr);
  assert(argv != nullptr);
  assert(*argv == nullptr);

  // The extra flag to indicate GraphicsFuzz arguments
  const char *intent_flag = "gfz";

  JavaVM* java_vm = state->activity->vm;
  JNIEnv* jni_env;
  assert(java_vm->AttachCurrentThread(&jni_env, nullptr) == JNI_OK);
  jobject activity_clazz = state->activity->clazz;
  jmethodID get_intent_method_id = jni_env->GetMethodID(jni_env->GetObjectClass(activity_clazz), "getIntent", "()Landroid/content/Intent;");
  jobject intent = jni_env->CallObjectMethod(activity_clazz, get_intent_method_id);
  jmethodID get_string_extra_method_id = jni_env->GetMethodID(jni_env->GetObjectClass(intent), "getStringExtra", "(Ljava/lang/String;)Ljava/lang/String;");
  jvalue get_string_extra_args;
  get_string_extra_args.l = jni_env->NewStringUTF(intent_flag);
  jstring extra_jstring = static_cast<jstring>(jni_env->CallObjectMethodA(intent, get_string_extra_method_id, &get_string_extra_args));

  std::string extra_string;
  if (extra_jstring) {
    const char* extra_cstr = jni_env->GetStringUTFChars(extra_jstring, nullptr);
    log("EXTRA_CSTR: %s", extra_cstr);
    extra_string = extra_cstr;
    jni_env->ReleaseStringUTFChars(extra_jstring, extra_cstr);
    jni_env->DeleteLocalRef(extra_jstring);
  }

  jni_env->DeleteLocalRef(get_string_extra_args.l);
  jni_env->DeleteLocalRef(intent);
  java_vm->DetachCurrentThread();

  // Prepare arguments with a value for argv[0], as gflags expects
  std::vector<std::string> args;
  args.push_back("android_vkworker"); // required but ignored by gflags

  // Split extra_string
  std::stringstream ss(extra_string);
  std::string arg;
  while (std::getline(ss, arg, ' ')) {
    if (!arg.empty()) {
      args.push_back(arg);
    }
  }

  // Convert to argc/argv, as gflags expects
  *argc = (int)(args.size());
  *argv = (char **)malloc(*argc * sizeof(char *));
  assert(*argv != nullptr);
  for (int i = 0; i < *argc; i++) {
    (*argv)[i] = strdup(args[i].c_str());
  }
}

void FreeGflagsArgs(int argc, char **argv) {
  for (int i = 0; i < argc; i++) {
    free(argv[i]);
  }
  free(argv);
}

void android_main(struct android_app* state) {

  // Reset all default values, as any change may survive the exiting of this
  // android_main() function and still be set when android_main() is called
  // again.
  FLAGS_sanity_before = "/sdcard/graphicsfuzz/sanity_before.png";
  FLAGS_sanity_after = "/sdcard/graphicsfuzz/sanity_after.png";
  FLAGS_png_template = "/sdcard/graphicsfuzz/image";
  FLAGS_info = false;
  FLAGS_skip_render = false;
  FLAGS_num_render = 3;

  int argc = 0;
  char **argv = nullptr;
  GetGflagsArgs(state, &argc, &argv);
  gflags::SetUsageMessage("GraphicsFuzz Vulkan worker http://github.com/google/graphicsfuzz");
  gflags::ParseCommandLineFlags(&argc, &argv, true);

  AppData *app_data = new AppData;
  app_data->vulkan_worker = nullptr;
  state->userData = (void *)app_data;

  PlatformData platform_data = {};
  // state->window will be ready later, when processing APP_CMD_INIT_WINDOW in processAppCmd()
  app_data->platform_data = &platform_data;

  // Android: setup main callbacks
  state->onAppCmd = ProcessAppCmd;
  state->onInputEvent = ProcessInputEvent;

  if (!FLAGS_info) {
    log("NOT DUMP INFO");
    app_data->vertex_file = fopen("/sdcard/graphicsfuzz/test.vert.spv", "r");
    assert(app_data->vertex_file != nullptr);

    app_data->fragment_file = fopen("/sdcard/graphicsfuzz/test.frag.spv", "r");
    assert(app_data->fragment_file != nullptr);

    app_data->uniform_file = fopen("/sdcard/graphicsfuzz/test.json", "r");
    assert(app_data->uniform_file != nullptr);
  }

  // Android: loop on things to do
  while (1) {
    int events;
    int timeoutMillis = 0;
    struct android_poll_source *source;

    while ((ALooper_pollOnce(timeoutMillis, nullptr, &events, (void **)&source)) >= 0) {

      if (source != nullptr) {
        source->process(state, source);
      }

      if (state->destroyRequested != 0) {
        // Terminate
        if (app_data->vulkan_worker != nullptr) {
          delete app_data->vulkan_worker;
        }
        if (app_data->vertex_file != nullptr) {
          fclose(app_data->vertex_file);
        }
        if (app_data->fragment_file != nullptr) {
        fclose(app_data->fragment_file);
        }
        if (app_data->uniform_file != nullptr) {
          fclose(app_data->uniform_file);
        }
        delete app_data;

        log("\nANDROID TERMINATE OK\n");

        FILE *done = fopen("/sdcard/graphicsfuzz/DONE", "w");
        assert(done != nullptr);
        fprintf(done, "DONE\n");
        fclose(done);

        FreeGflagsArgs(argc, argv);

        return;
      }
    }
  }
}
<|endoftext|>


<commit_before>//===----------------------------------------------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

// test libc++'s implementation of align_val_t, and the relevant new/delete
// overloads in all dialects when -faligned-allocation is present.

// Libc++ defers to the underlying MSVC library to provide the new/delete
// definitions, which does not yet provide aligned allocation
// XFAIL: LIBCXX-WINDOWS-FIXME

// AppleClang 10 (and older) will trigger an availability error when the deployment
// target does not support aligned allocation, even if we pass `-faligned-allocation`.
// XFAIL: apple-clang-10 && availability=macosx10.13
// XFAIL: apple-clang-10 && availability=macosx10.12
// XFAIL: apple-clang-10 && availability=macosx10.11
// XFAIL: apple-clang-10 && availability=macosx10.10
// XFAIL: apple-clang-10 && availability=macosx10.9
// XFAIL: apple-clang-10 && availability=macosx10.8
// XFAIL: apple-clang-10 && availability=macosx10.7

// The dylibs shipped before macosx10.14 do not contain the aligned allocation
// functions, so trying to force using those with -faligned-allocation results
// in a link error.
// XFAIL: with_system_cxx_lib=macosx10.13
// XFAIL: with_system_cxx_lib=macosx10.12
// XFAIL: with_system_cxx_lib=macosx10.11
// XFAIL: with_system_cxx_lib=macosx10.10
// XFAIL: with_system_cxx_lib=macosx10.9
// XFAIL: with_system_cxx_lib=macosx10.8
// XFAIL: with_system_cxx_lib=macosx10.7

// The test will fail on deployment targets that do not support sized deallocation.
// XFAIL: availability=macosx10.11
// XFAIL: availability=macosx10.10
// XFAIL: availability=macosx10.9
// XFAIL: availability=macosx10.8
// XFAIL: availability=macosx10.7

// XFAIL: sanitizer-new-delete, ubsan

// GCC doesn't support the aligned-allocation flags.
// XFAIL: gcc

// RUN: %build -faligned-allocation -fsized-deallocation
// RUN: %run
// RUN: %build -faligned-allocation -fno-sized-deallocation -DNO_SIZE
// RUN: %run
// RUN: %build -fno-aligned-allocation -fsized-deallocation -DNO_ALIGN
// RUN: %run
// RUN: %build -fno-aligned-allocation -fno-sized-deallocation -DNO_ALIGN -DNO_SIZE
// RUN: %run

#include <new>
#include <typeinfo>
#include <string>
#include <cassert>

#include "test_macros.h"

struct alloc_stats {
  alloc_stats() { reset(); }

  int aligned_sized_called;
  int aligned_called;
  int sized_called;
  int plain_called;
  int last_size;
  int last_align;

  void reset() {
    aligned_sized_called = aligned_called = sized_called = plain_called = 0;
    last_align = last_size = -1;
  }

  bool expect_plain() const {
    assert(aligned_sized_called == 0);
    assert(aligned_called == 0);
    assert(sized_called == 0);
    assert(last_size == -1);
    assert(last_align == -1);
    return plain_called == 1;
  }

  bool expect_size(int n) const {
    assert(plain_called == 0);
    assert(aligned_sized_called == 0);
    assert(aligned_called == 0);
    assert(last_size == n);
    assert(last_align == -1);
    return sized_called == 1;
  }

  bool expect_align(int a) const {
    assert(plain_called == 0);
    assert(aligned_sized_called == 0);
    assert(sized_called == 0);
    assert(last_size == -1);
    assert(last_align == a);
    return aligned_called == 1;
  }

  bool expect_size_align(int n, int a) const {
    assert(plain_called == 0);
    assert(sized_called == 0);
    assert(aligned_called == 0);
    assert(last_size == n);
    assert(last_align == a);
    return aligned_sized_called == 1;
  }
};
alloc_stats stats;

void operator delete(void* p)TEST_NOEXCEPT {
  ::free(p);
  stats.plain_called++;
  stats.last_size = stats.last_align = -1;
}

#ifndef NO_SIZE
void operator delete(void* p, size_t n)TEST_NOEXCEPT {
  ::free(p);
  stats.sized_called++;
  stats.last_size = n;
  stats.last_align = -1;
}
#endif

#ifndef NO_ALIGN
void operator delete(void* p, std::align_val_t a)TEST_NOEXCEPT {
  ::free(p);
  stats.aligned_called++;
  stats.last_align = static_cast<int>(a);
  stats.last_size = -1;
}

void operator delete(void* p, size_t n, std::align_val_t a)TEST_NOEXCEPT {
  ::free(p);
  stats.aligned_sized_called++;
  stats.last_align = static_cast<int>(a);
  stats.last_size = n;
}
#endif

void test_libcpp_dealloc() {
  void* p = nullptr;
  size_t over_align_val = TEST_ALIGNOF(std::max_align_t) * 2;
  size_t under_align_val = TEST_ALIGNOF(int);
  size_t with_size_val = 2;

  {
    std::__libcpp_deallocate_unsized(p, under_align_val);
    assert(stats.expect_plain());
  }
  stats.reset();

#if defined(NO_SIZE) && defined(NO_ALIGN)
  {
    std::__libcpp_deallocate(p, with_size_val, over_align_val);
    assert(stats.expect_plain());
  }
  stats.reset();
#elif defined(NO_SIZE)
  {
    std::__libcpp_deallocate(p, with_size_val, over_align_val);
    assert(stats.expect_align(over_align_val));
  }
  stats.reset();
#elif defined(NO_ALIGN)
  {
    std::__libcpp_deallocate(p, with_size_val, over_align_val);
    assert(stats.expect_size(with_size_val));
  }
  stats.reset();
#else
  {
    std::__libcpp_deallocate(p, with_size_val, over_align_val);
    assert(stats.expect_size_align(with_size_val, over_align_val));
  }
  stats.reset();
  {
    std::__libcpp_deallocate_unsized(p, over_align_val);
    assert(stats.expect_align(over_align_val));
  }
  stats.reset();
  {
    std::__libcpp_deallocate(p, with_size_val, under_align_val);
    assert(stats.expect_size(with_size_val));
  }
  stats.reset();
#endif
}

struct TEST_ALIGNAS(128) AlignedType {
  AlignedType() : elem(0) {}
  TEST_ALIGNAS(128) char elem;
};

void test_allocator_and_new_match() {
  stats.reset();
#if defined(NO_SIZE) && defined(NO_ALIGN)
  {
    int* x = new int(42);
    delete x;
    assert(stats.expect_plain());
  }
  stats.reset();
  {
    AlignedType* a = new AlignedType();
    delete a;
    assert(stats.expect_plain());
  }
  stats.reset();
#elif defined(NO_SIZE)
  stats.reset();
#if TEST_STD_VER >= 11
  {
    int* x = new int(42);
    delete x;
    assert(stats.expect_plain());
  }
#endif
  stats.reset();
  {
    AlignedType* a = new AlignedType();
    delete a;
    assert(stats.expect_align(TEST_ALIGNOF(AlignedType)));
  }
  stats.reset();
#elif defined(NO_ALIGN)
  stats.reset();
  {
    int* x = new int(42);
    delete x;
    assert(stats.expect_size(sizeof(int)));
  }
  stats.reset();
  {
    AlignedType* a = new AlignedType();
    delete a;
    assert(stats.expect_size(sizeof(AlignedType)));
  }
  stats.reset();
#else
  stats.reset();
  {
    int* x = new int(42);
    delete x;
    assert(stats.expect_size(sizeof(int)));
  }
  stats.reset();
  {
    AlignedType* a = new AlignedType();
    delete a;
    assert(stats.expect_size_align(sizeof(AlignedType),
                                   TEST_ALIGNOF(AlignedType)));
  }
  stats.reset();
#endif
}

int main() {
  test_libcpp_dealloc();
  test_allocator_and_new_match();
}
<commit_msg>[libcxx] Remove outdated XFAILs for aligned deallocation<commit_after>//===----------------------------------------------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

// test libc++'s implementation of align_val_t, and the relevant new/delete
// overloads in all dialects when -faligned-allocation is present.

// Libc++ defers to the underlying MSVC library to provide the new/delete
// definitions, which does not yet provide aligned allocation
// XFAIL: LIBCXX-WINDOWS-FIXME

// The dylibs shipped before macosx10.14 do not contain the aligned allocation
// functions, so trying to force using those with -faligned-allocation results
// in a link error.
// XFAIL: with_system_cxx_lib=macosx10.13
// XFAIL: with_system_cxx_lib=macosx10.12
// XFAIL: with_system_cxx_lib=macosx10.11
// XFAIL: with_system_cxx_lib=macosx10.10
// XFAIL: with_system_cxx_lib=macosx10.9
// XFAIL: with_system_cxx_lib=macosx10.8
// XFAIL: with_system_cxx_lib=macosx10.7

// The test will fail on deployment targets that do not support sized deallocation.
// XFAIL: availability=macosx10.11
// XFAIL: availability=macosx10.10
// XFAIL: availability=macosx10.9
// XFAIL: availability=macosx10.8
// XFAIL: availability=macosx10.7

// XFAIL: sanitizer-new-delete, ubsan

// GCC doesn't support the aligned-allocation flags.
// XFAIL: gcc

// RUN: %build -faligned-allocation -fsized-deallocation
// RUN: %run
// RUN: %build -faligned-allocation -fno-sized-deallocation -DNO_SIZE
// RUN: %run
// RUN: %build -fno-aligned-allocation -fsized-deallocation -DNO_ALIGN
// RUN: %run
// RUN: %build -fno-aligned-allocation -fno-sized-deallocation -DNO_ALIGN -DNO_SIZE
// RUN: %run

#include <new>
#include <typeinfo>
#include <string>
#include <cassert>

#include "test_macros.h"

struct alloc_stats {
  alloc_stats() { reset(); }

  int aligned_sized_called;
  int aligned_called;
  int sized_called;
  int plain_called;
  int last_size;
  int last_align;

  void reset() {
    aligned_sized_called = aligned_called = sized_called = plain_called = 0;
    last_align = last_size = -1;
  }

  bool expect_plain() const {
    assert(aligned_sized_called == 0);
    assert(aligned_called == 0);
    assert(sized_called == 0);
    assert(last_size == -1);
    assert(last_align == -1);
    return plain_called == 1;
  }

  bool expect_size(int n) const {
    assert(plain_called == 0);
    assert(aligned_sized_called == 0);
    assert(aligned_called == 0);
    assert(last_size == n);
    assert(last_align == -1);
    return sized_called == 1;
  }

  bool expect_align(int a) const {
    assert(plain_called == 0);
    assert(aligned_sized_called == 0);
    assert(sized_called == 0);
    assert(last_size == -1);
    assert(last_align == a);
    return aligned_called == 1;
  }

  bool expect_size_align(int n, int a) const {
    assert(plain_called == 0);
    assert(sized_called == 0);
    assert(aligned_called == 0);
    assert(last_size == n);
    assert(last_align == a);
    return aligned_sized_called == 1;
  }
};
alloc_stats stats;

void operator delete(void* p)TEST_NOEXCEPT {
  ::free(p);
  stats.plain_called++;
  stats.last_size = stats.last_align = -1;
}

#ifndef NO_SIZE
void operator delete(void* p, size_t n)TEST_NOEXCEPT {
  ::free(p);
  stats.sized_called++;
  stats.last_size = n;
  stats.last_align = -1;
}
#endif

#ifndef NO_ALIGN
void operator delete(void* p, std::align_val_t a)TEST_NOEXCEPT {
  ::free(p);
  stats.aligned_called++;
  stats.last_align = static_cast<int>(a);
  stats.last_size = -1;
}

void operator delete(void* p, size_t n, std::align_val_t a)TEST_NOEXCEPT {
  ::free(p);
  stats.aligned_sized_called++;
  stats.last_align = static_cast<int>(a);
  stats.last_size = n;
}
#endif

void test_libcpp_dealloc() {
  void* p = nullptr;
  size_t over_align_val = TEST_ALIGNOF(std::max_align_t) * 2;
  size_t under_align_val = TEST_ALIGNOF(int);
  size_t with_size_val = 2;

  {
    std::__libcpp_deallocate_unsized(p, under_align_val);
    assert(stats.expect_plain());
  }
  stats.reset();

#if defined(NO_SIZE) && defined(NO_ALIGN)
  {
    std::__libcpp_deallocate(p, with_size_val, over_align_val);
    assert(stats.expect_plain());
  }
  stats.reset();
#elif defined(NO_SIZE)
  {
    std::__libcpp_deallocate(p, with_size_val, over_align_val);
    assert(stats.expect_align(over_align_val));
  }
  stats.reset();
#elif defined(NO_ALIGN)
  {
    std::__libcpp_deallocate(p, with_size_val, over_align_val);
    assert(stats.expect_size(with_size_val));
  }
  stats.reset();
#else
  {
    std::__libcpp_deallocate(p, with_size_val, over_align_val);
    assert(stats.expect_size_align(with_size_val, over_align_val));
  }
  stats.reset();
  {
    std::__libcpp_deallocate_unsized(p, over_align_val);
    assert(stats.expect_align(over_align_val));
  }
  stats.reset();
  {
    std::__libcpp_deallocate(p, with_size_val, under_align_val);
    assert(stats.expect_size(with_size_val));
  }
  stats.reset();
#endif
}

struct TEST_ALIGNAS(128) AlignedType {
  AlignedType() : elem(0) {}
  TEST_ALIGNAS(128) char elem;
};

void test_allocator_and_new_match() {
  stats.reset();
#if defined(NO_SIZE) && defined(NO_ALIGN)
  {
    int* x = new int(42);
    delete x;
    assert(stats.expect_plain());
  }
  stats.reset();
  {
    AlignedType* a = new AlignedType();
    delete a;
    assert(stats.expect_plain());
  }
  stats.reset();
#elif defined(NO_SIZE)
  stats.reset();
#if TEST_STD_VER >= 11
  {
    int* x = new int(42);
    delete x;
    assert(stats.expect_plain());
  }
#endif
  stats.reset();
  {
    AlignedType* a = new AlignedType();
    delete a;
    assert(stats.expect_align(TEST_ALIGNOF(AlignedType)));
  }
  stats.reset();
#elif defined(NO_ALIGN)
  stats.reset();
  {
    int* x = new int(42);
    delete x;
    assert(stats.expect_size(sizeof(int)));
  }
  stats.reset();
  {
    AlignedType* a = new AlignedType();
    delete a;
    assert(stats.expect_size(sizeof(AlignedType)));
  }
  stats.reset();
#else
  stats.reset();
  {
    int* x = new int(42);
    delete x;
    assert(stats.expect_size(sizeof(int)));
  }
  stats.reset();
  {
    AlignedType* a = new AlignedType();
    delete a;
    assert(stats.expect_size_align(sizeof(AlignedType),
                                   TEST_ALIGNOF(AlignedType)));
  }
  stats.reset();
#endif
}

int main() {
  test_libcpp_dealloc();
  test_allocator_and_new_match();
}
<|endoftext|>


<commit_before>
#include "../io.h"
#include "../directory.h"
#include "../../core/slist.h"
#include "info.h"
#include "../file.h"

namespace Yuni
{
namespace IO
{
namespace Directory
{

	namespace // anonymous
	{

		struct InfoItem
		{
			bool isFile;
			uint64  size;
			String filename;
		};
		typedef LinkedList<InfoItem> List;

	} // anonymous namespace

	bool Copy(const AnyString& src, const AnyString& dst, bool recursive,
		bool overwrite, const IO::Directory::CopyOnUpdateBind& onUpdate)
	{
		// normalize paths
		String fsrc;
		IO::Normalize(fsrc, src);
		if (fsrc.empty())
			return false;

		String fdst;
		IO::Normalize(fdst, dst);

		// The list of files to copy
		List list;
		uint64 totalSize = 0;

		// Adding the target folder, to create it if required
		if (not onUpdate(cpsGatheringInformation, fdst, fdst, 0, 1))
			return false;
		IO::Directory::Create(fdst);

		{
			IO::Directory::Info info(fsrc);
			if (recursive)
			{
				const IO::Directory::Info::recursive_iterator& end = info.recursive_end();
				for (IO::Directory::Info::recursive_iterator i = info.recursive_begin(); i != end; ++i)
				{
					list.push_back();
					InfoItem& info = list.back();
					info.filename = i.filename();
					info.isFile   = i.isFile();
					totalSize += i.size();
					if (!onUpdate(cpsGatheringInformation, *i, *i, 0, list.size()))
						return false;
				}
			}
			else
			{
				const IO::Directory::Info::recursive_iterator& end = info.recursive_end();
				for (IO::Directory::Info::recursive_iterator i = info.recursive_begin(); i != end; ++i)
				{
					list.push_back();
					InfoItem& info = list.back();
					info.filename = i.filename();
					info.isFile   = i.isFile();
					totalSize += i.size();

					if (!onUpdate(cpsGatheringInformation, i.filename(), i.filename(), 0, list.size()))
						return false;
				}
			}
		}

		uint64 current = 0;
		// A temporary string
		String tmp;

		// Streams : in the worst scenario, the last file to copy will be closed
		// at the end of this routine
		// Stream on the source file
		IO::File::Stream fromFile;
		// Stream on the target file
		IO::File::Stream toFile;

		// A temporary buffer for copying files' contents
		// 16k seems to be a good choice (better than smaller block size when used
		// in Virtual Machines)
		enum { bufferSize = 8192 };
		char* buffer = new char[bufferSize];

		// reduce overhead brought by `onUpdate`
		uint skip = 8;

		const List::const_iterator end = list.end();
		for (List::const_iterator i = list.begin(); i != end; ++i)
		{
			// alias to the current information block
			const InfoItem& info = *i;

			// Address of the target file
			tmp = fdst; // without any OS-dependant separator
			if (fsrc.size() < info.filename.size())
				tmp.append(info.filename.c_str() + fsrc.size(), info.filename.size() - fsrc.size());

			if (not info.isFile)
			{
				// The target file is actually a folder
				// We have to create it before copying its content
				if (!onUpdate(cpsCopying, info.filename, tmp, current, totalSize)
					|| !IO::Directory::Create(tmp))
				{
					delete[] buffer;
					return false;
				}
			}
			else
			{
				// The target file is a real file (and not a folder)
				// Checking first for overwritting
				if (not overwrite && IO::Exists(tmp))
					continue;

				// Try to open the source file
				// The previous opened source file will be closed here
				if (fromFile.open(info.filename, IO::OpenMode::read))
				{
					// Try to open for writing the target file
					// The previous opened target file will be closed here
					if (toFile.open(tmp, IO::OpenMode::write | IO::OpenMode::truncate))
					{
						// reading the whole source file
						uint64 numRead;
						while ((numRead = fromFile.read(buffer, bufferSize)) != 0)
						{
							// progression
							current += numRead;

							// Trying to copy the block which has just been read
							if (numRead != toFile.write((const char*)buffer, numRead))
							{
								delete[] buffer;
								return false;
							}

							// Notify the user from time to time about the progression
							if (!--skip)
							{
								if (!onUpdate(cpsCopying, info.filename, tmp, current, totalSize))
								{
									delete[] buffer;
									return false;
								}
								skip = 8;
							}
						} // read
					}
				}
			}
		}

		delete[] buffer;

		return true;
	}

} // namespace Directory
} // namespace IO
} // namespace Yuni

<commit_msg>IO::Directory::Copy: several optimization<commit_after>
#include "../io.h"
#include "../directory.h"
#include "info.h"
#include "../file.h"

namespace Yuni
{
namespace IO
{
namespace Directory
{

	namespace // anonymous
	{

		struct InfoItem
		{
			bool isFile;
			uint64  size;
			String filename;
		};
		typedef std::vector<InfoItem> List;

	} // anonymous namespace

	bool Copy(const AnyString& src, const AnyString& dst, bool recursive, bool overwrite,
		const IO::Directory::CopyOnUpdateBind& onUpdate)
	{
		// normalize paths
		String fsrc;
		IO::Normalize(fsrc, src);
		if (fsrc.empty())
			return false;

		String fdst;
		IO::Normalize(fdst, dst);

		// Adding the target folder, to create it if required
		if (not onUpdate(cpsGatheringInformation, fdst, fdst, 0, 1))
			return false;

		if (not IO::Directory::Create(fdst))
			return false;

		// The list of files to copy
		List list;
		list.reserve(512);
		// the total number of bytes to copy
		uint64 totalSize = 0;

		// get the complete list of all files to copy and all folders to create
		{
			IO::Directory::Info info(fsrc);
			if (recursive)
			{
				const IO::Directory::Info::recursive_iterator& end = info.recursive_end();
				for (IO::Directory::Info::recursive_iterator i = info.recursive_begin(); i != end; ++i)
				{
					list.resize(list.size() + 1);
					InfoItem& info = list.back();
					info.filename = i.filename();
					info.isFile   = i.isFile();
					totalSize += i.size();
					if (not onUpdate(cpsGatheringInformation, *i, *i, 0, list.size()))
						return false;
				}
			}
			else
			{
				const IO::Directory::Info::iterator& end = info.end();
				for (IO::Directory::Info::iterator i = info.begin(); i != end; ++i)
				{
					list.resize(list.size() + 1);
					InfoItem& info = list.back();
					info.filename = i.filename();
					info.isFile   = i.isFile();
					totalSize += i.size();

					if (not onUpdate(cpsGatheringInformation, i.filename(), i.filename(), 0, list.size()))
						return false;
				}
			}
		}

		if (list.empty())
			return true;

		uint64 current = 0;
		// A temporary string
		String tmp;
		tmp.reserve(1024);

		// Streams : in the worst scenario, the last file to copy will be closed
		// at the end of this routine
		// Stream on the source file
		IO::File::Stream fromFile;
		// Stream on the target file
		IO::File::Stream toFile;

		// A temporary buffer for copying files' contents
		// 16k seems to be a good choice (better than smaller block size when used
		// in Virtual Machines)
		enum { bufferSize = 8192 };
		char* const buffer = new char[(uint) bufferSize];

		// reduce overhead brought by `onUpdate`
		enum { maxSkip = 6 };
		uint skip = (uint) maxSkip;
		// result
		bool success = true;

		const List::const_iterator end = list.end();
		for (List::const_iterator i = list.begin(); i != end; ++i)
		{
			// alias to the current information block
			const InfoItem& info = *i;

			// Address of the target file
			tmp = fdst; // without any OS-dependant separator
			if (fsrc.size() < info.filename.size())
				tmp.append(info.filename.c_str() + fsrc.size(), info.filename.size() - fsrc.size());

			if (not info.isFile)
			{
				// The target file is actually a folder - must be created before copying its content
				if (not onUpdate(cpsCopying, info.filename, tmp, current, totalSize) or not IO::Directory::Create(tmp))
				{
					success = false;
					break;
				}
			}
			else
			{
				// The target file is a real file (and not a folder)
				// Checking first for overwritting
				if (not overwrite && IO::Exists(tmp))
					continue;

				// Try to open the source file
				// The previous opened source file will be closed here
				if (fromFile.open(info.filename, IO::OpenMode::read))
				{
					// Try to open for writing the target file
					// The previous opened target file will be closed here
					if (toFile.open(tmp, IO::OpenMode::write | IO::OpenMode::truncate))
					{
						// reading the whole source file
						uint64 numRead;
						while ((numRead = fromFile.read(buffer, (uint) bufferSize)) > 0)
						{
							// progression
							current += numRead;

							// Trying to copy the block which has just been read
							if (numRead != toFile.write((const char*)buffer, numRead))
							{
								success = false;
								break;
							}

							// Notify the user from time to time about the progression
							if (0 == --skip)
							{
								if (not onUpdate(cpsCopying, info.filename, tmp, current, totalSize))
								{
									success = false;
									break;
								}
								skip = (uint) maxSkip;
							}
						} // read
					}
					else
					{
						success = false;
						break;
					}
				}
				else
				{
					success = false;
					break;
				}
			}
		}

		delete[] buffer;

		return success;
	}

} // namespace Directory
} // namespace IO
} // namespace Yuni

<|endoftext|>


<commit_before>/* -*- mode: C++; c-basic-offset: 4; indent-tabs-mode: nil -*- */
// vim: ft=cpp:expandtab:ts=8:sw=4:softtabstop=4:
#ident "$Id$"
#ident "Copyright (c) 2007-2012 Tokutek Inc.  All rights reserved."
#ident "The technology is licensed by the Massachusetts Institute of Technology, Rutgers State University of New Jersey, and the Research Foundation of State University of New York at Stony Brook under United States of America Serial No. 11/760379 and to the patents and/or patent applications resulting from it."
#include <toku_portability.h>
#include "test.h"
#include "minicron.h"
#include <unistd.h>

#include <string.h>
#include <stdlib.h>

static double
tdiff (struct timeval *a, struct timeval *b) {
    return (a->tv_sec-b->tv_sec) + (a->tv_usec-b->tv_usec)*1e-6;
}

struct timeval starttime;
static double elapsed (void) {
    struct timeval now;
    gettimeofday(&now, 0);
    return tdiff(&now, &starttime);
}

static int
#ifndef GCOV
__attribute__((__noreturn__))
#endif
never_run (void *a) {
    assert(a==0);
    assert(0);
#if TOKU_WINDOWS || defined(GCOV)
    return 0; //ICC ignores the noreturn attribute.
#endif
}

// Can we start something with period=0 (the function should never run) and shut it down.
static void*
test1 (void* v)
{
    struct minicron m;
    int r = toku_minicron_setup(&m, 0, never_run, 0);   assert(r==0);
    sleep(1);
    r = toku_minicron_shutdown(&m);                     assert(r==0);
    return v;
}

// Can we start something with period=10 and shut it down after 2 seconds (the function should never run) .
static void*
test2 (void* v)
{
    struct minicron m;
    int r = toku_minicron_setup(&m, 10, never_run, 0);   assert(r==0);
    sleep(2);
    r = toku_minicron_shutdown(&m);                     assert(r==0);
    return v;
}

struct tenx {
    struct timeval tv;
    int counter;
};

static int
run_5x (void *v) {
    struct tenx *CAST_FROM_VOIDP(tx, v);
    struct timeval now;
    gettimeofday(&now, 0);
    double diff = tdiff(&now, &tx->tv);
    if (verbose) printf("T=%f tx->counter=%d\n", diff, tx->counter);
    // We only verify that the timer was not premature.
    // Sometimes it will be delayed, but there's no good way to test it and nothing we can do about it.
    if (!(diff>0.5 + tx->counter)) {
      printf("T=%f tx->counter=%d\n", diff, tx->counter);
      assert(0);
    }
    tx->counter++;
    return 0;
}

// Start something with period=1 and run it a few times
static void*
test3 (void* v)
{
    struct minicron m;
    struct tenx tx;
    gettimeofday(&tx.tv, 0);
    tx.counter=0;
    int r = toku_minicron_setup(&m, 1, run_5x, &tx);   assert(r==0);
    sleep(5);
    r = toku_minicron_shutdown(&m);                     assert(r==0);
    assert(tx.counter>=4 && tx.counter<=5); // after 5 seconds it could have run 4 or 5 times.
    return v;
}

static int
run_3sec (void *v) {
    if (verbose) printf("start3sec at %.6f\n", elapsed());
    int *CAST_FROM_VOIDP(counter, v);
    (*counter)++;
    sleep(3);
    if (verbose) printf("end3sec at %.6f\n", elapsed());
    return 0;
}

// make sure that if f is really slow that it doesn't run too many times
static void*
test4 (void *v) {
    struct minicron m;
    int counter = 0;
    int r = toku_minicron_setup(&m, 2, run_3sec, &counter); assert(r==0);
    sleep(9);
    r = toku_minicron_shutdown(&m);                     assert(r==0);
    assert(counter==2);
    return v;
}

static void*
test5 (void *v) {
    struct minicron m;
    int counter = 0;
    int r = toku_minicron_setup(&m, 10, run_3sec, &counter); assert(r==0);
    r = toku_minicron_change_period(&m, 2);                  assert(r==0);
    sleep(9);
    r = toku_minicron_shutdown(&m);                     assert(r==0);
    assert(counter==2);
    return v;
}

static void*
test6 (void *v) {
    struct minicron m;
    int r = toku_minicron_setup(&m, 5, never_run, 0); assert(r==0);
    r = toku_minicron_change_period(&m, 0);                  assert(r==0);
    sleep(7);
    r = toku_minicron_shutdown(&m);                          assert(r==0);
    return v;
}

typedef void*(*ptf)(void*);
int
test_main (int argc, const char *argv[]) {
    default_parse_args(argc,argv);
    gettimeofday(&starttime, 0);

    ptf testfuns[] = {test1, test2, test3,
		      test4,
		      test5,
		      test6
    };
#define N (sizeof(testfuns)/sizeof(testfuns[0]))
    toku_pthread_t tests[N];

    unsigned int i;
    for (i=0; i<N; i++) {
	int r=toku_pthread_create(tests+i, 0, testfuns[i], 0);
	assert(r==0);
    }
    for (i=0; i<N; i++) {
	void *v;
	int r=toku_pthread_join(tests[i], &v);
	assert(r==0);
	assert(v==0);
    }
    return 0;
}
<commit_msg>refs #5507 fix minicron-test<commit_after>/* -*- mode: C++; c-basic-offset: 4; indent-tabs-mode: nil -*- */
// vim: ft=cpp:expandtab:ts=8:sw=4:softtabstop=4:
#ident "$Id$"
#ident "Copyright (c) 2007-2012 Tokutek Inc.  All rights reserved."
#ident "The technology is licensed by the Massachusetts Institute of Technology, Rutgers State University of New Jersey, and the Research Foundation of State University of New York at Stony Brook under United States of America Serial No. 11/760379 and to the patents and/or patent applications resulting from it."
#include <toku_portability.h>
#include "test.h"
#include "minicron.h"
#include <unistd.h>

#include <string.h>
#include <stdlib.h>

static double
tdiff (struct timeval *a, struct timeval *b) {
    return (a->tv_sec-b->tv_sec) + (a->tv_usec-b->tv_usec)*1e-6;
}

struct timeval starttime;
static double elapsed (void) {
    struct timeval now;
    gettimeofday(&now, 0);
    return tdiff(&now, &starttime);
}

static int
#ifndef GCOV
__attribute__((__noreturn__))
#endif
never_run (void *a) {
    assert(a==0);
    assert(0);
#if TOKU_WINDOWS || defined(GCOV)
    return 0; //ICC ignores the noreturn attribute.
#endif
}

// Can we start something with period=0 (the function should never run) and shut it down.
static void*
test1 (void* v)
{
    struct minicron m;
    ZERO_STRUCT(m);
    int r = toku_minicron_setup(&m, 0, never_run, 0);   assert(r==0);
    sleep(1);
    r = toku_minicron_shutdown(&m);                     assert(r==0);
    return v;
}

// Can we start something with period=10 and shut it down after 2 seconds (the function should never run) .
static void*
test2 (void* v)
{
    struct minicron m;
    ZERO_STRUCT(m);
    int r = toku_minicron_setup(&m, 10, never_run, 0);   assert(r==0);
    sleep(2);
    r = toku_minicron_shutdown(&m);                     assert(r==0);
    return v;
}

struct tenx {
    struct timeval tv;
    int counter;
};

static int
run_5x (void *v) {
    struct tenx *CAST_FROM_VOIDP(tx, v);
    struct timeval now;
    gettimeofday(&now, 0);
    double diff = tdiff(&now, &tx->tv);
    if (verbose) printf("T=%f tx->counter=%d\n", diff, tx->counter);
    // We only verify that the timer was not premature.
    // Sometimes it will be delayed, but there's no good way to test it and nothing we can do about it.
    if (!(diff>0.5 + tx->counter)) {
      printf("T=%f tx->counter=%d\n", diff, tx->counter);
      assert(0);
    }
    tx->counter++;
    return 0;
}

// Start something with period=1 and run it a few times
static void*
test3 (void* v)
{
    struct minicron m;
    struct tenx tx;
    gettimeofday(&tx.tv, 0);
    tx.counter=0;
    ZERO_STRUCT(m);
    int r = toku_minicron_setup(&m, 1, run_5x, &tx);   assert(r==0);
    sleep(5);
    r = toku_minicron_shutdown(&m);                     assert(r==0);
    assert(tx.counter>=4 && tx.counter<=5); // after 5 seconds it could have run 4 or 5 times.
    return v;
}

static int
run_3sec (void *v) {
    if (verbose) printf("start3sec at %.6f\n", elapsed());
    int *CAST_FROM_VOIDP(counter, v);
    (*counter)++;
    sleep(3);
    if (verbose) printf("end3sec at %.6f\n", elapsed());
    return 0;
}

// make sure that if f is really slow that it doesn't run too many times
static void*
test4 (void *v) {
    struct minicron m;
    int counter = 0;
    ZERO_STRUCT(m);
    int r = toku_minicron_setup(&m, 2, run_3sec, &counter); assert(r==0);
    sleep(9);
    r = toku_minicron_shutdown(&m);                     assert(r==0);
    assert(counter==2);
    return v;
}

static void*
test5 (void *v) {
    struct minicron m;
    int counter = 0;
    ZERO_STRUCT(m);
    int r = toku_minicron_setup(&m, 10, run_3sec, &counter); assert(r==0);
    r = toku_minicron_change_period(&m, 2);                  assert(r==0);
    sleep(9);
    r = toku_minicron_shutdown(&m);                     assert(r==0);
    assert(counter==2);
    return v;
}

static void*
test6 (void *v) {
    struct minicron m;
    ZERO_STRUCT(m);
    int r = toku_minicron_setup(&m, 5, never_run, 0); assert(r==0);
    r = toku_minicron_change_period(&m, 0);                  assert(r==0);
    sleep(7);
    r = toku_minicron_shutdown(&m);                          assert(r==0);
    return v;
}

typedef void*(*ptf)(void*);
int
test_main (int argc, const char *argv[]) {
    default_parse_args(argc,argv);
    gettimeofday(&starttime, 0);

    ptf testfuns[] = {test1, test2, test3,
		      test4,
		      test5,
		      test6
    };
#define N (sizeof(testfuns)/sizeof(testfuns[0]))
    toku_pthread_t tests[N];

    unsigned int i;
    for (i=0; i<N; i++) {
	int r=toku_pthread_create(tests+i, 0, testfuns[i], 0);
	assert(r==0);
    }
    for (i=0; i<N; i++) {
	void *v;
	int r=toku_pthread_join(tests[i], &v);
	assert(r==0);
	assert(v==0);
    }
    return 0;
}
<|endoftext|>


<commit_before>/******************************************************************************
 Copyright (c) 2017 Leandro T. C. Melo (ltcmelo@gmail.com)

 This library is free software; you can redistribute it and/or modify it under
 the terms of the GNU Lesser General Public License as published by the Free
 Software Foundation; either version 2.1 of the License, or (at your option)
 any later version.

 This library is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
 for more details.

 You should have received a copy of the GNU Lesser General Public License along
 with this library; if not, write to the Free Software Foundation, Inc., 51
 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA
 *****************************************************************************/

#include "StdLibIndex.h"
#include "Control.h"
#include <algorithm>
#include <iterator>
#include <unordered_set>

using namespace psyche;
using namespace CPlusPlus;

// C89/90
const StdLibIndex::Index StdLibIndex::c89idx_
    {
        { "assert.h",
            {
                { "assert", SymbolKind::Value }
            }
        },
        { "errno.h",
            {
                { "errno", SymbolKind::Value }
            }
        },
        { "ctype.h",
            {
                { "isalnum", SymbolKind::Value },
                { "isalpha", SymbolKind::Value },
                { "islower", SymbolKind::Value },
                { "isupper", SymbolKind::Value },
                { "isdigit", SymbolKind::Value },
                { "isxdigit", SymbolKind::Value },
                { "iscntrl", SymbolKind::Value },
                { "isgraph", SymbolKind::Value },
                { "isspace", SymbolKind::Value },
                { "isprint", SymbolKind::Value },
                { "ispunch", SymbolKind::Value },
                { "tolower", SymbolKind::Value },
                { "toupper", SymbolKind::Value }
            }
        },
        { "stdlib.h",
            {
                { "atof", SymbolKind::Value },
                { "atoi", SymbolKind::Value },
                { "atol", SymbolKind::Value },
                { "strtol", SymbolKind::Value },
                { "strtoul", SymbolKind::Value },
                { "strtod", SymbolKind::Value }
            }
        },
        { "string.h",
            {
                { "strcpy", SymbolKind::Value },
                { "strncpy", SymbolKind::Value },
                { "strcat", SymbolKind::Value },
                { "strncat", SymbolKind::Value },
                { "strxfrm", SymbolKind::Value },
                { "strlen", SymbolKind::Value },
                { "strcmp", SymbolKind::Value },
                { "strncmp", SymbolKind::Value },
                { "strcoll", SymbolKind::Value },
                { "strchr", SymbolKind::Value },
                { "strspn", SymbolKind::Value },
                { "strcspn", SymbolKind::Value }
            }
        }
    };

// C99
const StdLibIndex::Index StdLibIndex::c99idx_
    {
        { "ctype.h",
            {
                { "isblank", SymbolKind::Value }
            }
        },
        { "stdlib.h",
            {
                { "atoll", SymbolKind::Value },
                { "strtoll", SymbolKind::Value },
                { "strtoull", SymbolKind::Value },
                { "strtof", SymbolKind::Value },
                { "strtold", SymbolKind::Value }
            }
        }
    };

// C11
const StdLibIndex::Index StdLibIndex::c11idx_
    {
        { "assert.h",
            {
                { "static_assert", SymbolKind::Value }
            }
        },
        { "errno.h",
            {
                { "errno_t", SymbolKind::Type }
            }
        },
        { "string.h",
            {
                { "strcpy_s", SymbolKind::Value },
                { "strncpy_s", SymbolKind::Value },
                { "strcat_s", SymbolKind::Value },
                { "strncat_s", SymbolKind::Value },
                { "strnlen_s", SymbolKind::Value }
            }
        }
    };

StdLibIndex::StdLibIndex(StdLibVersion std)
    : std_(std)
{}

std::vector<std::string> StdLibIndex::inspect(const Control& control) const
{
    std::unordered_set<std::string> deps;

    auto f = [&deps, &control] (const Index& idx) {
        for (const auto& v : idx) {
            if (deps.count(v.first)) // Maybe the header has already been inserted.
                continue;
            for (const auto& s : v.second) {
                if (control.findIdentifier(s.first, strlen(s.first))) {
                    deps.insert(v.first);
                    break;
                }
            }
        }
    };

    f(c89idx_);
    if (std_ == StdLibVersion::C99)
        f(c99idx_);
    if (std_ == StdLibVersion::C11)
        f(c11idx_);

    std::vector<std::string> v;
    std::move(deps.begin(), deps.end(), std::back_inserter(v));
    return v;
}
<commit_msg>Add missing header<commit_after>/******************************************************************************
 Copyright (c) 2017 Leandro T. C. Melo (ltcmelo@gmail.com)

 This library is free software; you can redistribute it and/or modify it under
 the terms of the GNU Lesser General Public License as published by the Free
 Software Foundation; either version 2.1 of the License, or (at your option)
 any later version.

 This library is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
 for more details.

 You should have received a copy of the GNU Lesser General Public License along
 with this library; if not, write to the Free Software Foundation, Inc., 51
 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA
 *****************************************************************************/

#include "StdLibIndex.h"
#include "Control.h"
#include <algorithm>
#include <cstring>
#include <iterator>
#include <unordered_set>

using namespace psyche;
using namespace CPlusPlus;

// C89/90
const StdLibIndex::Index StdLibIndex::c89idx_
    {
        { "assert.h",
            {
                { "assert", SymbolKind::Value }
            }
        },
        { "errno.h",
            {
                { "errno", SymbolKind::Value }
            }
        },
        { "ctype.h",
            {
                { "isalnum", SymbolKind::Value },
                { "isalpha", SymbolKind::Value },
                { "islower", SymbolKind::Value },
                { "isupper", SymbolKind::Value },
                { "isdigit", SymbolKind::Value },
                { "isxdigit", SymbolKind::Value },
                { "iscntrl", SymbolKind::Value },
                { "isgraph", SymbolKind::Value },
                { "isspace", SymbolKind::Value },
                { "isprint", SymbolKind::Value },
                { "ispunch", SymbolKind::Value },
                { "tolower", SymbolKind::Value },
                { "toupper", SymbolKind::Value }
            }
        },
        { "stdlib.h",
            {
                { "atof", SymbolKind::Value },
                { "atoi", SymbolKind::Value },
                { "atol", SymbolKind::Value },
                { "strtol", SymbolKind::Value },
                { "strtoul", SymbolKind::Value },
                { "strtod", SymbolKind::Value }
            }
        },
        { "string.h",
            {
                { "strcpy", SymbolKind::Value },
                { "strncpy", SymbolKind::Value },
                { "strcat", SymbolKind::Value },
                { "strncat", SymbolKind::Value },
                { "strxfrm", SymbolKind::Value },
                { "strlen", SymbolKind::Value },
                { "strcmp", SymbolKind::Value },
                { "strncmp", SymbolKind::Value },
                { "strcoll", SymbolKind::Value },
                { "strchr", SymbolKind::Value },
                { "strspn", SymbolKind::Value },
                { "strcspn", SymbolKind::Value }
            }
        }
    };

// C99
const StdLibIndex::Index StdLibIndex::c99idx_
    {
        { "ctype.h",
            {
                { "isblank", SymbolKind::Value }
            }
        },
        { "stdlib.h",
            {
                { "atoll", SymbolKind::Value },
                { "strtoll", SymbolKind::Value },
                { "strtoull", SymbolKind::Value },
                { "strtof", SymbolKind::Value },
                { "strtold", SymbolKind::Value }
            }
        }
    };

// C11
const StdLibIndex::Index StdLibIndex::c11idx_
    {
        { "assert.h",
            {
                { "static_assert", SymbolKind::Value }
            }
        },
        { "errno.h",
            {
                { "errno_t", SymbolKind::Type }
            }
        },
        { "string.h",
            {
                { "strcpy_s", SymbolKind::Value },
                { "strncpy_s", SymbolKind::Value },
                { "strcat_s", SymbolKind::Value },
                { "strncat_s", SymbolKind::Value },
                { "strnlen_s", SymbolKind::Value }
            }
        }
    };

StdLibIndex::StdLibIndex(StdLibVersion std)
    : std_(std)
{}

std::vector<std::string> StdLibIndex::inspect(const Control& control) const
{
    std::unordered_set<std::string> deps;

    auto f = [&deps, &control] (const Index& idx) {
        for (const auto& v : idx) {
            if (deps.count(v.first)) // Maybe the header has already been inserted.
                continue;
            for (const auto& s : v.second) {
                if (control.findIdentifier(s.first, strlen(s.first))) {
                    deps.insert(v.first);
                    break;
                }
            }
        }
    };

    f(c89idx_);
    if (std_ == StdLibVersion::C99)
        f(c99idx_);
    if (std_ == StdLibVersion::C11)
        f(c11idx_);

    std::vector<std::string> v;
    std::move(deps.begin(), deps.end(), std::back_inserter(v));
    return v;
}
<|endoftext|>


<commit_before>#include <cstring>
#include "vrambatcher.h"
Poke::Poke() : size(0), mode(PM_NOOP) {}
Poke::Poke(uint8_t val, volatile uint8_t *addr_) : size(sizeof(uint8_t)), mode(PM_INT), addr(addr_), value8(val) {
}
Poke::Poke(uint16_t val, volatile uint16_t *addr_) : size(sizeof(uint16_t)), mode(PM_INT), addr(addr_), value16(val) {
}
Poke::Poke(uint32_t val, volatile uint32_t *addr_) : size(sizeof(uint32_t)), mode(PM_INT), addr(addr_), value32(val) {
}
Poke::Poke(std::unique_ptr<uint8_t[]> &&dataPtr, size_t dataSize, hwPtr addr_) : size(dataSize), mode(PM_MEMCPY), addr(addr_), valuePtr(std::move(dataPtr)) {
}
Poke::~Poke() {
	switch(mode) {
		case PM_DMA:
		case PM_MEMCPY:
			valuePtr.~unique_ptr();
		break;
		default:
		break;
	}
}

void Poke::Perform() {
	switch(mode) {
		case PM_NOOP:
		break;
		case PM_INT:
			switch(size) {
				case sizeof(uint8_t):
					*((volatile uint8_t*)addr)=value8;
				break;
				case sizeof(uint16_t):
					*((volatile uint16_t*)addr)=value16;
				break;
				case sizeof(uint32_t):
					*((volatile uint32_t*)addr)=value32;
				break;
			}
		break;
		case PM_BITFIELD:
		break;
		case PM_DMA:
		break;
		case PM_MEMCPY:
		break;

	}
}

PokeChainLink::PokeChainLink() {}
PokeChainLink::PokeChainLink(Poke &&p, std::unique_ptr<PokeChainLink> &&next_) : next(std::move(next_)), poke(std::move(p)) {}
PokeChainLink::~PokeChainLink() {}

void VramBatcher::AddPoke(int line, uint8_t val, volatile uint8_t *addr) {
	AddPoke(line,Poke(val,addr));
}
void VramBatcher::AddPoke(int line, uint16_t val, volatile uint16_t *addr){
	AddPoke(line,Poke(val,addr));
}
void VramBatcher::AddPoke(int line, uint32_t val, volatile uint32_t *addr){
	AddPoke(line,Poke(val,addr));
}
void VramBatcher::AddPoke(int line, std::unique_ptr<uint8_t[]> &&data, size_t dataSize, hwPtr addr){
	AddPoke(line,Poke(std::move(data),dataSize,addr));
}
void VramBatcher::AddPoke(int line, Poke&& p) {
	PokeChainLink *l=new PokeChainLink(std::move(p),std::move(lineEntries[line]));
	lineEntries[line]=std::unique_ptr<PokeChainLink>(l);
}

void VramBatcher::Clear() {
	for(int line=0;line<SCREEN_HEIGHT;++line) {
		lineEntries[line].reset();
	}
}

void VramBatcher::ApplyPokesForLine(int line) {
	for(PokeChainLink *pPtr=lineEntries[line].get();pPtr!=nullptr;pPtr=pPtr->next.get()) {
		pPtr->poke.Perform();
	}
}<commit_msg>Implement PM_MEMCPY<commit_after>#include <algorithm>
#include <cstring>
#include "vrambatcher.h"
Poke::Poke() : size(0), mode(PM_NOOP) {}
Poke::Poke(uint8_t val, volatile uint8_t *addr_) : size(sizeof(uint8_t)), mode(PM_INT), addr(addr_), value8(val) {
}
Poke::Poke(uint16_t val, volatile uint16_t *addr_) : size(sizeof(uint16_t)), mode(PM_INT), addr(addr_), value16(val) {
}
Poke::Poke(uint32_t val, volatile uint32_t *addr_) : size(sizeof(uint32_t)), mode(PM_INT), addr(addr_), value32(val) {
}
Poke::Poke(std::unique_ptr<uint8_t[]> &&dataPtr, size_t dataSize, hwPtr addr_) : size(dataSize), mode(PM_MEMCPY), addr(addr_), valuePtr(std::move(dataPtr)) {
}
Poke::~Poke() {
	switch(mode) {
		case PM_DMA:
		case PM_MEMCPY:
			valuePtr.~unique_ptr();
		break;
		default:
		break;
	}
}

void Poke::Perform() {
	switch(mode) {
		case PM_NOOP:
		break;
		case PM_INT:
			switch(size) {
				case sizeof(uint8_t):
					*((volatile uint8_t*)addr)=value8;
				break;
				case sizeof(uint16_t):
					*((volatile uint16_t*)addr)=value16;
				break;
				case sizeof(uint32_t):
					*((volatile uint32_t*)addr)=value32;
				break;
			}
		break;
		case PM_BITFIELD:
		break;
		case PM_DMA:
		break;
		case PM_MEMCPY: {
			volatile uint8_t *dst=valuePtr.get();
			std::copy(dst,dst+size,(uint8_t *)addr);
		} break;

	}
}

PokeChainLink::PokeChainLink() {}
PokeChainLink::PokeChainLink(Poke &&p, std::unique_ptr<PokeChainLink> &&next_) : next(std::move(next_)), poke(std::move(p)) {}
PokeChainLink::~PokeChainLink() {}

void VramBatcher::AddPoke(int line, uint8_t val, volatile uint8_t *addr) {
	AddPoke(line,Poke(val,addr));
}
void VramBatcher::AddPoke(int line, uint16_t val, volatile uint16_t *addr){
	AddPoke(line,Poke(val,addr));
}
void VramBatcher::AddPoke(int line, uint32_t val, volatile uint32_t *addr){
	AddPoke(line,Poke(val,addr));
}
void VramBatcher::AddPoke(int line, std::unique_ptr<uint8_t[]> &&data, size_t dataSize, hwPtr addr){
	AddPoke(line,Poke(std::move(data),dataSize,addr));
}
void VramBatcher::AddPoke(int line, Poke&& p) {
	PokeChainLink *l=new PokeChainLink(std::move(p),std::move(lineEntries[line]));
	lineEntries[line]=std::unique_ptr<PokeChainLink>(l);
}

void VramBatcher::Clear() {
	for(int line=0;line<SCREEN_HEIGHT;++line) {
		lineEntries[line].reset();
	}
}

void VramBatcher::ApplyPokesForLine(int line) {
	for(PokeChainLink *pPtr=lineEntries[line].get();pPtr!=nullptr;pPtr=pPtr->next.get()) {
		pPtr->poke.Perform();
	}
}<|endoftext|>