<commit_before>// Full SQL dump of the blockchain

#include <fstream>

#include <util.h>
#include <stdio.h>
#include <stdlib.h>
#include <common.h>
#include <errlog.h>
#include <option.h>
#include <callback.h>
#include <unistd.h>
#include <stdint.h>
#include "sqlite3pp.h"

static uint8_t empty[kSHA256ByteSize] = { 0x42 };
typedef GoogMap<Hash256, uint64_t, Hash256Hasher, Hash256Equal>::Map OutputMap;

inline bool file_exists (const std::string &name)
{
    std::ifstream file(name);
    return (file.good());
}

static void writeEscapedBinaryBuffer(
    FILE          *f,
    const uint8_t *p,
    size_t        n
)
{
    char buf[3];
    p += n;

    while (n--)
    {
        uint8_t c = *(--p);
        sprintf(buf, "%02X", (unsigned char) c);
        fputs(buf, f);
    }
}

struct SQLDump: public Callback
{
    FILE *txFile;
    FILE *bashFile;
    FILE *blockFile;
    FILE *inputFile;
    FILE *outputFile;
    FILE *progressFile;

    uint64_t txID;
    uint64_t blkID;
    uint64_t inputID;
    uint64_t outputID;
    uint64_t cutoffBlock;
    OutputMap outputMap;
    optparse::OptionParser parser;

    SQLDump()
    {
        parser
        .usage("[options]")
        .version("")
        .description("create an SQL dump of the blockchain")
        .epilog("")
        ;
        parser
        .add_option("-a", "--atBlock")
        .action("store")
        .type("int")
        .set_default(1)
        .help("start dump at block <block> (default: genesis block) - this is ignored if a blockchain database already exists")
        ;
    }

    virtual const char                   *name() const
    {
        return "sqldump";
    }
    virtual const optparse::OptionParser *optionParser() const
    {
        return &parser;
    }
    virtual bool                         needTXHash() const
    {
        return true;
    }

    virtual void aliases(
        std::vector<const char *> &v
    ) const
    {
        v.push_back("dump");
    }

    virtual int init(
        int argc,
        const char *argv[]
    )
    {
        txID = 0;
        blkID = 0;
        inputID = 0;
        outputID = 0;

        static uint64_t sz = 32 * 1000 * 1000;
        outputMap.setEmptyKey(empty);
        outputMap.resize(sz);

        optparse::Values &values = parser.parse_args(argc, argv);
        if (!file_exists("../blockchain/blockchain.sqlite"))
        {
            cutoffBlock = values.get("atBlock");
        }
        else
        {
            sqlite3pp::database db("../blockchain/blockchain.sqlite");
            sqlite3pp::query qry(db, "SELECT MAX(block_id) FROM blocks");

            sqlite3pp::query::iterator i = qry.begin();

            cutoffBlock = (uint64_t) atoi((*i).get<char const *>(0)) + 1;

            info("Resuming from block %" PRIu64 ".\n", cutoffBlock);
        }

        info("Dumping the blockchain...");

        txFile = fopen("tx.txt", "w");
        if (!txFile) sysErrFatal("Couldn't open file tx.txt for writing\n");

        blockFile = fopen("blocks.txt", "w");
        if (!blockFile) sysErrFatal("Couldn't open file blocks.txt for writing\n");

        inputFile = fopen("txin.txt", "w");
        if (!inputFile) sysErrFatal("Couldn't open file txin.txt for writing\n");

        outputFile = fopen("txout.txt", "w");
        if (!outputFile) sysErrFatal("Couldn't open file txout.txt for writing\n");

        FILE *sqlFile = fopen("blockchain.sql", "w");
        if (!sqlFile) sysErrFatal("Couldn't open file blockchain.sql for writing\n");

        fprintf(
            sqlFile,
            "PRAGMA journal_mode=MEMORY;\n"
            "PRAGMA synchronous=0;\n"
            "CREATE TABLE IF NOT EXISTS blocks(\n"
            "    block_id BIGINT NOT NULL PRIMARY KEY,\n"
            "    block_hash TEXT NOT NULL,\n"
            "    time BIGINT NOT NULL\n"
            ");\n"
            "\n"
            "CREATE TABLE IF NOT EXISTS tx(\n"
            "    tx_id BIGINT NOT NULL PRIMARY KEY,\n"
            "    tx_hash TEXT NOT NULL,\n"
            "    block_id BIGINT NOT NULL,\n"
            "    FOREIGN KEY (block_id) REFERENCES blocks (block_id)\n"
            ");\n"
            "\n"
            "CREATE TABLE IF NOT EXISTS txout(\n"
            "    txout_id BIGINT NOT NULL PRIMARY KEY,\n"
            "    address CHAR(40),\n"
            "    txout_value BIGINT NOT NULL,\n"
            "    tx_id BIGINT NOT NULL,\n"
            "    txout_pos INT NOT NULL,\n"
            "    FOREIGN KEY (tx_id) REFERENCES tx (tx_id)\n"
            ");\n"
            "\n"
            "CREATE TABLE IF NOT EXISTS txin(\n"
            "    txin_id BIGINT NOT NULL PRIMARY KEY,\n"
            "    txout_id BIGINT NOT NULL,\n"
            "    tx_id BIGINT NOT NULL,\n"
            "    txin_pos INT NOT NULL,\n"
            "    FOREIGN KEY (tx_id) REFERENCES tx (tx_id)\n"
            ");\n"
            "CREATE INDEX IF NOT EXISTS x_txin_txout ON txin (txout_id);\n"
            "CREATE INDEX IF NOT EXISTS x_txout_address ON txout (address);\n"
            "CREATE INDEX IF NOT EXISTS x_txin_txid ON txin (tx_id);\n"
            "CREATE INDEX IF NOT EXISTS x_txout_txid ON txout (tx_id);\n"
            "CREATE INDEX IF NOT EXISTS x_tx_txid ON tx (tx_id);\n"
            "CREATE INDEX IF NOT EXISTS x_txout_value ON txout(txout_value);\n"
            "CREATE INDEX IF NOT EXISTS x_blocks_id ON blocks(block_id);\n"
            "CREATE VIEW IF NOT EXISTS tx_full AS SELECT blocks.time, tx.tx_hash, tx.tx_id, txout.address, txout.txout_value FROM txout LEFT JOIN tx ON (tx.tx_id = txout.tx_id) LEFT JOIN blocks ON (tx.block_id = blocks.block_id);\n"
            "\n"
        );
        fclose(sqlFile);

        bashFile = fopen("blockchain.sh", "w");
        if (!bashFile) sysErrFatal("Couldn't open file blockchain.sh for writing!\n");

        // EDIT here: using /run/shm/ for performance on a server - modify to local path!
        fprintf(
            bashFile,
            "\n"
            "#!/bin/bash\n"
            "\n"
            "echo 'Recreating DB blockchain...'\n"
            "rm -f /run/shm/blockchain.sqlite\n"
            "mkdir ../blockchain\n"
            "cp -f ../blockchain/blockchain.sqlite /run/shm/\n"
            "sqlite3 /run/shm/blockchain.sqlite < blockchain.sql\n"
            "echo done\n"
            "echo\n"
            "rm -f blockchain.sql\n"
            "\n"
            "for i in blocks tx txin txout\n"
            "do\n"
            "    echo Importing table $i ...\n"
            "    echo \".import $i.txt $i\" | sqlite3 /run/shm/blockchain.sqlite\n"
            "    echo done\n"
            "    rm -f $i.txt\n"
            "    echo\n"
            "done\n"
            "mv -f /run/shm/blockchain.sqlite ../blockchain/blockchain.sqlite\n"
            "rm -f blockchain.sh\n"
            "\n"
        );
        fclose(bashFile);

        return 0;
    }

    virtual void startBlock(
        const Block *b,
        uint64_t chainSize
    )
    {
        uint8_t blockHash[kSHA256ByteSize];
        sha256Twice(blockHash, b->data, 80);

        const uint8_t *p = b->data;
        SKIP(uint32_t, version, p);
        SKIP(uint256_t, prevBlkHash, p);
        SKIP(uint256_t, blkMerkleRoot, p);
        LOAD(uint32_t, blkTime, p);

        blkID = b->height - 1;

        if (blkID >= cutoffBlock)
        {
            // block_id BIGINT PRIMARY KEY
            // block_hash BINARY(32)
            // time BIGINT
            fprintf(blockFile, "%" PRIu64 "|", blkID);

            writeEscapedBinaryBuffer(blockFile, blockHash, kSHA256ByteSize);
            fputc('|', blockFile);
            fprintf(blockFile, "%" PRIu64 "\n", (uint64_t)blkTime);
        }
        if (0 == (b->height) % 5000)
        {
            fprintf(
                stderr,
                "block=%8" PRIu64 " "
                "nbOutputs=%9" PRIu64 "\n",
                b->height,
                outputMap.size()
            );
        }
    }

    virtual void startTX(
        const uint8_t *p,
        const uint8_t *hash
    )
    {
        if (blkID >= cutoffBlock)
        {
            // tx_id BIGINT PRIMARY KEY
            // tx_hash BINARY(32)
            // block_id BIGINT
            fprintf(txFile, "%" PRIu64 "|", ++txID);

            writeEscapedBinaryBuffer(txFile, hash, kSHA256ByteSize);
            fputc('|', txFile);

            fprintf(txFile, "%" PRIu64 "\n", blkID);
        } else {
            txID++;
        }
    }

    virtual void endOutput(
        const uint8_t *p,
        uint64_t      value,
        const uint8_t *txHash,
        uint64_t      outputIndex,
        const uint8_t *outputScript,
        uint64_t      outputScriptSize
    )
    {
        uint8_t address[40];
        address[0] = 'X';
        address[1] = 0;

        uint8_t addrType[3];
        uint160_t pubKeyHash;
        int type = solveOutputScript(pubKeyHash.v, outputScript, outputScriptSize, addrType);
        if (likely(0 <= type)) hash160ToAddr(address, pubKeyHash.v);

        if (blkID >= cutoffBlock)
        {
            // txout_id BIGINT PRIMARY KEY
            // address CHAR(40)
            // txout_value BIGINT
            // tx_id BIGINT
            // txout_pos INT
            fprintf(
                outputFile,
                "%" PRIu64 "|"
                "%s|"
                "%" PRIu64 "|"
                "%" PRIu64 "|"
                "%" PRIu32 "\n"
                ,
                outputID,
                address,
                value,
                txID,
                (uint32_t)outputIndex
            );
        }

        uint32_t oi = outputIndex;
        uint8_t *h = allocHash256();
        memcpy(h, txHash, kSHA256ByteSize);

        uintptr_t ih = reinterpret_cast<uintptr_t>(h);
        uint32_t *h32 = reinterpret_cast<uint32_t *>(ih);
        h32[0] ^= oi;

        outputMap[h] = outputID++;
    }

    virtual void edge(
        uint64_t      value,
        const uint8_t *upTXHash,
        uint64_t      outputIndex,
        const uint8_t *outputScript,
        uint64_t      outputScriptSize,
        const uint8_t *downTXHash,
        uint64_t      inputIndex,
        const uint8_t *inputScript,
        uint64_t      inputScriptSize
    )
    {
        uint256_t h;
        uint32_t oi = outputIndex;
        memcpy(h.v, upTXHash, kSHA256ByteSize);

        uintptr_t ih = reinterpret_cast<uintptr_t>(h.v);
        uint32_t *h32 = reinterpret_cast<uint32_t *>(ih);
        h32[0] ^= oi;

        auto src = outputMap.find(h.v);
        if (outputMap.end() == src) errFatal("Unconnected input!");

        if (blkID >= cutoffBlock)
        {
            fprintf(
                inputFile,
                "%" PRIu64 "|"
                "%" PRIu64 "|"
                "%" PRIu64 "|"
                "%" PRIu32 "\n"
                ,
                inputID++,
                src->second,
                txID,
                (uint32_t)outputIndex
            );
        } else {
            inputID++;
        }
    }

    virtual void wrapup()
    {
        fclose(outputFile);
        fclose(inputFile);
        fclose(blockFile);
        fclose(txFile);
        system("chmod +x ./blockchain.sh");
        system("./blockchain.sh");
        info("Done.\n");
        exit(0);
    }
};

static SQLDump sqlDump;

<commit_msg>Drop SQLite indices on primary keys.<commit_after>// Full SQL dump of the blockchain

#include <fstream>

#include <util.h>
#include <stdio.h>
#include <stdlib.h>
#include <common.h>
#include <errlog.h>
#include <option.h>
#include <callback.h>
#include <unistd.h>
#include <stdint.h>
#include "sqlite3pp.h"

static uint8_t empty[kSHA256ByteSize] = { 0x42 };
typedef GoogMap<Hash256, uint64_t, Hash256Hasher, Hash256Equal>::Map OutputMap;

inline bool file_exists (const std::string &name)
{
    std::ifstream file(name);
    return (file.good());
}

static void writeEscapedBinaryBuffer(
    FILE          *f,
    const uint8_t *p,
    size_t        n
)
{
    char buf[3];
    p += n;

    while (n--)
    {
        uint8_t c = *(--p);
        sprintf(buf, "%02X", (unsigned char) c);
        fputs(buf, f);
    }
}

struct SQLDump: public Callback
{
    FILE *txFile;
    FILE *bashFile;
    FILE *blockFile;
    FILE *inputFile;
    FILE *outputFile;
    FILE *progressFile;

    uint64_t txID;
    uint64_t blkID;
    uint64_t inputID;
    uint64_t outputID;
    uint64_t cutoffBlock;
    OutputMap outputMap;
    optparse::OptionParser parser;

    SQLDump()
    {
        parser
        .usage("[options]")
        .version("")
        .description("create an SQL dump of the blockchain")
        .epilog("")
        ;
        parser
        .add_option("-a", "--atBlock")
        .action("store")
        .type("int")
        .set_default(1)
        .help("start dump at block <block> (default: genesis block) - this is ignored if a blockchain database already exists")
        ;
    }

    virtual const char                   *name() const
    {
        return "sqldump";
    }
    virtual const optparse::OptionParser *optionParser() const
    {
        return &parser;
    }
    virtual bool                         needTXHash() const
    {
        return true;
    }

    virtual void aliases(
        std::vector<const char *> &v
    ) const
    {
        v.push_back("dump");
    }

    virtual int init(
        int argc,
        const char *argv[]
    )
    {
        txID = 0;
        blkID = 0;
        inputID = 0;
        outputID = 0;

        static uint64_t sz = 32 * 1000 * 1000;
        outputMap.setEmptyKey(empty);
        outputMap.resize(sz);

        optparse::Values &values = parser.parse_args(argc, argv);
        if (!file_exists("../blockchain/blockchain.sqlite"))
        {
            cutoffBlock = values.get("atBlock");
        }
        else
        {
            sqlite3pp::database db("../blockchain/blockchain.sqlite");
            sqlite3pp::query qry(db, "SELECT MAX(block_id) FROM blocks");

            sqlite3pp::query::iterator i = qry.begin();

            cutoffBlock = (uint64_t) atoi((*i).get<char const *>(0)) + 1;

            info("Resuming from block %" PRIu64 ".\n", cutoffBlock);
        }

        info("Dumping the blockchain...");

        txFile = fopen("tx.txt", "w");
        if (!txFile) sysErrFatal("Couldn't open file tx.txt for writing\n");

        blockFile = fopen("blocks.txt", "w");
        if (!blockFile) sysErrFatal("Couldn't open file blocks.txt for writing\n");

        inputFile = fopen("txin.txt", "w");
        if (!inputFile) sysErrFatal("Couldn't open file txin.txt for writing\n");

        outputFile = fopen("txout.txt", "w");
        if (!outputFile) sysErrFatal("Couldn't open file txout.txt for writing\n");

        FILE *sqlFile = fopen("blockchain.sql", "w");
        if (!sqlFile) sysErrFatal("Couldn't open file blockchain.sql for writing\n");

        fprintf(
            sqlFile,
            "PRAGMA journal_mode=MEMORY;\n"
            "PRAGMA synchronous=0;\n"
            "CREATE TABLE IF NOT EXISTS blocks(\n"
            "    block_id BIGINT NOT NULL PRIMARY KEY,\n"
            "    block_hash TEXT NOT NULL,\n"
            "    time BIGINT NOT NULL\n"
            ");\n"
            "\n"
            "CREATE TABLE IF NOT EXISTS tx(\n"
            "    tx_id BIGINT NOT NULL PRIMARY KEY,\n"
            "    tx_hash TEXT NOT NULL,\n"
            "    block_id BIGINT NOT NULL,\n"
            "    FOREIGN KEY (block_id) REFERENCES blocks (block_id)\n"
            ");\n"
            "\n"
            "CREATE TABLE IF NOT EXISTS txout(\n"
            "    txout_id BIGINT NOT NULL PRIMARY KEY,\n"
            "    address CHAR(40),\n"
            "    txout_value BIGINT NOT NULL,\n"
            "    tx_id BIGINT NOT NULL,\n"
            "    txout_pos INT NOT NULL,\n"
            "    FOREIGN KEY (tx_id) REFERENCES tx (tx_id)\n"
            ");\n"
            "\n"
            "CREATE TABLE IF NOT EXISTS txin(\n"
            "    txin_id BIGINT NOT NULL PRIMARY KEY,\n"
            "    txout_id BIGINT NOT NULL,\n"
            "    tx_id BIGINT NOT NULL,\n"
            "    txin_pos INT NOT NULL,\n"
            "    FOREIGN KEY (tx_id) REFERENCES tx (tx_id)\n"
            ");\n"
            "CREATE INDEX IF NOT EXISTS x_txin_txout ON txin (txout_id);\n"
            "CREATE INDEX IF NOT EXISTS x_txout_address ON txout (address);\n"
            "CREATE INDEX IF NOT EXISTS x_txin_txid ON txin (tx_id);\n"
            "CREATE INDEX IF NOT EXISTS x_txout_txid ON txout (tx_id);\n"
            "CREATE INDEX IF NOT EXISTS x_txout_value ON txout (txout_value);\n"
            "CREATE VIEW IF NOT EXISTS tx_full AS SELECT blocks.time, tx.tx_hash, tx.tx_id, txout.address, txout.txout_value FROM txout LEFT JOIN tx ON (tx.tx_id = txout.tx_id) LEFT JOIN blocks ON (tx.block_id = blocks.block_id);\n"
            "\n"
        );
        fclose(sqlFile);

        bashFile = fopen("blockchain.sh", "w");
        if (!bashFile) sysErrFatal("Couldn't open file blockchain.sh for writing!\n");

        // EDIT here: using /run/shm/ for performance on a server - modify to local path!
        fprintf(
            bashFile,
            "\n"
            "#!/bin/bash\n"
            "\n"
            "echo 'Recreating DB blockchain...'\n"
            "rm -f /run/shm/blockchain.sqlite\n"
            "mkdir ../blockchain\n"
            "cp -f ../blockchain/blockchain.sqlite /run/shm/\n"
            "sqlite3 /run/shm/blockchain.sqlite < blockchain.sql\n"
            "echo done\n"
            "echo\n"
            "rm -f blockchain.sql\n"
            "\n"
            "for i in blocks tx txin txout\n"
            "do\n"
            "    echo Importing table $i ...\n"
            "    echo \".import $i.txt $i\" | sqlite3 /run/shm/blockchain.sqlite\n"
            "    echo done\n"
            "    rm -f $i.txt\n"
            "    echo\n"
            "done\n"
            "mv -f /run/shm/blockchain.sqlite ../blockchain/blockchain.sqlite\n"
            "rm -f blockchain.sh\n"
            "\n"
        );
        fclose(bashFile);

        return 0;
    }

    virtual void startBlock(
        const Block *b,
        uint64_t chainSize
    )
    {
        uint8_t blockHash[kSHA256ByteSize];
        sha256Twice(blockHash, b->data, 80);

        const uint8_t *p = b->data;
        SKIP(uint32_t, version, p);
        SKIP(uint256_t, prevBlkHash, p);
        SKIP(uint256_t, blkMerkleRoot, p);
        LOAD(uint32_t, blkTime, p);

        blkID = b->height - 1;

        if (blkID >= cutoffBlock)
        {
            // block_id BIGINT PRIMARY KEY
            // block_hash BINARY(32)
            // time BIGINT
            fprintf(blockFile, "%" PRIu64 "|", blkID);

            writeEscapedBinaryBuffer(blockFile, blockHash, kSHA256ByteSize);
            fputc('|', blockFile);
            fprintf(blockFile, "%" PRIu64 "\n", (uint64_t)blkTime);
        }
        if (0 == (b->height) % 5000)
        {
            fprintf(
                stderr,
                "block=%8" PRIu64 " "
                "nbOutputs=%9" PRIu64 "\n",
                b->height,
                outputMap.size()
            );
        }
    }

    virtual void startTX(
        const uint8_t *p,
        const uint8_t *hash
    )
    {
        if (blkID >= cutoffBlock)
        {
            // tx_id BIGINT PRIMARY KEY
            // tx_hash BINARY(32)
            // block_id BIGINT
            fprintf(txFile, "%" PRIu64 "|", ++txID);

            writeEscapedBinaryBuffer(txFile, hash, kSHA256ByteSize);
            fputc('|', txFile);

            fprintf(txFile, "%" PRIu64 "\n", blkID);
        } else {
            txID++;
        }
    }

    virtual void endOutput(
        const uint8_t *p,
        uint64_t      value,
        const uint8_t *txHash,
        uint64_t      outputIndex,
        const uint8_t *outputScript,
        uint64_t      outputScriptSize
    )
    {
        uint8_t address[40];
        address[0] = 'X';
        address[1] = 0;

        uint8_t addrType[3];
        uint160_t pubKeyHash;
        int type = solveOutputScript(pubKeyHash.v, outputScript, outputScriptSize, addrType);
        if (likely(0 <= type)) hash160ToAddr(address, pubKeyHash.v);

        if (blkID >= cutoffBlock)
        {
            // txout_id BIGINT PRIMARY KEY
            // address CHAR(40)
            // txout_value BIGINT
            // tx_id BIGINT
            // txout_pos INT
            fprintf(
                outputFile,
                "%" PRIu64 "|"
                "%s|"
                "%" PRIu64 "|"
                "%" PRIu64 "|"
                "%" PRIu32 "\n"
                ,
                outputID,
                address,
                value,
                txID,
                (uint32_t)outputIndex
            );
        }

        uint32_t oi = outputIndex;
        uint8_t *h = allocHash256();
        memcpy(h, txHash, kSHA256ByteSize);

        uintptr_t ih = reinterpret_cast<uintptr_t>(h);
        uint32_t *h32 = reinterpret_cast<uint32_t *>(ih);
        h32[0] ^= oi;

        outputMap[h] = outputID++;
    }

    virtual void edge(
        uint64_t      value,
        const uint8_t *upTXHash,
        uint64_t      outputIndex,
        const uint8_t *outputScript,
        uint64_t      outputScriptSize,
        const uint8_t *downTXHash,
        uint64_t      inputIndex,
        const uint8_t *inputScript,
        uint64_t      inputScriptSize
    )
    {
        uint256_t h;
        uint32_t oi = outputIndex;
        memcpy(h.v, upTXHash, kSHA256ByteSize);

        uintptr_t ih = reinterpret_cast<uintptr_t>(h.v);
        uint32_t *h32 = reinterpret_cast<uint32_t *>(ih);
        h32[0] ^= oi;

        auto src = outputMap.find(h.v);
        if (outputMap.end() == src) errFatal("Unconnected input!");

        if (blkID >= cutoffBlock)
        {
            fprintf(
                inputFile,
                "%" PRIu64 "|"
                "%" PRIu64 "|"
                "%" PRIu64 "|"
                "%" PRIu32 "\n"
                ,
                inputID++,
                src->second,
                txID,
                (uint32_t)outputIndex
            );
        } else {
            inputID++;
        }
    }

    virtual void wrapup()
    {
        fclose(outputFile);
        fclose(inputFile);
        fclose(blockFile);
        fclose(txFile);
        system("chmod +x ./blockchain.sh");
        system("./blockchain.sh");
        info("Done.\n");
        exit(0);
    }
};

static SQLDump sqlDump;

<|endoftext|>


<commit_before>//=================================================================================================
// Copyright 2013-2014 Dirk Lemstra <https://magick.codeplex.com/>
//
// Licensed under the ImageMagick License (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.imagemagick.org/script/license.php
//
// 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.
//=================================================================================================
#include "Stdafx.h"

using namespace System::IO;
using namespace System::Globalization;

namespace ImageMagick
{
	//==============================================================================================
	String^ Throw::FormatMessage(String^ message, ... array<Object^>^ args)
	{
		if (args->Length == 0)
			return message;

		return String::Format(CultureInfo::InvariantCulture, message, args);
	}
	//==============================================================================================
	void Throw::IfFalse(String^ paramName, bool condition, String^ message, ... array<Object^>^ args)
	{
		if (!condition)
			throw gcnew ArgumentException(FormatMessage(message, args), paramName);
	}
	//==============================================================================================
	void Throw::IfInvalidFileName(String^ fileName)
	{
		Throw::IfNullOrEmpty("fileName", fileName);

		if (fileName->Length > 248)
			return;

		int colonIndex = fileName->IndexOf(':');
		if (colonIndex + 1 > fileName->Length)
		{
			if (fileName->IndexOf(':', colonIndex + 1) != -1)
				return;
		}

		String^ path = Path::GetFullPath(fileName);
		if (path->EndsWith("]", StringComparison::OrdinalIgnoreCase))
		{
			int endIndex = path->IndexOf("[", StringComparison::OrdinalIgnoreCase);
			if (endIndex != -1)
				path = path->Substring(0, endIndex);
		}

		Throw::IfFalse("fileName", File::Exists(path), "Unable to find file: {0}", path);
	}
	//==============================================================================================
	void Throw::IfNegative(String^ paramName, Percentage value)
	{
		if ((double)value < 0.0)
			throw gcnew ArgumentException("Value should be greater then zero.", paramName);
	}
	//==============================================================================================
	void Throw::IfNull(String^ paramName, Object^ value)
	{
		if (value == nullptr)
			throw gcnew ArgumentNullException(paramName);
	}
	//==============================================================================================
	void Throw::IfNull(String^ paramName, Object^ value, String^ message, ... array<Object^>^ args)
	{
		if (value == nullptr)
			throw gcnew ArgumentNullException(paramName, FormatMessage(message, args));
	}
	//==============================================================================================
	void Throw::IfNullOrEmpty(String^ paramName, Array^ value)
	{
		Throw::IfNull(paramName, value);

		if (value->Length == 0)
			throw gcnew ArgumentException("Value cannot be empty", paramName);
	}
	//==============================================================================================
	void Throw::IfNullOrEmpty(String^ paramName, String^ value)
	{
		Throw::IfNull(paramName, value);

		if (value->Length == 0)
			throw gcnew ArgumentException("Value cannot be empty", paramName);
	}
	//==============================================================================================
	void Throw::IfNullOrEmpty(String^ paramName, String^ value, String^ message, ... array<Object^>^ args)
	{
		Throw::IfNull(paramName, value, message, args);

		if (value->Length == 0)
			throw gcnew ArgumentException(FormatMessage(message, args), paramName);
	}
	//==============================================================================================
	void Throw::IfOutOfRange(String^ paramName, int index, int length)
	{
		if (index < 0 || index >= length)
			throw gcnew ArgumentOutOfRangeException(paramName);
	}
	//==============================================================================================
	void Throw::IfTrue(String^ paramName, bool condition, String^ message, ... array<Object^>^ args)
	{
		if (condition)
			throw gcnew ArgumentException(FormatMessage(message, args), paramName);
	}
	//==============================================================================================
}
<commit_msg>Fixed Throw.IfInvalidFileName<commit_after>//=================================================================================================
// Copyright 2013-2014 Dirk Lemstra <https://magick.codeplex.com/>
//
// Licensed under the ImageMagick License (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.imagemagick.org/script/license.php
//
// 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.
//=================================================================================================
#include "Stdafx.h"

using namespace System::IO;
using namespace System::Globalization;

namespace ImageMagick
{
	//==============================================================================================
	String^ Throw::FormatMessage(String^ message, ... array<Object^>^ args)
	{
		if (args->Length == 0)
			return message;

		return String::Format(CultureInfo::InvariantCulture, message, args);
	}
	//==============================================================================================
	void Throw::IfFalse(String^ paramName, bool condition, String^ message, ... array<Object^>^ args)
	{
		if (!condition)
			throw gcnew ArgumentException(FormatMessage(message, args), paramName);
	}
	//==============================================================================================
	void Throw::IfInvalidFileName(String^ fileName)
	{
		Throw::IfNullOrEmpty("fileName", fileName);

		if (fileName->Length > 248)
			return;

		int colonIndex = fileName->IndexOf(':');
		if (colonIndex + 1 > fileName->Length)
		{
			if (fileName->IndexOf(':', colonIndex + 1) != -1)
				return;
		}

		if (!fileName->Contains("\\"))
			return;

		String^ path = Path::GetFullPath(fileName);
		if (path->EndsWith("]", StringComparison::OrdinalIgnoreCase))
		{
			int endIndex = path->IndexOf("[", StringComparison::OrdinalIgnoreCase);
			if (endIndex != -1)
				path = path->Substring(0, endIndex);
		}

		Throw::IfFalse("fileName", File::Exists(path), "Unable to find file: {0}", path);
	}
	//==============================================================================================
	void Throw::IfNegative(String^ paramName, Percentage value)
	{
		if ((double)value < 0.0)
			throw gcnew ArgumentException("Value should be greater then zero.", paramName);
	}
	//==============================================================================================
	void Throw::IfNull(String^ paramName, Object^ value)
	{
		if (value == nullptr)
			throw gcnew ArgumentNullException(paramName);
	}
	//==============================================================================================
	void Throw::IfNull(String^ paramName, Object^ value, String^ message, ... array<Object^>^ args)
	{
		if (value == nullptr)
			throw gcnew ArgumentNullException(paramName, FormatMessage(message, args));
	}
	//==============================================================================================
	void Throw::IfNullOrEmpty(String^ paramName, Array^ value)
	{
		Throw::IfNull(paramName, value);

		if (value->Length == 0)
			throw gcnew ArgumentException("Value cannot be empty", paramName);
	}
	//==============================================================================================
	void Throw::IfNullOrEmpty(String^ paramName, String^ value)
	{
		Throw::IfNull(paramName, value);

		if (value->Length == 0)
			throw gcnew ArgumentException("Value cannot be empty", paramName);
	}
	//==============================================================================================
	void Throw::IfNullOrEmpty(String^ paramName, String^ value, String^ message, ... array<Object^>^ args)
	{
		Throw::IfNull(paramName, value, message, args);

		if (value->Length == 0)
			throw gcnew ArgumentException(FormatMessage(message, args), paramName);
	}
	//==============================================================================================
	void Throw::IfOutOfRange(String^ paramName, int index, int length)
	{
		if (index < 0 || index >= length)
			throw gcnew ArgumentOutOfRangeException(paramName);
	}
	//==============================================================================================
	void Throw::IfTrue(String^ paramName, bool condition, String^ message, ... array<Object^>^ args)
	{
		if (condition)
			throw gcnew ArgumentException(FormatMessage(message, args), paramName);
	}
	//==============================================================================================
}
<|endoftext|>


<commit_before>#include "phune_rest_jamp.h"

static s3eCallback onResultPending;
static PhuneMatch *currentMatch = NULL;

static int32 onNullReturn(void *, void*){
	return 0;
}

static int32 onStartMatchReturn(void *data, void* userData){
	currentMatch = static_cast<PhuneMatch*>(data);
	onResultPending(NULL, userData);
	return 0;
}

int32 PhuneRestJamp::Init(s3eCallback onResult, s3eCallback onError, void *userData){
	return PhuneRest::Init(onResult, onError, userData);
}

int32 PhuneRestJamp::Login(s3eWebView* g_WebView, s3eCallback onResult, s3eCallback onError, void *userData){
	return PhuneRest::Login(g_WebView, onResult, onError, userData);
}

int32 PhuneRestJamp::GetMe(s3eCallback onResult, s3eCallback onError, void *userData){
	return PhuneRest::GetMe(onResult, onError, userData);
}

int32 PhuneRestJamp::StartMatch(JampGameId gameId, s3eCallback onResult, s3eCallback onError, void *userData){
	char buffer[50];
	sprintf(buffer, "%d", gameId);
	std::string s = std::string(buffer);
	onResultPending = onResult;
	return PhuneRest::StartMatch(s.c_str(), onStartMatchReturn, onError, userData);
}

int32 PhuneRestJamp::EndMatch(JampGameId gameId, std::string level, JampScore score, PlayerStatus status, s3eCallback onResult, s3eCallback onError, void *userData){
	if (currentMatch == NULL){
		onError(NULL, NULL);
		return 0;
	}
	char buffer[50];
	sprintf(buffer, "%d", gameId);
	std::string s = std::string(buffer);

	std::string s3 = std::string(SCORE_LEVEL_KEY_PREFIX);
	s3.append(level);

	score.matchId = currentMatch->matchId;

	PhunePlayer player;
	player.score = score.score;
	player.status = status;
	player.id = currentMatch->playerId;

	int64 t = getCurrentTime();

	//Send the result of the match
	PhuneRest::EndMatch(score.matchId, player, onNullReturn, onError);

    IwTrace(PHUNE, ("Creating map begin"));
    std::map<int64, JsonListObject<JsonString> > map;
    int consecutivePerfects = 0;
    int bestSequence = -1;
    bool allPerfects = true;
	//aggregate cells performance
    for (std::vector<JampCellPerformance>::iterator it = score.cellsPerformance.elements.begin(); it != score.cellsPerformance.elements.end(); it++){

        //Use the notes for events
        if(it->useNoteEvaluation){
            for (std::vector<JampNotePerformance>::iterator it2 = it->notesPerformance.elements.begin(); it2 != it->notesPerformance.elements.end(); it2++){
                if (it2->classification == PERFECT) {
                    consecutivePerfects++;
                }
                else{
                    allPerfects = false;
                    if(consecutivePerfects > 3 && consecutivePerfects > bestSequence){
                        bestSequence = consecutivePerfects;
                    }
                    consecutivePerfects = 0;
                }
            }

        }
        //use the cell for events
        else{
            if (it->classification == PERFECT) {
                consecutivePerfects++;
            }
            else{
                allPerfects = false;
                if(consecutivePerfects > 3 && consecutivePerfects > bestSequence){
                    bestSequence = consecutivePerfects;
                }
                consecutivePerfects = 0;
            }
        }

        //found
        if (map.find(it->cellId) == map.end()) {
            JsonListObject<JsonString> list;
            it->timeStamp = t;
            JsonString js;
            js.Deserialize(it->Serialize());
            list.pushElement(js);
            map.insert(std::make_pair(it->cellId,list));
        }
        else {
            it->timeStamp = t;
            std::string aux2;
            JsonString js2;
            js2.Deserialize(it->Serialize());
            map.find(it->cellId)->second.pushElement(js2);
        }
    }

    if(consecutivePerfects > 3 && consecutivePerfects > bestSequence){
        bestSequence = consecutivePerfects;
    }

    IwTrace(PHUNE, ("Creating map end"));
    IwTrace(PHUNE, ("Sending cells begin"));
    //store the Cell performances
    for (std::map<int64, JsonListObject<JsonString> >::iterator itMap = map.begin(); itMap != map.end(); itMap++){

        if (itMap->first > 0) {

            char buffer4[50];
            sprintf(buffer4, "%s%lld", CELL_PERFORMACE_PREFIX, itMap->first);
            std::string key_cell = std::string(buffer4);

            std::string out = itMap->second.Serialize();

            IwTrace(PHUNE, ("Sending cell %lld begin", itMap->first));

            PhuneRestBase::StoreGameDataJsonBatch(s.c_str(), key_cell.c_str(), itMap->second.Serialize().c_str(), onNullReturn, onError, userData, true);

            IwTrace(PHUNE, ("Sending cell %lld end", itMap->first));
        }
        else{
            IwTrace(PHUNE, ("Cell with invalid id:%lld. Ignoring...", itMap->first));
        }

    }
    IwTrace(PHUNE, ("Sending cells end"));

    //Send the events

    JsonListObject<GameTriggerdEvent> events;

    //consecutive perfects
    if(bestSequence != -1){
        ConsecutivePerfectsEvent cpe(bestSequence, gameId);

        cpe.playerId = currentMatch->playerId;

        events.pushElement(cpe);
    }

    //all perfects
    if(allPerfects){
        AllPerfectsEvent ape(gameId, level);
        ape.playerId = currentMatch->playerId;

        events.pushElement(ape);
    }

    if(events.elements.size() > 0){
        PhuneRest::StoreMatchEvents(events, score.matchId, onNullReturn, onError);
    }

	//store the score for the match
	score.timeStamp = t;
	PhuneRestBase::StoreGameDataJson(s.c_str(), s3.c_str(), score.Serialize().c_str(), onResult, onError, userData, true);

	currentMatch = NULL;

	return 0;
}

int32 PhuneRestJamp::GetHistoricScoreForLevelInGame(JampGameId gameId, const char *level, s3eCallback onResult, s3eCallback onError, void *userData){
	char buffer[50];
	sprintf(buffer, "%d", gameId);
	std::string s = std::string(buffer);

	std::string key_score = std::string(SCORE_LEVEL_KEY_PREFIX);
	key_score.append(level);
	return PhuneRestBase::GetGameDataJsonList(s.c_str(), key_score.c_str(), onResult, onError, userData);
}

int32 PhuneRestJamp::StorePackInfoInGame(JampGameId gameId, JampPack pack, s3eCallback onResult, s3eCallback onError, void *userData){
	char buffer[50];
	sprintf(buffer, "%d", gameId);
	std::string s = std::string(buffer);

	char buffer2[50];
	sprintf(buffer2, "%s%d", PACK_PREFIX, gameId);
	std::string s2 = std::string(buffer2);

	return PhuneRestBase::StoreGameDataJson(s.c_str(), s2.c_str(), pack.Serialize().c_str(), onResult, onError, userData);
}

int32 PhuneRestJamp::GetPackInfoInGame(JampGameId gameId, int64 packid, s3eCallback onResult, s3eCallback onError, void *userData){
	char buffer[50];
	sprintf(buffer, "%d", gameId);
	std::string s = std::string(buffer);

	char buffer2[50];
	sprintf(buffer2, "%s%d", PACK_PREFIX, gameId);
	std::string s2 = std::string(buffer2);

	return PhuneRestBase::GetGameDataJson(s.c_str(), s2.c_str(), onResult, onError, userData);
}

int32 PhuneRestJamp::StorePacksInGame(JampGameId gameId, JsonListObject<JampPack> packs, s3eCallback onResult, s3eCallback onError, void *userData){
	char buffer[50];
	sprintf(buffer, "%d", gameId);
	std::string s = std::string(buffer);

    int64 totalStars = 0;
    int64 starsWon = 0;

    for (std::vector<JampPack>::iterator it = packs.elements.begin(); it != packs.elements.end(); it++){
        totalStars += it->starsMax;
        starsWon += it->starsWon;
    }

    JampGameProgress gp;

    gp.progress = (starsWon/(float)totalStars)*100;

    PhuneRestBase::StoreGameDataJson(s.c_str(), GAME_PROGRESS_KEY, gp.Serialize().c_str(), onNullReturn, onError, NULL);

	return PhuneRestBase::StoreGameDataJsonList(s.c_str(), PACKS_KEY, packs, onResult, onError, userData);
}

int32 PhuneRestJamp::GetPacksInGame(JampGameId gameId, s3eCallback onResult, s3eCallback onError, void *userData){
	char buffer[50];
	sprintf(buffer, "%d", gameId);
	std::string s = std::string(buffer);

	return PhuneRestBase::GetGameDataJsonList(s.c_str(), PACKS_KEY, onResult, onError, userData);
}
<commit_msg>JAMP: returning result after match finish. The other requests are done in background. More responsive to UI<commit_after>#include "phune_rest_jamp.h"

static s3eCallback onResultPending;
static PhuneMatch *currentMatch = NULL;

static int32 onNullReturn(void *, void*){
	return 0;
}

static int32 onStartMatchReturn(void *data, void* userData){
	currentMatch = static_cast<PhuneMatch*>(data);
	onResultPending(NULL, userData);
	return 0;
}

int32 PhuneRestJamp::Init(s3eCallback onResult, s3eCallback onError, void *userData){
	return PhuneRest::Init(onResult, onError, userData);
}

int32 PhuneRestJamp::Login(s3eWebView* g_WebView, s3eCallback onResult, s3eCallback onError, void *userData){
	return PhuneRest::Login(g_WebView, onResult, onError, userData);
}

int32 PhuneRestJamp::GetMe(s3eCallback onResult, s3eCallback onError, void *userData){
	return PhuneRest::GetMe(onResult, onError, userData);
}

int32 PhuneRestJamp::StartMatch(JampGameId gameId, s3eCallback onResult, s3eCallback onError, void *userData){
	char buffer[50];
	sprintf(buffer, "%d", gameId);
	std::string s = std::string(buffer);
	onResultPending = onResult;
	return PhuneRest::StartMatch(s.c_str(), onStartMatchReturn, onError, userData);
}

int32 PhuneRestJamp::EndMatch(JampGameId gameId, std::string level, JampScore score, PlayerStatus status, s3eCallback onResult, s3eCallback onError, void *userData){
    if (currentMatch == NULL){
        onError(NULL, NULL);
        return 0;
    }
    char buffer[50];
    sprintf(buffer, "%d", gameId);
    std::string s = std::string(buffer);

    std::string s3 = std::string(SCORE_LEVEL_KEY_PREFIX);
    s3.append(level);

    score.matchId = currentMatch->matchId;

    PhunePlayer player;
    player.score = score.score;
    player.status = status;
    player.id = currentMatch->playerId;

    int64 t = getCurrentTime();

    //Send the result of the match
    PhuneRest::EndMatch(score.matchId, player, onResult, onError, userData);

    IwTrace(PHUNE, ("Creating map begin"));
    std::map<int64, JsonListObject<JsonString> > map;
    int consecutivePerfects = 0;
    int bestSequence = -1;
    bool allPerfects = true;
    //aggregate cells performance
    for (std::vector<JampCellPerformance>::iterator it = score.cellsPerformance.elements.begin(); it != score.cellsPerformance.elements.end(); it++){

        //Use the notes for events
        if(it->useNoteEvaluation){
            for (std::vector<JampNotePerformance>::iterator it2 = it->notesPerformance.elements.begin(); it2 != it->notesPerformance.elements.end(); it2++){

                if (it2->classification == PERFECT) {
                    consecutivePerfects++;
                }
                else{
                    allPerfects = false;
                    if(consecutivePerfects > 3 && consecutivePerfects > bestSequence){
                        bestSequence = consecutivePerfects;
                    }
                    consecutivePerfects = 0;
                }
            }

        }
        //use the cell for events
        else{
            if (it->classification == PERFECT) {
                consecutivePerfects++;
            }
            else{
                allPerfects = false;
                if(consecutivePerfects > 3 && consecutivePerfects > bestSequence){
                    bestSequence = consecutivePerfects;
                }
                consecutivePerfects = 0;
            }
        }

        //found
        if (map.find(it->cellId) == map.end()) {
            JsonListObject<JsonString> list;
            it->timeStamp = t;
            JsonString js;
            js.Deserialize(it->Serialize());
            list.pushElement(js);
            map.insert(std::make_pair(it->cellId,list));
        }
        else {
            it->timeStamp = t;
            std::string aux2;
            JsonString js2;
            js2.Deserialize(it->Serialize());
            map.find(it->cellId)->second.pushElement(js2);
        }
    }

    if(consecutivePerfects > 3 && consecutivePerfects > bestSequence){
        bestSequence = consecutivePerfects;
    }

    IwTrace(PHUNE, ("Creating map end"));
    IwTrace(PHUNE, ("Sending cells begin"));
    //store the Cell performances
    for (std::map<int64, JsonListObject<JsonString> >::iterator itMap = map.begin(); itMap != map.end(); itMap++){

        if (itMap->first > 0) {

            char buffer4[50];
            sprintf(buffer4, "%s%lld", CELL_PERFORMACE_PREFIX, itMap->first);
            std::string key_cell = std::string(buffer4);

            std::string out = itMap->second.Serialize();

            IwTrace(PHUNE, ("Sending cell %lld begin", itMap->first));

            PhuneRestBase::StoreGameDataJsonBatch(s.c_str(), key_cell.c_str(), itMap->second.Serialize().c_str(), onNullReturn, onError, userData, true);

            IwTrace(PHUNE, ("Sending cell %lld end", itMap->first));
        }
        else{
            IwTrace(PHUNE, ("Cell with invalid id:%lld. Ignoring...", itMap->first));
        }

    }
    IwTrace(PHUNE, ("Sending cells end"));

    //Send the events

    JsonListObject<GameTriggerdEvent> events;

    //consecutive perfects
    if(bestSequence != -1){
        ConsecutivePerfectsEvent cpe(bestSequence, gameId);

        cpe.playerId = currentMatch->playerId;

        events.pushElement(cpe);
    }

    //all perfects
    if(allPerfects){
        AllPerfectsEvent ape(gameId, level);
        ape.playerId = currentMatch->playerId;

        events.pushElement(ape);
    }

    if(events.elements.size() > 0){
        PhuneRest::StoreMatchEvents(events, score.matchId, onNullReturn, onError);
    }

    //store the score for the match
    score.timeStamp = t;
    PhuneRestBase::StoreGameDataJson(s.c_str(), s3.c_str(), score.Serialize().c_str(), onNullReturn, onError, NULL, true);

    currentMatch = NULL;

	return 0;
}

int32 PhuneRestJamp::GetHistoricScoreForLevelInGame(JampGameId gameId, const char *level, s3eCallback onResult, s3eCallback onError, void *userData){
	char buffer[50];
	sprintf(buffer, "%d", gameId);
	std::string s = std::string(buffer);

	std::string key_score = std::string(SCORE_LEVEL_KEY_PREFIX);
	key_score.append(level);
	return PhuneRestBase::GetGameDataJsonList(s.c_str(), key_score.c_str(), onResult, onError, userData);
}

int32 PhuneRestJamp::StorePackInfoInGame(JampGameId gameId, JampPack pack, s3eCallback onResult, s3eCallback onError, void *userData){
	char buffer[50];
	sprintf(buffer, "%d", gameId);
	std::string s = std::string(buffer);

	char buffer2[50];
	sprintf(buffer2, "%s%d", PACK_PREFIX, gameId);
	std::string s2 = std::string(buffer2);

	return PhuneRestBase::StoreGameDataJson(s.c_str(), s2.c_str(), pack.Serialize().c_str(), onResult, onError, userData);
}

int32 PhuneRestJamp::GetPackInfoInGame(JampGameId gameId, int64 packid, s3eCallback onResult, s3eCallback onError, void *userData){
	char buffer[50];
	sprintf(buffer, "%d", gameId);
	std::string s = std::string(buffer);

	char buffer2[50];
	sprintf(buffer2, "%s%d", PACK_PREFIX, gameId);
	std::string s2 = std::string(buffer2);

	return PhuneRestBase::GetGameDataJson(s.c_str(), s2.c_str(), onResult, onError, userData);
}

int32 PhuneRestJamp::StorePacksInGame(JampGameId gameId, JsonListObject<JampPack> packs, s3eCallback onResult, s3eCallback onError, void *userData){
	char buffer[50];
	sprintf(buffer, "%d", gameId);
	std::string s = std::string(buffer);

    int64 totalStars = 0;
    int64 starsWon = 0;

    for (std::vector<JampPack>::iterator it = packs.elements.begin(); it != packs.elements.end(); it++){
        totalStars += it->starsMax;
        starsWon += it->starsWon;
    }

    JampGameProgress gp;

    gp.progress = (starsWon/(float)totalStars)*100;

    PhuneRestBase::StoreGameDataJson(s.c_str(), GAME_PROGRESS_KEY, gp.Serialize().c_str(), onNullReturn, onError, NULL);

	return PhuneRestBase::StoreGameDataJsonList(s.c_str(), PACKS_KEY, packs, onResult, onError, userData);
}

int32 PhuneRestJamp::GetPacksInGame(JampGameId gameId, s3eCallback onResult, s3eCallback onError, void *userData){
	char buffer[50];
	sprintf(buffer, "%d", gameId);
	std::string s = std::string(buffer);

	return PhuneRestBase::GetGameDataJsonList(s.c_str(), PACKS_KEY, onResult, onError, userData);
}
<|endoftext|>


<commit_before>/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
**
** GNU Lesser General Public License Usage
**
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this file.
** Please review the following information to ensure the GNU Lesser General
** Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** Other Usage
**
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**************************************************************************/

#include "qmladapter.h"

#include "debuggerstartparameters.h"
#include "qscriptdebuggerclient.h"
#include "qmlv8debuggerclient.h"
#include "qmljsprivateapi.h"

#include "qmlengine.h"

#include <extensionsystem/pluginmanager.h>
#include <utils/qtcassert.h>

#include <qmljsdebugclient/qdebugmessageclient.h>

#include <QtCore/QTimer>
#include <QtCore/QDebug>

namespace Debugger {
namespace Internal {

class QmlAdapterPrivate
{
public:
    explicit QmlAdapterPrivate(DebuggerEngine *engine)
        : m_engine(engine)
        , m_qmlClient(0)
        , m_engineDebugClient(0)
        , m_conn(0)
        , m_currentSelectedDebugId(-1)
        , m_msgClient(0)
    {
        m_connectionTimer.setInterval(4000);
        m_connectionTimer.setSingleShot(true);
    }

    QWeakPointer<DebuggerEngine> m_engine;
    QmlDebuggerClient *m_qmlClient;
    QmlJsDebugClient::QDeclarativeEngineDebug *m_engineDebugClient;
    QTimer m_connectionTimer;
    QDeclarativeDebugConnection *m_conn;
    QHash<QString, QmlDebuggerClient*> debugClients;
    int m_currentSelectedDebugId;
    QString m_currentSelectedDebugName;
    QmlJsDebugClient::QDebugMessageClient *m_msgClient;
};

} // namespace Internal

QmlAdapter::QmlAdapter(DebuggerEngine *engine, QObject *parent)
    : QObject(parent), d(new Internal::QmlAdapterPrivate(engine))
{
    connect(&d->m_connectionTimer, SIGNAL(timeout()), SLOT(checkConnectionState()));
    d->m_conn = new QDeclarativeDebugConnection(this);
    connect(d->m_conn, SIGNAL(stateChanged(QAbstractSocket::SocketState)),
            SLOT(connectionStateChanged()));
    connect(d->m_conn, SIGNAL(error(QAbstractSocket::SocketError)),
            SLOT(connectionErrorOccurred(QAbstractSocket::SocketError)));

    ExtensionSystem::PluginManager *pluginManager =
        ExtensionSystem::PluginManager::instance();
    pluginManager->addObject(this);

    createDebuggerClients();
    d->m_msgClient = new QmlJsDebugClient::QDebugMessageClient(d->m_conn);
    connect(d->m_msgClient, SIGNAL(newStatus(QDeclarativeDebugClient::Status)),
            this, SLOT(clientStatusChanged(QDeclarativeDebugClient::Status)));
}

QmlAdapter::~QmlAdapter()
{
    ExtensionSystem::PluginManager *pluginManager =
        ExtensionSystem::PluginManager::instance();

    if (pluginManager->allObjects().contains(this))
        pluginManager->removeObject(this);
    delete d;
}

void QmlAdapter::beginConnection()
{
    if (d->m_engine.isNull()
            || (d->m_conn && d->m_conn->state() != QAbstractSocket::UnconnectedState))
        return;

    const DebuggerStartParameters &parameters = d->m_engine.data()->startParameters();
    if (parameters.communicationChannel == DebuggerStartParameters::CommunicationChannelUsb) {
        const QString &port = parameters.remoteChannel;
        showConnectionStatusMessage(tr("Connecting to debug server on %1").arg(port));
        d->m_conn->connectToOst(port);
    } else {
        const QString &address = parameters.qmlServerAddress;
        quint16 port = parameters.qmlServerPort;
        showConnectionStatusMessage(tr("Connecting to debug server %1:%2").arg(address).arg(QString::number(port)));
        d->m_conn->connectToHost(address, port);
    }

    //A timeout to check the connection state
    d->m_connectionTimer.start();
}

void QmlAdapter::closeConnection()
{
    if (d->m_connectionTimer.isActive()) {
        d->m_connectionTimer.stop();
    } else {
        if (d->m_conn) {
            d->m_conn->close();
        }
    }
}

void QmlAdapter::connectionErrorOccurred(QAbstractSocket::SocketError socketError)
{
    showConnectionStatusMessage(tr("Error: (%1) %2", "%1=error code, %2=error message")
                                .arg(socketError).arg(d->m_conn->errorString()));

    // this is only an error if we are already connected and something goes wrong.
    if (isConnected()) {
        emit connectionError(socketError);
    } else {
        d->m_connectionTimer.stop();
        emit connectionStartupFailed();
    }
}

void QmlAdapter::clientStatusChanged(QDeclarativeDebugClient::Status status)
{
    QString serviceName;
    if (QDeclarativeDebugClient *client = qobject_cast<QDeclarativeDebugClient*>(sender()))
        serviceName = client->name();

    logServiceStatusChange(serviceName, status);
}

void QmlAdapter::debugClientStatusChanged(QDeclarativeDebugClient::Status /*status*/)
{
    QDeclarativeDebugClient *client = qobject_cast<QDeclarativeDebugClient*>(sender());
    QTC_ASSERT(client, return);

    d->m_qmlClient =  qobject_cast<Internal::QmlDebuggerClient *>(client);
    d->m_qmlClient->startSession();
}

void QmlAdapter::connectionStateChanged()
{
    switch (d->m_conn->state()) {
    case QAbstractSocket::UnconnectedState:
    {
        showConnectionStatusMessage(tr("disconnected.\n\n"));
        emit disconnected();

        break;
    }
    case QAbstractSocket::HostLookupState:
        showConnectionStatusMessage(tr("resolving host..."));
        break;
    case QAbstractSocket::ConnectingState:
        showConnectionStatusMessage(tr("connecting to debug server..."));
        break;
    case QAbstractSocket::ConnectedState:
    {
        showConnectionStatusMessage(tr("connected.\n"));

        d->m_connectionTimer.stop();

        //reloadEngines();
        emit connected();
        break;
    }
    case QAbstractSocket::ClosingState:
        showConnectionStatusMessage(tr("closing..."));
        break;
    case QAbstractSocket::BoundState:
    case QAbstractSocket::ListeningState:
        break;
    }
}

void QmlAdapter::checkConnectionState()
{
    if (!isConnected()) {
        closeConnection();
        emit connectionStartupFailed();
    }
}

void QmlAdapter::createDebuggerClients()
{

    Internal::QScriptDebuggerClient *client1 = new Internal::QScriptDebuggerClient(d->m_conn);
    connect(client1, SIGNAL(newStatus(QDeclarativeDebugClient::Status)),
            this, SLOT(clientStatusChanged(QDeclarativeDebugClient::Status)));
    connect(client1, SIGNAL(newStatus(QDeclarativeDebugClient::Status)),
            this, SLOT(debugClientStatusChanged(QDeclarativeDebugClient::Status)));

    Internal::QmlV8DebuggerClient *client2 = new Internal::QmlV8DebuggerClient(d->m_conn);
    connect(client2, SIGNAL(newStatus(QDeclarativeDebugClient::Status)),
            this, SLOT(clientStatusChanged(QDeclarativeDebugClient::Status)));
    connect(client2, SIGNAL(newStatus(QDeclarativeDebugClient::Status)),
            this, SLOT(debugClientStatusChanged(QDeclarativeDebugClient::Status)));

    d->debugClients.insert(client1->name(),client1);
    d->debugClients.insert(client2->name(),client2);

    client1->setEngine((Internal::QmlEngine*)(d->m_engine.data()));
    client2->setEngine((Internal::QmlEngine*)(d->m_engine.data()));

    //engine->startSuccessful();  // FIXME: AAA: port to new debugger states
}

bool QmlAdapter::isConnected() const
{
    return d->m_conn && d->m_qmlClient && d->m_conn->state() == QAbstractSocket::ConnectedState;
}

QDeclarativeDebugConnection *QmlAdapter::connection() const
{
    return d->m_conn;
}

DebuggerEngine *QmlAdapter::debuggerEngine() const
{
    return d->m_engine.data();
}

void QmlAdapter::showConnectionStatusMessage(const QString &message)
{
    if (!d->m_engine.isNull())
        d->m_engine.data()->showMessage(QLatin1String("QML Debugger: ") + message, LogStatus);
}

void QmlAdapter::showConnectionErrorMessage(const QString &message)
{
    if (!d->m_engine.isNull())
        d->m_engine.data()->showMessage(QLatin1String("QML Debugger: ") + message, LogError);
}

bool QmlAdapter::disableJsDebugging(bool block)
{
    if (d->m_engine.isNull())
        return block;

    bool isBlocked = d->m_engine.data()->state() == InferiorRunOk;

    if (isBlocked == block)
        return block;

    if (block) {
        d->m_engine.data()->continueInferior();
    } else {
        d->m_engine.data()->requestInterruptInferior();
    }

    return isBlocked;
}

Internal::QmlDebuggerClient *QmlAdapter::activeDebuggerClient()
{
    return d->m_qmlClient;
}

QHash<QString, Internal::QmlDebuggerClient*> QmlAdapter::debuggerClients()
{
    return d->debugClients;
}

QmlJsDebugClient::QDeclarativeEngineDebug *QmlAdapter::engineDebugClient() const
{
    return d->m_engineDebugClient;
}

void QmlAdapter::setEngineDebugClient(QmlJsDebugClient::QDeclarativeEngineDebug *client)
{
    d->m_engineDebugClient = client;
}

QmlJsDebugClient::QDebugMessageClient *QmlAdapter::messageClient() const
{
    return d->m_msgClient;
}

int QmlAdapter::currentSelectedDebugId() const
{
    return d->m_currentSelectedDebugId;
}

QString QmlAdapter::currentSelectedDisplayName() const
{
    return d->m_currentSelectedDebugName;
}

void QmlAdapter::setCurrentSelectedDebugInfo(int currentDebugId, const QString &displayName)
{
    d->m_currentSelectedDebugId = currentDebugId;
    d->m_currentSelectedDebugName = displayName;
    emit selectionChanged();
}

void QmlAdapter::logServiceStatusChange(const QString &service,
                                        QDeclarativeDebugClient::Status newStatus)
{
    switch (newStatus) {
    case QDeclarativeDebugClient::Unavailable: {
        showConnectionStatusMessage(tr("Status of '%1' changed to 'unavailable'.").arg(service));
        break;
    }
    case QDeclarativeDebugClient::Enabled: {
        showConnectionStatusMessage(tr("Status of '%1' changed to 'enabled'.").arg(service));
        break;
    }

    case QDeclarativeDebugClient::NotConnected: {
        showConnectionStatusMessage(tr("Status of '%1' changed to 'not connected'.").arg(service));
        break;
    }
    }
}

void QmlAdapter::logServiceActivity(const QString &service, const QString &logMessage)
{
    if (!d->m_engine.isNull())
        d->m_engine.data()->showMessage(service + QLatin1Char(' ') + logMessage, LogDebug);
}

} // namespace Debugger
<commit_msg>QmlAdapter: Set the debug client when status is enabled<commit_after>/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
**
** GNU Lesser General Public License Usage
**
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this file.
** Please review the following information to ensure the GNU Lesser General
** Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** Other Usage
**
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**************************************************************************/

#include "qmladapter.h"

#include "debuggerstartparameters.h"
#include "qscriptdebuggerclient.h"
#include "qmlv8debuggerclient.h"
#include "qmljsprivateapi.h"

#include "qmlengine.h"

#include <extensionsystem/pluginmanager.h>
#include <utils/qtcassert.h>

#include <qmljsdebugclient/qdebugmessageclient.h>

#include <QtCore/QTimer>
#include <QtCore/QDebug>

namespace Debugger {
namespace Internal {

class QmlAdapterPrivate
{
public:
    explicit QmlAdapterPrivate(DebuggerEngine *engine)
        : m_engine(engine)
        , m_qmlClient(0)
        , m_engineDebugClient(0)
        , m_conn(0)
        , m_currentSelectedDebugId(-1)
        , m_msgClient(0)
    {
        m_connectionTimer.setInterval(4000);
        m_connectionTimer.setSingleShot(true);
    }

    QWeakPointer<DebuggerEngine> m_engine;
    QmlDebuggerClient *m_qmlClient;
    QmlJsDebugClient::QDeclarativeEngineDebug *m_engineDebugClient;
    QTimer m_connectionTimer;
    QDeclarativeDebugConnection *m_conn;
    QHash<QString, QmlDebuggerClient*> debugClients;
    int m_currentSelectedDebugId;
    QString m_currentSelectedDebugName;
    QmlJsDebugClient::QDebugMessageClient *m_msgClient;
};

} // namespace Internal

QmlAdapter::QmlAdapter(DebuggerEngine *engine, QObject *parent)
    : QObject(parent), d(new Internal::QmlAdapterPrivate(engine))
{
    connect(&d->m_connectionTimer, SIGNAL(timeout()), SLOT(checkConnectionState()));
    d->m_conn = new QDeclarativeDebugConnection(this);
    connect(d->m_conn, SIGNAL(stateChanged(QAbstractSocket::SocketState)),
            SLOT(connectionStateChanged()));
    connect(d->m_conn, SIGNAL(error(QAbstractSocket::SocketError)),
            SLOT(connectionErrorOccurred(QAbstractSocket::SocketError)));

    ExtensionSystem::PluginManager *pluginManager =
        ExtensionSystem::PluginManager::instance();
    pluginManager->addObject(this);

    createDebuggerClients();
    d->m_msgClient = new QmlJsDebugClient::QDebugMessageClient(d->m_conn);
    connect(d->m_msgClient, SIGNAL(newStatus(QDeclarativeDebugClient::Status)),
            this, SLOT(clientStatusChanged(QDeclarativeDebugClient::Status)));
}

QmlAdapter::~QmlAdapter()
{
    ExtensionSystem::PluginManager *pluginManager =
        ExtensionSystem::PluginManager::instance();

    if (pluginManager->allObjects().contains(this))
        pluginManager->removeObject(this);
    delete d;
}

void QmlAdapter::beginConnection()
{
    if (d->m_engine.isNull()
            || (d->m_conn && d->m_conn->state() != QAbstractSocket::UnconnectedState))
        return;

    const DebuggerStartParameters &parameters = d->m_engine.data()->startParameters();
    if (parameters.communicationChannel == DebuggerStartParameters::CommunicationChannelUsb) {
        const QString &port = parameters.remoteChannel;
        showConnectionStatusMessage(tr("Connecting to debug server on %1").arg(port));
        d->m_conn->connectToOst(port);
    } else {
        const QString &address = parameters.qmlServerAddress;
        quint16 port = parameters.qmlServerPort;
        showConnectionStatusMessage(tr("Connecting to debug server %1:%2").arg(address).arg(QString::number(port)));
        d->m_conn->connectToHost(address, port);
    }

    //A timeout to check the connection state
    d->m_connectionTimer.start();
}

void QmlAdapter::closeConnection()
{
    if (d->m_connectionTimer.isActive()) {
        d->m_connectionTimer.stop();
    } else {
        if (d->m_conn) {
            d->m_conn->close();
        }
    }
}

void QmlAdapter::connectionErrorOccurred(QAbstractSocket::SocketError socketError)
{
    showConnectionStatusMessage(tr("Error: (%1) %2", "%1=error code, %2=error message")
                                .arg(socketError).arg(d->m_conn->errorString()));

    // this is only an error if we are already connected and something goes wrong.
    if (isConnected()) {
        emit connectionError(socketError);
    } else {
        d->m_connectionTimer.stop();
        emit connectionStartupFailed();
    }
}

void QmlAdapter::clientStatusChanged(QDeclarativeDebugClient::Status status)
{
    QString serviceName;
    if (QDeclarativeDebugClient *client = qobject_cast<QDeclarativeDebugClient*>(sender()))
        serviceName = client->name();

    logServiceStatusChange(serviceName, status);
}

void QmlAdapter::debugClientStatusChanged(QDeclarativeDebugClient::Status status)
{
    if (status != QDeclarativeDebugClient::Enabled)
        return;
    QDeclarativeDebugClient *client = qobject_cast<QDeclarativeDebugClient*>(sender());
    QTC_ASSERT(client, return);

    d->m_qmlClient =  qobject_cast<Internal::QmlDebuggerClient *>(client);
    d->m_qmlClient->startSession();
}

void QmlAdapter::connectionStateChanged()
{
    switch (d->m_conn->state()) {
    case QAbstractSocket::UnconnectedState:
    {
        showConnectionStatusMessage(tr("disconnected.\n\n"));
        emit disconnected();

        break;
    }
    case QAbstractSocket::HostLookupState:
        showConnectionStatusMessage(tr("resolving host..."));
        break;
    case QAbstractSocket::ConnectingState:
        showConnectionStatusMessage(tr("connecting to debug server..."));
        break;
    case QAbstractSocket::ConnectedState:
    {
        showConnectionStatusMessage(tr("connected.\n"));

        d->m_connectionTimer.stop();

        //reloadEngines();
        emit connected();
        break;
    }
    case QAbstractSocket::ClosingState:
        showConnectionStatusMessage(tr("closing..."));
        break;
    case QAbstractSocket::BoundState:
    case QAbstractSocket::ListeningState:
        break;
    }
}

void QmlAdapter::checkConnectionState()
{
    if (!isConnected()) {
        closeConnection();
        emit connectionStartupFailed();
    }
}

void QmlAdapter::createDebuggerClients()
{

    Internal::QScriptDebuggerClient *client1 = new Internal::QScriptDebuggerClient(d->m_conn);
    connect(client1, SIGNAL(newStatus(QDeclarativeDebugClient::Status)),
            this, SLOT(clientStatusChanged(QDeclarativeDebugClient::Status)));
    connect(client1, SIGNAL(newStatus(QDeclarativeDebugClient::Status)),
            this, SLOT(debugClientStatusChanged(QDeclarativeDebugClient::Status)));

    Internal::QmlV8DebuggerClient *client2 = new Internal::QmlV8DebuggerClient(d->m_conn);
    connect(client2, SIGNAL(newStatus(QDeclarativeDebugClient::Status)),
            this, SLOT(clientStatusChanged(QDeclarativeDebugClient::Status)));
    connect(client2, SIGNAL(newStatus(QDeclarativeDebugClient::Status)),
            this, SLOT(debugClientStatusChanged(QDeclarativeDebugClient::Status)));

    d->debugClients.insert(client1->name(),client1);
    d->debugClients.insert(client2->name(),client2);

    client1->setEngine((Internal::QmlEngine*)(d->m_engine.data()));
    client2->setEngine((Internal::QmlEngine*)(d->m_engine.data()));

    //engine->startSuccessful();  // FIXME: AAA: port to new debugger states
}

bool QmlAdapter::isConnected() const
{
    return d->m_conn && d->m_qmlClient && d->m_conn->state() == QAbstractSocket::ConnectedState;
}

QDeclarativeDebugConnection *QmlAdapter::connection() const
{
    return d->m_conn;
}

DebuggerEngine *QmlAdapter::debuggerEngine() const
{
    return d->m_engine.data();
}

void QmlAdapter::showConnectionStatusMessage(const QString &message)
{
    if (!d->m_engine.isNull())
        d->m_engine.data()->showMessage(QLatin1String("QML Debugger: ") + message, LogStatus);
}

void QmlAdapter::showConnectionErrorMessage(const QString &message)
{
    if (!d->m_engine.isNull())
        d->m_engine.data()->showMessage(QLatin1String("QML Debugger: ") + message, LogError);
}

bool QmlAdapter::disableJsDebugging(bool block)
{
    if (d->m_engine.isNull())
        return block;

    bool isBlocked = d->m_engine.data()->state() == InferiorRunOk;

    if (isBlocked == block)
        return block;

    if (block) {
        d->m_engine.data()->continueInferior();
    } else {
        d->m_engine.data()->requestInterruptInferior();
    }

    return isBlocked;
}

Internal::QmlDebuggerClient *QmlAdapter::activeDebuggerClient()
{
    return d->m_qmlClient;
}

QHash<QString, Internal::QmlDebuggerClient*> QmlAdapter::debuggerClients()
{
    return d->debugClients;
}

QmlJsDebugClient::QDeclarativeEngineDebug *QmlAdapter::engineDebugClient() const
{
    return d->m_engineDebugClient;
}

void QmlAdapter::setEngineDebugClient(QmlJsDebugClient::QDeclarativeEngineDebug *client)
{
    d->m_engineDebugClient = client;
}

QmlJsDebugClient::QDebugMessageClient *QmlAdapter::messageClient() const
{
    return d->m_msgClient;
}

int QmlAdapter::currentSelectedDebugId() const
{
    return d->m_currentSelectedDebugId;
}

QString QmlAdapter::currentSelectedDisplayName() const
{
    return d->m_currentSelectedDebugName;
}

void QmlAdapter::setCurrentSelectedDebugInfo(int currentDebugId, const QString &displayName)
{
    d->m_currentSelectedDebugId = currentDebugId;
    d->m_currentSelectedDebugName = displayName;
    emit selectionChanged();
}

void QmlAdapter::logServiceStatusChange(const QString &service,
                                        QDeclarativeDebugClient::Status newStatus)
{
    switch (newStatus) {
    case QDeclarativeDebugClient::Unavailable: {
        showConnectionStatusMessage(tr("Status of '%1' changed to 'unavailable'.").arg(service));
        break;
    }
    case QDeclarativeDebugClient::Enabled: {
        showConnectionStatusMessage(tr("Status of '%1' changed to 'enabled'.").arg(service));
        break;
    }

    case QDeclarativeDebugClient::NotConnected: {
        showConnectionStatusMessage(tr("Status of '%1' changed to 'not connected'.").arg(service));
        break;
    }
    }
}

void QmlAdapter::logServiceActivity(const QString &service, const QString &logMessage)
{
    if (!d->m_engine.isNull())
        d->m_engine.data()->showMessage(service + QLatin1Char(' ') + logMessage, LogDebug);
}

} // namespace Debugger
<|endoftext|>


<commit_before>#include "vtkMoabReader.h"

#include "SimpleMoab.h"
#include "DataSetConverter.h"

#include "vtkNew.h"
#include "vtkObjectFactory.h"
#include "vtkInformation.h"
#include "vtkInformationVector.h"
#include "vtkMultiBlockDataSet.h"
#include "vtkUnstructuredGrid.h"

#include "vtkPolyData.h"

vtkStandardNewMacro(vtkMoabReader)
//------------------------------------------------------------------------------
vtkMoabReader::vtkMoabReader()
  {
  this->SetNumberOfInputPorts(0);
  this->FileName = NULL;
  }

//------------------------------------------------------------------------------
vtkMoabReader::~vtkMoabReader()
  {
  }

//------------------------------------------------------------------------------
int vtkMoabReader::RequestInformation(vtkInformation *request,
                       vtkInformationVector **inputVector,
                       vtkInformationVector *outputVector)
{

  //todo. Walk the file and display all the 2d and 3d elements that the users
  //could possibly want to load
  return this->Superclass::RequestInformation(request,inputVector,outputVector);
}

//------------------------------------------------------------------------------
int vtkMoabReader::RequestData(vtkInformation *vtkNotUsed(request),
                vtkInformationVector **vtkNotUsed(inputVector),
                vtkInformationVector *outputVector)
{
  //First pass is lets load in all 3d elements in a block called Volumes,
  //and load all 2d elements in a block called Surfaces

  vtkInformation* outInfo = outputVector->GetInformationObject(0);
  vtkMultiBlockDataSet *output =
    vtkMultiBlockDataSet::SafeDownCast(outInfo->Get(vtkDataObject::DATA_OBJECT()));

  vtkNew<vtkMultiBlockDataSet> volumeRoot;
  vtkNew<vtkMultiBlockDataSet> boundaryRoot;
  vtkNew<vtkMultiBlockDataSet> surfaceRoot;
  vtkNew<vtkMultiBlockDataSet> neumannRoot;
  vtkNew<vtkMultiBlockDataSet> dirichletRoot;

  const int blockIndex = output->GetNumberOfBlocks();
  output->SetBlock(blockIndex,volumeRoot.GetPointer());
  output->SetBlock(blockIndex+1,boundaryRoot.GetPointer());
  output->SetBlock(blockIndex+2,surfaceRoot.GetPointer());
  output->SetBlock(blockIndex+3,neumannRoot.GetPointer());
  output->SetBlock(blockIndex+4,dirichletRoot.GetPointer());

  //boring work, set the names of the blocks
  output->GetMetaData(blockIndex)->Set(vtkCompositeDataSet::NAME(), "Volumes");
  output->GetMetaData(blockIndex+1)->Set(vtkCompositeDataSet::NAME(), "Boundary");
  output->GetMetaData(blockIndex+2)->Set(vtkCompositeDataSet::NAME(), "Surfaces");
  output->GetMetaData(blockIndex+3)->Set(vtkCompositeDataSet::NAME(), "Neumann Sets");
  output->GetMetaData(blockIndex+4)->Set(vtkCompositeDataSet::NAME(), "Dirichlet Sets");

  smoab::GeomTag geom3Tag(3);
  smoab::GeomTag geom2Tag(2);
  smoab::GeomTag geom1Tag(2);
  smoab::NeumannTag neTag;
  smoab::DirichletTag diTag;

  smoab::Interface interface(this->FileName);
  this->CreateSubBlocks(volumeRoot, &interface, &geom3Tag);
  this->CreateSubBlocks(boundaryRoot, &interface, &geom3Tag, &geom2Tag);
  this->CreateSubBlocks(boundaryRoot, &interface, &geom3Tag, &geom1Tag);

  this->CreateSubBlocks(surfaceRoot, &interface, &geom2Tag);
  this->CreateSubBlocks(neumannRoot, &interface, &neTag);
  this->CreateSubBlocks(dirichletRoot, &interface, &diTag);

  return 1;
}

//------------------------------------------------------------------------------
void vtkMoabReader::CreateSubBlocks(vtkNew<vtkMultiBlockDataSet> & root,
                                    smoab::Interface* interface,
                                    smoab::Tag const* parentTag,
                                    smoab::Tag const* extractTag)
{
  if(!extractTag)
    {
    extractTag = parentTag;
    }
  //basic premise: query the database for all tagged elements and create a new
  //multiblock elemenent for each
  smoab::DataSetConverter converter(*interface,extractTag);
  converter.readMaterialIds(true);
  converter.readProperties(true);

  smoab::EntityHandle rootHandle = interface->getRoot();
  smoab::Range parents = interface->findEntityRootParents(rootHandle);
  smoab::Range dimEnts = interface->findEntitiesWithTag(*parentTag,
                                                       rootHandle);

  smoab::Range geomParents = smoab::intersect(parents,dimEnts);

  parents.clear(); //remove this range as it is unneeded
  dimEnts.clear();

  //now each item in range can be extracted into a different grid
  typedef smoab::Range::iterator iterator;
  vtkIdType index = 0;
  for(iterator i=geomParents.begin(); i != geomParents.end(); ++i)
    {
    vtkNew<vtkUnstructuredGrid> block;
    //fill the dataset with geometry and properties
    converter.fill(*i, block.GetPointer(),index);

    //only add it if we have cells found
    if(block->GetNumberOfCells() > 0)
      {
      root->SetBlock(index,block.GetPointer());
      std::string name = interface->name(*i);
      if(name.size() > 0)
        {
        root->GetMetaData(index)->Set(vtkCompositeDataSet::NAME(), name.c_str());
        }
      ++index;
      }
    }
}

//------------------------------------------------------------------------------
void vtkMoabReader::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os,indent);
}
<commit_msg>Read in material sets and correct 1d shell reading<commit_after>#include "vtkMoabReader.h"

#include "SimpleMoab.h"
#include "DataSetConverter.h"

#include "vtkNew.h"
#include "vtkObjectFactory.h"
#include "vtkInformation.h"
#include "vtkInformationVector.h"
#include "vtkMultiBlockDataSet.h"
#include "vtkUnstructuredGrid.h"

#include "vtkPolyData.h"

vtkStandardNewMacro(vtkMoabReader)
//------------------------------------------------------------------------------
vtkMoabReader::vtkMoabReader()
  {
  this->SetNumberOfInputPorts(0);
  this->FileName = NULL;
  }

//------------------------------------------------------------------------------
vtkMoabReader::~vtkMoabReader()
  {
  }

//------------------------------------------------------------------------------
int vtkMoabReader::RequestInformation(vtkInformation *request,
                       vtkInformationVector **inputVector,
                       vtkInformationVector *outputVector)
{

  //todo. Walk the file and display all the 2d and 3d elements that the users
  //could possibly want to load
  return this->Superclass::RequestInformation(request,inputVector,outputVector);
}

//------------------------------------------------------------------------------
int vtkMoabReader::RequestData(vtkInformation *vtkNotUsed(request),
                vtkInformationVector **vtkNotUsed(inputVector),
                vtkInformationVector *outputVector)
{
  //First pass is lets load in all 3d elements in a block called Volumes,
  //and load all 2d elements in a block called Surfaces

  vtkInformation* outInfo = outputVector->GetInformationObject(0);
  vtkMultiBlockDataSet *output =
    vtkMultiBlockDataSet::SafeDownCast(outInfo->Get(vtkDataObject::DATA_OBJECT()));

  vtkNew<vtkMultiBlockDataSet> volumeRoot;
  vtkNew<vtkMultiBlockDataSet> boundaryRoot;
  vtkNew<vtkMultiBlockDataSet> surfaceRoot;
  vtkNew<vtkMultiBlockDataSet> materialRoot;
  vtkNew<vtkMultiBlockDataSet> neumannRoot;
  vtkNew<vtkMultiBlockDataSet> dirichletRoot;

  const int blockIndex = output->GetNumberOfBlocks();
  output->SetBlock(blockIndex,volumeRoot.GetPointer());
  output->SetBlock(blockIndex+1,boundaryRoot.GetPointer());
  output->SetBlock(blockIndex+2,surfaceRoot.GetPointer());
  output->SetBlock(blockIndex+3,materialRoot.GetPointer());
  output->SetBlock(blockIndex+4,neumannRoot.GetPointer());
  output->SetBlock(blockIndex+5,dirichletRoot.GetPointer());

  //boring work, set the names of the blocks
  output->GetMetaData(blockIndex)->Set(vtkCompositeDataSet::NAME(), "Volumes");
  output->GetMetaData(blockIndex+1)->Set(vtkCompositeDataSet::NAME(), "Boundary");
  output->GetMetaData(blockIndex+2)->Set(vtkCompositeDataSet::NAME(), "Surfaces");
  output->GetMetaData(blockIndex+3)->Set(vtkCompositeDataSet::NAME(), "Material");
  output->GetMetaData(blockIndex+4)->Set(vtkCompositeDataSet::NAME(), "Neumann Sets");
  output->GetMetaData(blockIndex+5)->Set(vtkCompositeDataSet::NAME(), "Dirichlet Sets");

  smoab::GeomTag geom3Tag(3);
  smoab::GeomTag geom2Tag(2);
  smoab::GeomTag geom1Tag(1);
  smoab::MaterialTag matTag;
  smoab::NeumannTag neTag;
  smoab::DirichletTag diTag;

  smoab::Interface interface(this->FileName);
  this->CreateSubBlocks(volumeRoot, &interface, &geom3Tag);
  this->CreateSubBlocks(boundaryRoot, &interface, &geom3Tag, &geom2Tag);
  this->CreateSubBlocks(boundaryRoot, &interface, &geom3Tag, &geom1Tag);

  this->CreateSubBlocks(surfaceRoot, &interface, &geom2Tag);
  this->CreateSubBlocks(materialRoot, &interface, &matTag);
  this->CreateSubBlocks(neumannRoot, &interface, &neTag);
  this->CreateSubBlocks(dirichletRoot, &interface, &diTag);

  return 1;
}

//------------------------------------------------------------------------------
void vtkMoabReader::CreateSubBlocks(vtkNew<vtkMultiBlockDataSet> & root,
                                    smoab::Interface* interface,
                                    smoab::Tag const* parentTag,
                                    smoab::Tag const* extractTag)
{
  if(!extractTag)
    {
    extractTag = parentTag;
    }
  //basic premise: query the database for all tagged elements and create a new
  //multiblock elemenent for each
  smoab::DataSetConverter converter(*interface,extractTag);
  converter.readMaterialIds(true);
  converter.readProperties(true);

  smoab::EntityHandle rootHandle = interface->getRoot();
  smoab::Range parents = interface->findEntityRootParents(rootHandle);
  smoab::Range dimEnts = interface->findEntitiesWithTag(*parentTag,
                                                       rootHandle);

  smoab::Range geomParents = smoab::intersect(parents,dimEnts);

  parents.clear(); //remove this range as it is unneeded
  dimEnts.clear();

  //now each item in range can be extracted into a different grid
  typedef smoab::Range::iterator iterator;
  vtkIdType index = 0;
  for(iterator i=geomParents.begin(); i != geomParents.end(); ++i)
    {
    vtkNew<vtkUnstructuredGrid> block;
    //fill the dataset with geometry and properties
    converter.fill(*i, block.GetPointer(),index);

    //only add it if we have cells found
    if(block->GetNumberOfCells() > 0)
      {
      root->SetBlock(index,block.GetPointer());
      std::string name = interface->name(*i);
      if(name.size() > 0)
        {
        root->GetMetaData(index)->Set(vtkCompositeDataSet::NAME(), name.c_str());
        }
      ++index;
      }
    }
}

//------------------------------------------------------------------------------
void vtkMoabReader::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os,indent);
}
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2017-present ScyllaDB
 */

/*
 * This file is part of Scylla.
 *
 * Scylla 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.
 *
 * Scylla 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Scylla.  If not, see <http://www.gnu.org/licenses/>.
 */

#pragma once

#include <boost/test/unit_test.hpp>

#include "dht/i_partitioner.hh"
#include "schema.hh"
#include "sstables/index_reader.hh"
#include "reader_concurrency_semaphore.hh"

class index_reader_assertions {
    std::unique_ptr<sstables::index_reader> _r;
public:
    index_reader_assertions(std::unique_ptr<sstables::index_reader> r)
        : _r(std::move(r))
    { }

    index_reader_assertions& has_monotonic_positions(const schema& s) {
        tests::reader_concurrency_semaphore_wrapper semaphore;
        auto pos_cmp = sstables::promoted_index_block_compare(s);
        auto rp_cmp = dht::ring_position_comparator(s);
        auto prev = dht::ring_position::min();
        _r->read_partition_data().get();
        while (!_r->eof()) {
            auto k = _r->get_partition_key();
            auto rp = dht::ring_position(dht::decorate_key(s, k));

            if (rp_cmp(prev, rp) >= 0) {
                BOOST_FAIL(format("Partitions have invalid order: {} >= {}", prev, rp));
            }

            prev = rp;

            sstables::clustered_index_cursor* cur = _r->current_clustered_cursor();
            std::optional<sstables::promoted_index_block_position> prev_end;
            while (auto ei_opt = cur->next_entry().get0()) {
                sstables::clustered_index_cursor::entry_info& ei = *ei_opt;
                if (prev_end && pos_cmp(ei.start, sstables::to_view(*prev_end))) {
                    BOOST_FAIL(format("Index blocks are not monotonic: {} > {}", *prev_end, ei.start));
                }
                prev_end = sstables::materialize(ei.end);
            }
            _r->advance_to_next_partition().get();
        }
        return *this;
    }

    index_reader_assertions& is_empty(const schema& s) {
        _r->read_partition_data().get();
        while (!_r->eof()) {
            BOOST_REQUIRE(_r->get_promoted_index_size() == 0);
            _r->advance_to_next_partition().get();
        }
        return *this;
    }
};

inline
index_reader_assertions assert_that(std::unique_ptr<sstables::index_reader> r) {
    return { std::move(r) };
}
<commit_msg>test: lib: index_reader_assertions: close reader before it is destroyed<commit_after>/*
 * Copyright (C) 2017-present ScyllaDB
 */

/*
 * This file is part of Scylla.
 *
 * Scylla 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.
 *
 * Scylla 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Scylla.  If not, see <http://www.gnu.org/licenses/>.
 */

#pragma once

#include <boost/test/unit_test.hpp>

#include "dht/i_partitioner.hh"
#include "schema.hh"
#include "sstables/index_reader.hh"
#include "reader_concurrency_semaphore.hh"

class index_reader_assertions {
    std::unique_ptr<sstables::index_reader> _r;
public:
    // Must be called from a seastar thread
    ~index_reader_assertions() {
        close().get();
    }

    index_reader_assertions(std::unique_ptr<sstables::index_reader> r)
        : _r(std::move(r))
    { }

    index_reader_assertions& has_monotonic_positions(const schema& s) {
        tests::reader_concurrency_semaphore_wrapper semaphore;
        auto pos_cmp = sstables::promoted_index_block_compare(s);
        auto rp_cmp = dht::ring_position_comparator(s);
        auto prev = dht::ring_position::min();
        _r->read_partition_data().get();
        while (!_r->eof()) {
            auto k = _r->get_partition_key();
            auto rp = dht::ring_position(dht::decorate_key(s, k));

            if (rp_cmp(prev, rp) >= 0) {
                BOOST_FAIL(format("Partitions have invalid order: {} >= {}", prev, rp));
            }

            prev = rp;

            sstables::clustered_index_cursor* cur = _r->current_clustered_cursor();
            std::optional<sstables::promoted_index_block_position> prev_end;
            while (auto ei_opt = cur->next_entry().get0()) {
                sstables::clustered_index_cursor::entry_info& ei = *ei_opt;
                if (prev_end && pos_cmp(ei.start, sstables::to_view(*prev_end))) {
                    BOOST_FAIL(format("Index blocks are not monotonic: {} > {}", *prev_end, ei.start));
                }
                prev_end = sstables::materialize(ei.end);
            }
            _r->advance_to_next_partition().get();
        }
        return *this;
    }

    index_reader_assertions& is_empty(const schema& s) {
        _r->read_partition_data().get();
        while (!_r->eof()) {
            BOOST_REQUIRE(_r->get_promoted_index_size() == 0);
            _r->advance_to_next_partition().get();
        }
        return *this;
    }

    future<> close() noexcept {
        if (_r) {
            auto r = std::move(_r);
            auto f = r->close();
            return f.then([r = std::move(r)] {});
        }
        return make_ready_future<>();
    }
};

inline
index_reader_assertions assert_that(std::unique_ptr<sstables::index_reader> r) {
    return { std::move(r) };
}
<|endoftext|>


<commit_before>/**
 * This file is part of the CernVM File System.
 */
#include <benchmark/benchmark.h>

#include <fcntl.h>
#include <unistd.h>

#include "bm_util.h"
#include "platform.h"
#include "util/posix.h"

class BM_Syscalls : public benchmark::Fixture {
 protected:
  virtual void SetUp(const benchmark::State &st) {
  }

  virtual void TearDown(const benchmark::State &st) {
  }
};

BENCHMARK_DEFINE_F(BM_Syscalls, FileOpenClose)(benchmark::State &st) {
  while (st.KeepRunning()) {
    int fd = open("/dev/null", O_RDONLY);
    close(fd);
  }
  st.SetItemsProcessed(st.iterations());
  st.SetLabel("/dev/null");
}
BENCHMARK_REGISTER_F(BM_Syscalls, FileOpenClose)->Repetitions(3)->
  UseRealTime();

BENCHMARK_DEFINE_F(BM_Syscalls, Stat)(benchmark::State &st) {
  platform_stat64 info;
  while (st.KeepRunning()) {
    platform_stat("/dev/null", &info);
    ClobberMemory();
  }
  st.SetItemsProcessed(st.iterations());
  st.SetLabel("/dev/null");
}
BENCHMARK_REGISTER_F(BM_Syscalls, Stat)->Repetitions(3)->
  UseRealTime();

/**
 * Command-response with 100B commands and 4k responses
 */
BENCHMARK_DEFINE_F(BM_Syscalls, Pipe)(benchmark::State &st) {
  int pipe_cmd[2];
  int pipe_data[2];
  MakePipe(pipe_cmd);
  MakePipe(pipe_data);
  switch (fork()) {
    case -1:
      abort();
    case 0:
      close(pipe_cmd[1]);
      close(pipe_data[0]);
      char cmd_buf[100];
      char data_buf[4096];
      while (true) {
        ReadPipe(pipe_cmd[0], cmd_buf, sizeof(cmd_buf));
        if (pipe_cmd[0] == 'Q')
          exit(0);
        WritePipe(pipe_data[1], data_buf, sizeof(data_buf));
      }
  }
  close(pipe_cmd[0]);
  close(pipe_data[1]);
  char cmd_buf[100];
  char data_buf[4096];
  cmd_buf[0] = 'C';

  while (st.KeepRunning()) {
    WritePipe(pipe_cmd[1], cmd_buf, sizeof(cmd_buf));
    ReadPipe(pipe_data[0], data_buf, sizeof(data_buf));
    ClobberMemory();
  }
  st.SetItemsProcessed(st.iterations());

  close(pipe_data[0]);
  cmd_buf[0] = 'Q';
  WritePipe(pipe_cmd[1], cmd_buf, sizeof(cmd_buf));
  close(pipe_cmd[1]);
}
BENCHMARK_REGISTER_F(BM_Syscalls, Pipe)->Repetitions(3)->
  UseRealTime();
<commit_msg>additions to the micro benchmarks<commit_after>/**
 * This file is part of the CernVM File System.
 */
#include <benchmark/benchmark.h>

#include <fcntl.h>
#include <unistd.h>

#include "bm_util.h"
#include "platform.h"
#include "util/posix.h"

class BM_Syscalls : public benchmark::Fixture {
 protected:
  virtual void SetUp(const benchmark::State &st) {
  }

  virtual void TearDown(const benchmark::State &st) {
  }
};

BENCHMARK_DEFINE_F(BM_Syscalls, FileOpenClose)(benchmark::State &st) {
  while (st.KeepRunning()) {
    int fd = open("/dev/null", O_RDONLY);
    close(fd);
  }
  st.SetItemsProcessed(st.iterations());
  st.SetLabel("/dev/null");
}
BENCHMARK_REGISTER_F(BM_Syscalls, FileOpenClose)->Repetitions(3)->
  UseRealTime();

BENCHMARK_DEFINE_F(BM_Syscalls, Stat)(benchmark::State &st) {
  platform_stat64 info;
  while (st.KeepRunning()) {
    platform_stat("/dev/null", &info);
    ClobberMemory();
  }
  st.SetItemsProcessed(st.iterations());
  st.SetLabel("/dev/null");
}
BENCHMARK_REGISTER_F(BM_Syscalls, Stat)->Repetitions(3)->
  UseRealTime();

BENCHMARK_DEFINE_F(BM_Syscalls, Read)(benchmark::State &st) {
  int fd = open("/dev/zero", O_RDONLY);
  unsigned size = st.range_x();
  char *buf[size];
  assert(fd >= 0);

  while (st.KeepRunning()) {
    SafeRead(fd, buf, size);
    Escape(buf);
  }
  st.SetItemsProcessed(st.iterations());
  st.SetBytesProcessed(int64_t(st.iterations()) * int64_t(size));
  st.SetLabel("/dev/zero");

  close(fd);
}
BENCHMARK_REGISTER_F(BM_Syscalls, Read)->Repetitions(3)->
  UseRealTime()->Arg(4096)->Arg(128*1024);

/**
 * Command-response with 100B commands and 4k responses
 */
BENCHMARK_DEFINE_F(BM_Syscalls, Pipe)(benchmark::State &st) {
  int pipe_cmd[2];
  int pipe_data[2];
  MakePipe(pipe_cmd);
  MakePipe(pipe_data);
  switch (fork()) {
    case -1:
      abort();
    case 0:
      close(pipe_cmd[1]);
      close(pipe_data[0]);
      char cmd_buf[100];
      char data_buf[st.range_x()];
      while (true) {
        ReadPipe(pipe_cmd[0], cmd_buf, sizeof(cmd_buf));
        if (pipe_cmd[0] == 'Q')
          exit(0);
        WritePipe(pipe_data[1], data_buf, sizeof(data_buf));
      }
  }
  close(pipe_cmd[0]);
  close(pipe_data[1]);
  char cmd_buf[100];
  char data_buf[st.range_x()];
  cmd_buf[0] = 'C';

  while (st.KeepRunning()) {
    WritePipe(pipe_cmd[1], cmd_buf, sizeof(cmd_buf));
    SafeRead(pipe_data[0], data_buf, sizeof(data_buf));
    ClobberMemory();
  }
  st.SetItemsProcessed(st.iterations());
  st.SetBytesProcessed(int64_t(st.iterations()) * int64_t(st.range_x()));

  close(pipe_data[0]);
  cmd_buf[0] = 'Q';
  WritePipe(pipe_cmd[1], cmd_buf, sizeof(cmd_buf));
  close(pipe_cmd[1]);
}
BENCHMARK_REGISTER_F(BM_Syscalls, Pipe)->Repetitions(3)->
  UseRealTime()->Arg(4096)->Arg(128*1024);
<|endoftext|>


<commit_before><commit_msg>Logged more basic-block information in binary format<commit_after><|endoftext|>


<commit_before>#pragma once

#include <map>
#include <ros/console.h>

#include "AbstractCameraQueue.hpp"

template <class T>
class TrackingQueue {
public:
	TrackingQueue();
	~TrackingQueue();

	void enqueue(std::vector<CameraData> data);
	void enqueue(CameraData data);

	size_t getSize();
	std::vector<CameraData> dequeue();
	bool dataAvailable();

private:
	std::map<int, AbstractCameraQueue*> queues;
	std::vector<int> ids;
	int rrIndex;
	size_t size;
};

template <class T>
TrackingQueue<T>::TrackingQueue()
{
	size = 0;
	rrIndex = 0;
}

template <class T>
TrackingQueue<T>::~TrackingQueue()
{
	for (std::map<int, AbstractCameraQueue*>::iterator it = queues.begin(); it != queues.end(); it++) {
		delete it->second;
	}
}

template <class T>
void TrackingQueue<T>::enqueue(std::vector<CameraData> data)
{
	for (std::vector<CameraData>::iterator it = data.begin(); it != data.end(); it++) {
		enqueue(*it);
	}
}

template <class T>
void TrackingQueue<T>::enqueue(CameraData data)
{
	if (queues.count(data.quadcopterId) == 0) {
		queues[data.quadcopterId] = new T(8L * 1000 * 1000 * 1000 / 30,
										  15L * 1000 * 1000 * 1000 / 30,
										  4L * 1000 * 1000 * 1000 / 30);
		ids.push_back(data.quadcopterId);
	}

	size++;
	queues[data.quadcopterId]->enqueue(data);
}

template <class T>
size_t TrackingQueue<T>::getSize()
{
	return size;
}

template <class T>
std::vector<CameraData> TrackingQueue<T>::dequeue()
{
	if (size == 0) {
		return std::vector<CameraData>();
	}

	int index = rrIndex;
	int loopCount = 0;

	do {
		index  = (index + 1) % ids.size();
		loopCount++;

		if (queues[ids[index]]->dataAvailable()) {
			break;
		}
	} while (index != rrIndex);

	if (loopCount > ids.size()) {
		return std::vector<CameraData>();
	} else {
		rrIndex = index;
		std::vector<CameraData> result = queues[ids[index]]->dequeue();
		size -= result.size();

		return result;
	}
}

template <class T>
bool TrackingQueue<T>::dataAvailable()
{
	for (std::map<int, AbstractCameraQueue*>::iterator it = queues.begin(); it != queues.end(); it++) {
		if (it->second->dataAvailable()) {
			return true;
		}
	}

	return false;
}
<commit_msg>Increased arrival time even further<commit_after>#pragma once

#include <map>
#include <ros/console.h>

#include "AbstractCameraQueue.hpp"

template <class T>
class TrackingQueue {
public:
	TrackingQueue();
	~TrackingQueue();

	void enqueue(std::vector<CameraData> data);
	void enqueue(CameraData data);

	size_t getSize();
	std::vector<CameraData> dequeue();
	bool dataAvailable();

private:
	std::map<int, AbstractCameraQueue*> queues;
	std::vector<int> ids;
	int rrIndex;
	size_t size;
};

template <class T>
TrackingQueue<T>::TrackingQueue()
{
	size = 0;
	rrIndex = 0;
}

template <class T>
TrackingQueue<T>::~TrackingQueue()
{
	for (std::map<int, AbstractCameraQueue*>::iterator it = queues.begin(); it != queues.end(); it++) {
		delete it->second;
	}
}

template <class T>
void TrackingQueue<T>::enqueue(std::vector<CameraData> data)
{
	for (std::vector<CameraData>::iterator it = data.begin(); it != data.end(); it++) {
		enqueue(*it);
	}
}

template <class T>
void TrackingQueue<T>::enqueue(CameraData data)
{
	if (queues.count(data.quadcopterId) == 0) {
		queues[data.quadcopterId] = new T(10L * 1000 * 1000 * 1000 / 30,
										  18L * 1000 * 1000 * 1000 / 30,
										  4L * 1000 * 1000 * 1000 / 30);
		ids.push_back(data.quadcopterId);
	}

	size++;
	queues[data.quadcopterId]->enqueue(data);
}

template <class T>
size_t TrackingQueue<T>::getSize()
{
	return size;
}

template <class T>
std::vector<CameraData> TrackingQueue<T>::dequeue()
{
	if (size == 0) {
		return std::vector<CameraData>();
	}

	int index = rrIndex;
	int loopCount = 0;

	do {
		index  = (index + 1) % ids.size();
		loopCount++;

		if (queues[ids[index]]->dataAvailable()) {
			break;
		}
	} while (index != rrIndex);

	if (loopCount > ids.size()) {
		return std::vector<CameraData>();
	} else {
		rrIndex = index;
		std::vector<CameraData> result = queues[ids[index]]->dequeue();
		size -= result.size();

		return result;
	}
}

template <class T>
bool TrackingQueue<T>::dataAvailable()
{
	for (std::map<int, AbstractCameraQueue*>::iterator it = queues.begin(); it != queues.end(); it++) {
		if (it->second->dataAvailable()) {
			return true;
		}
	}

	return false;
}
<|endoftext|>


<commit_before><commit_msg>fix comment and tiny optimisation for shutdown.<commit_after><|endoftext|>


<commit_before>/*
 * Copyright 2015 - 2018 gtalent2@gmail.com
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

#pragma once

#include "types.hpp"

#if __has_include(<cstring>)
#include<cstring>
#else
extern "C" void *memcpy(void *dest, const void *src, std::size_t size);
#endif

int ox_memcmp(const void *ptr1, const void *ptr2, std::size_t size) noexcept;

constexpr void *ox_memcpy(void *dest, const void *src, std::size_t size) noexcept {
	auto srcBuf = static_cast<const char*>(src);
	auto dstBuf = static_cast<char*>(dest);
	for (std::size_t i = 0; i < size; i++) {
		dstBuf[i] = static_cast<char>(srcBuf[i]);
	}
	return dest;
}

constexpr void *ox_memset(void *ptr, int val, std::size_t size) noexcept {
	auto buf = static_cast<uint8_t*>(ptr);
	for (std::size_t i = 0; i < size; i++) {
		buf[i] = static_cast<uint8_t>(val);
	}
	return ptr;
}
<commit_msg>[ox/std] Add memset to memops.h<commit_after>/*
 * Copyright 2015 - 2018 gtalent2@gmail.com
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

#pragma once

#include "types.hpp"

#if __has_include(<cstring>)
#include<cstring>
#else
extern "C" {

void *memcpy(void *dest, const void *src, std::size_t size);

void *memset(void *ptr, int val, std::size_t size);

}
#endif

int ox_memcmp(const void *ptr1, const void *ptr2, std::size_t size) noexcept;

constexpr void *ox_memcpy(void *dest, const void *src, std::size_t size) noexcept {
	auto srcBuf = static_cast<const char*>(src);
	auto dstBuf = static_cast<char*>(dest);
	for (std::size_t i = 0; i < size; i++) {
		dstBuf[i] = static_cast<char>(srcBuf[i]);
	}
	return dest;
}

constexpr void *ox_memset(void *ptr, int val, std::size_t size) noexcept {
	auto buf = static_cast<uint8_t*>(ptr);
	for (std::size_t i = 0; i < size; i++) {
		buf[i] = static_cast<uint8_t>(val);
	}
	return ptr;
}
<|endoftext|>