<commit_before>// Copyright (c) 2010 Satoshi Nakamoto
// Copyright (c) 2009-2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "main.h"
#include "bitcoinrpc.h"

using namespace json_spirit;
using namespace std;

extern void TxToJSON(const CTransaction& tx, const uint256 hashBlock, json_spirit::Object& entry);
extern enum Checkpoints::CPMode CheckpointsMode;

double GetDifficulty(const CBlockIndex* blockindex)
{
    // Floating point number that is a multiple of the minimum difficulty,
    // minimum difficulty = 1.0.
    if (blockindex == NULL)
    {
        if (pindexBest == NULL)
            return 1.0;
        else
            blockindex = GetLastBlockIndex(pindexBest, false);
    }

    int nShift = (blockindex->nBits >> 24) & 0xff;

    double dDiff =
        (double)0x0000ffff / (double)(blockindex->nBits & 0x00ffffff);

    while (nShift < 29)
    {
        dDiff *= 256.0;
        nShift++;
    }
    while (nShift > 29)
    {
        dDiff /= 256.0;
        nShift--;
    }

    return dDiff;
}

double GetPoWMHashPS()
{

    int nPoWInterval = 72;
    int64_t nTargetSpacingWorkMin = 30, nTargetSpacingWork = 30;

    CBlockIndex* pindex = pindexGenesisBlock;
    CBlockIndex* pindexPrevWork = pindexGenesisBlock;

    while (pindex)
    {
        if (pindex->IsProofOfWork())
        {
            int64_t nActualSpacingWork = pindex->GetBlockTime() - pindexPrevWork->GetBlockTime();
            nTargetSpacingWork = ((nPoWInterval - 1) * nTargetSpacingWork + nActualSpacingWork + nActualSpacingWork) / (nPoWInterval + 1);
            nTargetSpacingWork = max(nTargetSpacingWork, nTargetSpacingWorkMin);
            pindexPrevWork = pindex;
        }

        pindex = pindex->pnext;
    }

    return GetDifficulty() * 4294.967296 / nTargetSpacingWork;
}

double GetPoSKernelPS()
{
    int nPoSInterval = 72;
    double dStakeKernelsTriedAvg = 0;
    int nStakesHandled = 0, nStakesTime = 0;

    CBlockIndex* pindex = pindexBest;;
    CBlockIndex* pindexPrevStake = NULL;

    while (pindex && nStakesHandled < nPoSInterval)
    {
        if (pindex->IsProofOfStake())
        {
            dStakeKernelsTriedAvg += GetDifficulty(pindex) * 4294967296.0;
            nStakesTime += pindexPrevStake ? (pindexPrevStake->nTime - pindex->nTime) : 0;
            pindexPrevStake = pindex;
            nStakesHandled++;
        }

        pindex = pindex->pprev;
    }

    return nStakesTime ? dStakeKernelsTriedAvg / nStakesTime : 0;
}

Object blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool fPrintTransactionDetail)
{
    Object result;
    result.push_back(Pair("hash", block.GetHash().GetHex()));
    CMerkleTx txGen(block.vtx[0]);
    txGen.SetMerkleBranch(&block);
    result.push_back(Pair("confirmations", (int)txGen.GetDepthInMainChain()));
    result.push_back(Pair("size", (int)::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION)));
    result.push_back(Pair("height", blockindex->nHeight));
    result.push_back(Pair("version", block.nVersion));
    result.push_back(Pair("merkleroot", block.hashMerkleRoot.GetHex()));
    result.push_back(Pair("mint", ValueFromAmount(blockindex->nMint)));
    result.push_back(Pair("time", (boost::int64_t)block.GetBlockTime()));
    result.push_back(Pair("nonce", (boost::uint64_t)block.nNonce));
    result.push_back(Pair("bits", HexBits(block.nBits)));
    result.push_back(Pair("difficulty", GetDifficulty(blockindex)));
    result.push_back(Pair("blocktrust", leftTrim(blockindex->GetBlockTrust().GetHex(), '0')));
    result.push_back(Pair("chaintrust", leftTrim(blockindex->nChainTrust.GetHex(), '0')));
    if (blockindex->pprev)
        result.push_back(Pair("previousblockhash", blockindex->pprev->GetBlockHash().GetHex()));
    if (blockindex->pnext)
        result.push_back(Pair("nextblockhash", blockindex->pnext->GetBlockHash().GetHex()));

    result.push_back(Pair("flags", strprintf("%s%s", blockindex->IsProofOfStake()? "proof-of-stake" : "proof-of-work", blockindex->GeneratedStakeModifier()? " stake-modifier": "")));
    result.push_back(Pair("proofhash", blockindex->IsProofOfStake()? blockindex->hashProofOfStake.GetHex() : blockindex->GetBlockHash().GetHex()));
    result.push_back(Pair("entropybit", (int)blockindex->GetStakeEntropyBit()));
    result.push_back(Pair("modifier", strprintf("%016"PRIx64, blockindex->nStakeModifier)));
    result.push_back(Pair("modifierchecksum", strprintf("%08x", blockindex->nStakeModifierChecksum)));
    Array txinfo;
    BOOST_FOREACH (const CTransaction& tx, block.vtx)
    {
        if (fPrintTransactionDetail)
        {
            Object entry;

            entry.push_back(Pair("txid", tx.GetHash().GetHex()));
            TxToJSON(tx, 0, entry);

            txinfo.push_back(entry);
        }
        else
            txinfo.push_back(tx.GetHash().GetHex());
    }

    result.push_back(Pair("tx", txinfo));

    if (block.IsProofOfStake())
        result.push_back(Pair("signature", HexStr(block.vchBlockSig.begin(), block.vchBlockSig.end())));

    return result;
}

Value getbestblockhash(const Array& params, bool fHelp)
{
    if (fHelp || params.size() != 0)
        throw runtime_error(
            "getbestblockhash\n"
            "Returns the hash of the best block in the longest block chain.");

    return hashBestChain.GetHex();
}

Value getblockcount(const Array& params, bool fHelp)
{
    if (fHelp || params.size() != 0)
        throw runtime_error(
            "getblockcount\n"
            "Returns the number of blocks in the longest block chain.");

    return nBestHeight;
}

Value getdifficulty(const Array& params, bool fHelp)
{
    if (fHelp || params.size() != 0)
        throw runtime_error(
            "getdifficulty\n"
            "Returns the difficulty as a multiple of the minimum difficulty.");

    Object obj;
    obj.push_back(Pair("proof-of-work",        GetDifficulty()));
    obj.push_back(Pair("proof-of-stake",       GetDifficulty(GetLastBlockIndex(pindexBest, true))));
    obj.push_back(Pair("search-interval",      (int)nLastCoinStakeSearchInterval));
    return obj;
}

Value settxfee(const Array& params, bool fHelp)
{
    if (fHelp || params.size() < 1 || params.size() > 1 || AmountFromValue(params[0]) < MIN_TX_FEE)
        throw runtime_error(
            "settxfee <amount>\n"
            "<amount> is a real and is rounded to the nearest 0.01");

    nTransactionFee = AmountFromValue(params[0]);
    nTransactionFee = (nTransactionFee / CENT) * CENT;  // round to cent

    return true;
}

Value getrawmempool(const Array& params, bool fHelp)
{
    if (fHelp || params.size() != 0)
        throw runtime_error(
            "getrawmempool\n"
            "Returns all transaction ids in memory pool.");

    vector<uint256> vtxid;
    mempool.queryHashes(vtxid);

    Array a;
    BOOST_FOREACH(const uint256& hash, vtxid)
        a.push_back(hash.ToString());

    return a;
}

Value getblockhash(const Array& params, bool fHelp)
{
    if (fHelp || params.size() != 1)
        throw runtime_error(
            "getblockhash <index>\n"
            "Returns hash of block in best-block-chain at <index>.");

    int nHeight = params[0].get_int();
    if (nHeight < 0 || nHeight > nBestHeight)
        throw runtime_error("Block number out of range.");

    CBlockIndex* pblockindex = FindBlockByHeight(nHeight);
    return pblockindex->phashBlock->GetHex();
}

Value getblock(const Array& params, bool fHelp)
{
    if (fHelp || params.size() < 1 || params.size() > 2)
        throw runtime_error(
            "getblock <hash> [txinfo]\n"
            "txinfo optional to print more detailed tx info\n"
            "Returns details of a block with given block-hash.");

    std::string strHash = params[0].get_str();
    uint256 hash(strHash);

    if (mapBlockIndex.count(hash) == 0)
        throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");

    CBlock block;
    CBlockIndex* pblockindex = mapBlockIndex[hash];
    block.ReadFromDisk(pblockindex, true);

    return blockToJSON(block, pblockindex, params.size() > 1 ? params[1].get_bool() : false);
}

Value getblockbynumber(const Array& params, bool fHelp)
{
    if (fHelp || params.size() < 1 || params.size() > 2)
        throw runtime_error(
            "getblock <number> [txinfo]\n"
            "txinfo optional to print more detailed tx info\n"
            "Returns details of a block with given block-number.");

    int nHeight = params[0].get_int();
    if (nHeight < 0 || nHeight > nBestHeight)
        throw runtime_error("Block number out of range.");

    CBlock block;
    CBlockIndex* pblockindex = mapBlockIndex[hashBestChain];
    while (pblockindex->nHeight > nHeight)
        pblockindex = pblockindex->pprev;

    uint256 hash = *pblockindex->phashBlock;

    pblockindex = mapBlockIndex[hash];
    block.ReadFromDisk(pblockindex, true);

    return blockToJSON(block, pblockindex, params.size() > 1 ? params[1].get_bool() : false);
}

// ppcoin: get information of sync-checkpoint
Value getcheckpoint(const Array& params, bool fHelp)
{
    if (fHelp || params.size() != 0)
        throw runtime_error(
            "getcheckpoint\n"
            "Show info of synchronized checkpoint.\n");

    Object result;
    CBlockIndex* pindexCheckpoint;

    result.push_back(Pair("synccheckpoint", Checkpoints::hashSyncCheckpoint.ToString().c_str()));
    pindexCheckpoint = mapBlockIndex[Checkpoints::hashSyncCheckpoint];
    result.push_back(Pair("height", pindexCheckpoint->nHeight));
    result.push_back(Pair("timestamp", DateTimeStrFormat(pindexCheckpoint->GetBlockTime()).c_str()));

    // Check that the block satisfies synchronized checkpoint
    if (CheckpointsMode == Checkpoints::STRICT)
        result.push_back(Pair("policy", "strict"));

    if (CheckpointsMode == Checkpoints::ADVISORY)
        result.push_back(Pair("policy", "advisory"));

    if (CheckpointsMode == Checkpoints::PERMISSIVE)
        result.push_back(Pair("policy", "permissive"));

    if (mapArgs.count("-checkpointkey"))
        result.push_back(Pair("checkpointmaster", true));

    return result;
}
<commit_msg>PoW End<commit_after>// Copyright (c) 2010 Satoshi Nakamoto
// Copyright (c) 2009-2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "main.h"
#include "bitcoinrpc.h"

using namespace json_spirit;
using namespace std;

extern void TxToJSON(const CTransaction& tx, const uint256 hashBlock, json_spirit::Object& entry);
extern enum Checkpoints::CPMode CheckpointsMode;

double GetDifficulty(const CBlockIndex* blockindex)
{
    // Floating point number that is a multiple of the minimum difficulty,
    // minimum difficulty = 1.0.
    if (blockindex == NULL)
    {
        if (pindexBest == NULL)
            return 1.0;
        else
            blockindex = GetLastBlockIndex(pindexBest, false);
    }

    int nShift = (blockindex->nBits >> 24) & 0xff;

    double dDiff =
        (double)0x0000ffff / (double)(blockindex->nBits & 0x00ffffff);

    while (nShift < 29)
    {
        dDiff *= 256.0;
        nShift++;
    }
    while (nShift > 29)
    {
        dDiff /= 256.0;
        nShift--;
    }

    return dDiff;
}

double GetPoWMHashPS()
{

    if (pindexBest->nHeight >= LAST_POW_BLOCK)
        return 0;

    int nPoWInterval = 72;
    int64_t nTargetSpacingWorkMin = 30, nTargetSpacingWork = 30;

    CBlockIndex* pindex = pindexGenesisBlock;
    CBlockIndex* pindexPrevWork = pindexGenesisBlock;

    while (pindex)
    {
        if (pindex->IsProofOfWork())
        {
            int64_t nActualSpacingWork = pindex->GetBlockTime() - pindexPrevWork->GetBlockTime();
            nTargetSpacingWork = ((nPoWInterval - 1) * nTargetSpacingWork + nActualSpacingWork + nActualSpacingWork) / (nPoWInterval + 1);
            nTargetSpacingWork = max(nTargetSpacingWork, nTargetSpacingWorkMin);
            pindexPrevWork = pindex;
        }

        pindex = pindex->pnext;
    }

    return GetDifficulty() * 4294.967296 / nTargetSpacingWork;
}

double GetPoSKernelPS()
{
    int nPoSInterval = 72;
    double dStakeKernelsTriedAvg = 0;
    int nStakesHandled = 0, nStakesTime = 0;

    CBlockIndex* pindex = pindexBest;;
    CBlockIndex* pindexPrevStake = NULL;

    while (pindex && nStakesHandled < nPoSInterval)
    {
        if (pindex->IsProofOfStake())
        {
            dStakeKernelsTriedAvg += GetDifficulty(pindex) * 4294967296.0;
            nStakesTime += pindexPrevStake ? (pindexPrevStake->nTime - pindex->nTime) : 0;
            pindexPrevStake = pindex;
            nStakesHandled++;
        }

        pindex = pindex->pprev;
    }

    return nStakesTime ? dStakeKernelsTriedAvg / nStakesTime : 0;
}

Object blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool fPrintTransactionDetail)
{
    Object result;
    result.push_back(Pair("hash", block.GetHash().GetHex()));
    CMerkleTx txGen(block.vtx[0]);
    txGen.SetMerkleBranch(&block);
    result.push_back(Pair("confirmations", (int)txGen.GetDepthInMainChain()));
    result.push_back(Pair("size", (int)::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION)));
    result.push_back(Pair("height", blockindex->nHeight));
    result.push_back(Pair("version", block.nVersion));
    result.push_back(Pair("merkleroot", block.hashMerkleRoot.GetHex()));
    result.push_back(Pair("mint", ValueFromAmount(blockindex->nMint)));
    result.push_back(Pair("time", (boost::int64_t)block.GetBlockTime()));
    result.push_back(Pair("nonce", (boost::uint64_t)block.nNonce));
    result.push_back(Pair("bits", HexBits(block.nBits)));
    result.push_back(Pair("difficulty", GetDifficulty(blockindex)));
    result.push_back(Pair("blocktrust", leftTrim(blockindex->GetBlockTrust().GetHex(), '0')));
    result.push_back(Pair("chaintrust", leftTrim(blockindex->nChainTrust.GetHex(), '0')));
    if (blockindex->pprev)
        result.push_back(Pair("previousblockhash", blockindex->pprev->GetBlockHash().GetHex()));
    if (blockindex->pnext)
        result.push_back(Pair("nextblockhash", blockindex->pnext->GetBlockHash().GetHex()));

    result.push_back(Pair("flags", strprintf("%s%s", blockindex->IsProofOfStake()? "proof-of-stake" : "proof-of-work", blockindex->GeneratedStakeModifier()? " stake-modifier": "")));
    result.push_back(Pair("proofhash", blockindex->IsProofOfStake()? blockindex->hashProofOfStake.GetHex() : blockindex->GetBlockHash().GetHex()));
    result.push_back(Pair("entropybit", (int)blockindex->GetStakeEntropyBit()));
    result.push_back(Pair("modifier", strprintf("%016"PRIx64, blockindex->nStakeModifier)));
    result.push_back(Pair("modifierchecksum", strprintf("%08x", blockindex->nStakeModifierChecksum)));
    Array txinfo;
    BOOST_FOREACH (const CTransaction& tx, block.vtx)
    {
        if (fPrintTransactionDetail)
        {
            Object entry;

            entry.push_back(Pair("txid", tx.GetHash().GetHex()));
            TxToJSON(tx, 0, entry);

            txinfo.push_back(entry);
        }
        else
            txinfo.push_back(tx.GetHash().GetHex());
    }

    result.push_back(Pair("tx", txinfo));

    if (block.IsProofOfStake())
        result.push_back(Pair("signature", HexStr(block.vchBlockSig.begin(), block.vchBlockSig.end())));

    return result;
}

Value getbestblockhash(const Array& params, bool fHelp)
{
    if (fHelp || params.size() != 0)
        throw runtime_error(
            "getbestblockhash\n"
            "Returns the hash of the best block in the longest block chain.");

    return hashBestChain.GetHex();
}

Value getblockcount(const Array& params, bool fHelp)
{
    if (fHelp || params.size() != 0)
        throw runtime_error(
            "getblockcount\n"
            "Returns the number of blocks in the longest block chain.");

    return nBestHeight;
}

Value getdifficulty(const Array& params, bool fHelp)
{
    if (fHelp || params.size() != 0)
        throw runtime_error(
            "getdifficulty\n"
            "Returns the difficulty as a multiple of the minimum difficulty.");

    Object obj;
    obj.push_back(Pair("proof-of-work",        GetDifficulty()));
    obj.push_back(Pair("proof-of-stake",       GetDifficulty(GetLastBlockIndex(pindexBest, true))));
    obj.push_back(Pair("search-interval",      (int)nLastCoinStakeSearchInterval));
    return obj;
}

Value settxfee(const Array& params, bool fHelp)
{
    if (fHelp || params.size() < 1 || params.size() > 1 || AmountFromValue(params[0]) < MIN_TX_FEE)
        throw runtime_error(
            "settxfee <amount>\n"
            "<amount> is a real and is rounded to the nearest 0.01");

    nTransactionFee = AmountFromValue(params[0]);
    nTransactionFee = (nTransactionFee / CENT) * CENT;  // round to cent

    return true;
}

Value getrawmempool(const Array& params, bool fHelp)
{
    if (fHelp || params.size() != 0)
        throw runtime_error(
            "getrawmempool\n"
            "Returns all transaction ids in memory pool.");

    vector<uint256> vtxid;
    mempool.queryHashes(vtxid);

    Array a;
    BOOST_FOREACH(const uint256& hash, vtxid)
        a.push_back(hash.ToString());

    return a;
}

Value getblockhash(const Array& params, bool fHelp)
{
    if (fHelp || params.size() != 1)
        throw runtime_error(
            "getblockhash <index>\n"
            "Returns hash of block in best-block-chain at <index>.");

    int nHeight = params[0].get_int();
    if (nHeight < 0 || nHeight > nBestHeight)
        throw runtime_error("Block number out of range.");

    CBlockIndex* pblockindex = FindBlockByHeight(nHeight);
    return pblockindex->phashBlock->GetHex();
}

Value getblock(const Array& params, bool fHelp)
{
    if (fHelp || params.size() < 1 || params.size() > 2)
        throw runtime_error(
            "getblock <hash> [txinfo]\n"
            "txinfo optional to print more detailed tx info\n"
            "Returns details of a block with given block-hash.");

    std::string strHash = params[0].get_str();
    uint256 hash(strHash);

    if (mapBlockIndex.count(hash) == 0)
        throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");

    CBlock block;
    CBlockIndex* pblockindex = mapBlockIndex[hash];
    block.ReadFromDisk(pblockindex, true);

    return blockToJSON(block, pblockindex, params.size() > 1 ? params[1].get_bool() : false);
}

Value getblockbynumber(const Array& params, bool fHelp)
{
    if (fHelp || params.size() < 1 || params.size() > 2)
        throw runtime_error(
            "getblock <number> [txinfo]\n"
            "txinfo optional to print more detailed tx info\n"
            "Returns details of a block with given block-number.");

    int nHeight = params[0].get_int();
    if (nHeight < 0 || nHeight > nBestHeight)
        throw runtime_error("Block number out of range.");

    CBlock block;
    CBlockIndex* pblockindex = mapBlockIndex[hashBestChain];
    while (pblockindex->nHeight > nHeight)
        pblockindex = pblockindex->pprev;

    uint256 hash = *pblockindex->phashBlock;

    pblockindex = mapBlockIndex[hash];
    block.ReadFromDisk(pblockindex, true);

    return blockToJSON(block, pblockindex, params.size() > 1 ? params[1].get_bool() : false);
}

// ppcoin: get information of sync-checkpoint
Value getcheckpoint(const Array& params, bool fHelp)
{
    if (fHelp || params.size() != 0)
        throw runtime_error(
            "getcheckpoint\n"
            "Show info of synchronized checkpoint.\n");

    Object result;
    CBlockIndex* pindexCheckpoint;

    result.push_back(Pair("synccheckpoint", Checkpoints::hashSyncCheckpoint.ToString().c_str()));
    pindexCheckpoint = mapBlockIndex[Checkpoints::hashSyncCheckpoint];
    result.push_back(Pair("height", pindexCheckpoint->nHeight));
    result.push_back(Pair("timestamp", DateTimeStrFormat(pindexCheckpoint->GetBlockTime()).c_str()));

    // Check that the block satisfies synchronized checkpoint
    if (CheckpointsMode == Checkpoints::STRICT)
        result.push_back(Pair("policy", "strict"));

    if (CheckpointsMode == Checkpoints::ADVISORY)
        result.push_back(Pair("policy", "advisory"));

    if (CheckpointsMode == Checkpoints::PERMISSIVE)
        result.push_back(Pair("policy", "permissive"));

    if (mapArgs.count("-checkpointkey"))
        result.push_back(Pair("checkpointmaster", true));

    return result;
}
<|endoftext|>


<commit_before>// Copyright (c) 2010 Satoshi Nakamoto
// Copyright (c) 2009-2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "main.h"
#include "bitcoinrpc.h"

using namespace json_spirit;
using namespace std;

void ScriptPubKeyToJSON(const CScript& scriptPubKey, Object& out);

double GetDifficulty(const CBlockIndex* blockindex)
{
    // Floating point number that is a multiple of the minimum difficulty,
    // minimum difficulty = 1.0.
    if (blockindex == NULL)
    {
        if (pindexBest == NULL)
            return 1.0;
        else
            blockindex = pindexBest;
    }

    int nShift = (blockindex->nBits >> 24) & 0xff;

    double dDiff =
        (double)0x0000ffff / (double)(blockindex->nBits & 0x00ffffff);

    while (nShift < 29)
    {
        dDiff *= 256.0;
        nShift++;
    }
    while (nShift > 29)
    {
        dDiff /= 256.0;
        nShift--;
    }

    return dDiff;
}

Object blockToJSON(const CBlock& block, const CBlockIndex* blockindex)
{
    Object result;
    result.push_back(Pair("hash", block.GetHash().GetHex()));
    CMerkleTx txGen(block.vtx[0]);
    txGen.SetMerkleBranch(&block);
    result.push_back(Pair("confirmations", (int)txGen.GetDepthInMainChain()));
    result.push_back(Pair("size", (int)::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION)));
    result.push_back(Pair("height", blockindex->nHeight));
    result.push_back(Pair("version", block.nVersion));
    result.push_back(Pair("merkleroot", block.hashMerkleRoot.GetHex()));
    Array txs;
    BOOST_FOREACH(const CTransaction&tx, block.vtx)
        txs.push_back(tx.GetHash().GetHex());
    result.push_back(Pair("tx", txs));
    result.push_back(Pair("time", (boost::int64_t)block.GetBlockTime()));
    result.push_back(Pair("nonce", (boost::uint64_t)block.nNonce));
    result.push_back(Pair("bits", HexBits(block.nBits)));
    result.push_back(Pair("difficulty", GetDifficulty(blockindex)));
    result.push_back(Pair("birthdayA", (int)block.nBirthdayA));
    result.push_back(Pair("birthdayB", (int)block.nBirthdayB));

    if (blockindex->pprev)
        result.push_back(Pair("previousblockhash", blockindex->pprev->GetBlockHash().GetHex()));
    if (blockindex->pnext)
        result.push_back(Pair("nextblockhash", blockindex->pnext->GetBlockHash().GetHex()));
    return result;
}

Value getblockcount(const Array& params, bool fHelp)
{
    if (fHelp || params.size() != 0)
        throw runtime_error(
            "getblockcount\n"
            "Returns the number of blocks in the longest block chain.");

    return nBestHeight;
}

Value getdifficulty(const Array& params, bool fHelp)
{
    if (fHelp || params.size() != 0)
        throw runtime_error(
            "getdifficulty\n"
            "Returns the proof-of-work difficulty as a multiple of the minimum difficulty.");

    return GetDifficulty();
}

Value settxfee(const Array& params, bool fHelp)
{
    if (fHelp || params.size() < 1 || params.size() > 1)
        throw runtime_error(
            "settxfee <amount>\n"
            "<amount> is a real and is rounded to the nearest 0.00000001");

    // Amount
    int64 nAmount = 0;
    if (params[0].get_real() != 0.0)
        nAmount = AmountFromValue(params[0]);        // rejects 0.0 amounts

    nTransactionFee = nAmount;
    return true;
}

Value getrawmempool(const Array& params, bool fHelp)
{
    if (fHelp || params.size() != 0)
        throw runtime_error(
            "getrawmempool\n"
            "Returns all transaction ids in memory pool.");

    vector<uint256> vtxid;
    mempool.queryHashes(vtxid);

    Array a;
    BOOST_FOREACH(const uint256& hash, vtxid)
        a.push_back(hash.ToString());

    return a;
}

Value getblockhash(const Array& params, bool fHelp)
{
    if (fHelp || params.size() != 1)
        throw runtime_error(
            "getblockhash <index>\n"
            "Returns hash of block in best-block-chain at <index>.");

    int nHeight = params[0].get_int();
    if (nHeight < 0 || nHeight > nBestHeight)
        throw runtime_error("Block number out of range.");

    CBlockIndex* pblockindex = FindBlockByHeight(nHeight);
    return pblockindex->phashBlock->GetHex();
}

Value getblock(const Array& params, bool fHelp)
{
    if (fHelp || params.size() != 1)
        throw runtime_error(
            "getblock <hash>\n"
            "Returns details of a block with given block-hash.");

    std::string strHash = params[0].get_str();
    uint256 hash(strHash);

    if (mapBlockIndex.count(hash) == 0)
        throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");

    CBlock block;
    CBlockIndex* pblockindex = mapBlockIndex[hash];
    block.ReadFromDisk(pblockindex);

    return blockToJSON(block, pblockindex);
}

Value gettxoutsetinfo(const Array& params, bool fHelp)
{
    if (fHelp || params.size() != 0)
        throw runtime_error(
            "gettxoutsetinfo\n"
            "Returns statistics about the unspent transaction output set.");

    Object ret;

    CCoinsStats stats;
    if (pcoinsTip->GetStats(stats)) {
        ret.push_back(Pair("height", (boost::int64_t)stats.nHeight));
        ret.push_back(Pair("bestblock", stats.hashBlock.GetHex()));
        ret.push_back(Pair("transactions", (boost::int64_t)stats.nTransactions));
        ret.push_back(Pair("txouts", (boost::int64_t)stats.nTransactionOutputs));
        ret.push_back(Pair("bytes_serialized", (boost::int64_t)stats.nSerializedSize));
        ret.push_back(Pair("hash_serialized", stats.hashSerialized.GetHex()));
        ret.push_back(Pair("total_amount", ValueFromAmount(stats.nTotalAmount)));
    }
    return ret;
}

Value gettxout(const Array& params, bool fHelp)
{
    if (fHelp || params.size() < 2 || params.size() > 3)
        throw runtime_error(
            "gettxout <txid> <n> [includemempool=true]\n"
            "Returns details about an unspent transaction output.");

    Object ret;

    std::string strHash = params[0].get_str();
    uint256 hash(strHash);
    int n = params[1].get_int();
    bool fMempool = true;
    if (params.size() > 2)
        fMempool = params[2].get_bool();

    CCoins coins;
    if (fMempool) {
        LOCK(mempool.cs);
        CCoinsViewMemPool view(*pcoinsTip, mempool);
        if (!view.GetCoins(hash, coins))
            return Value::null;
        mempool.pruneSpent(hash, coins); // TODO: this should be done by the CCoinsViewMemPool
    } else {
        if (!pcoinsTip->GetCoins(hash, coins))
            return Value::null;
    }
    if (n<0 || (unsigned int)n>=coins.vout.size() || coins.vout[n].IsNull())
        return Value::null;

    ret.push_back(Pair("bestblock", pcoinsTip->GetBestBlock()->GetBlockHash().GetHex()));
    if ((unsigned int)coins.nHeight == MEMPOOL_HEIGHT)
        ret.push_back(Pair("confirmations", 0));
    else
        ret.push_back(Pair("confirmations", pcoinsTip->GetBestBlock()->nHeight - coins.nHeight + 1));
    ret.push_back(Pair("value", ValueFromAmount(coins.vout[n].nValue)));
    Object o;
    ScriptPubKeyToJSON(coins.vout[n].scriptPubKey, o);
    ret.push_back(Pair("scriptPubKey", o));
    ret.push_back(Pair("version", coins.nVersion));
    ret.push_back(Pair("coinbase", coins.fCoinBase));

    return ret;
}

<commit_msg>unsigned fix.<commit_after>// Copyright (c) 2010 Satoshi Nakamoto
// Copyright (c) 2009-2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "main.h"
#include "bitcoinrpc.h"

using namespace json_spirit;
using namespace std;

void ScriptPubKeyToJSON(const CScript& scriptPubKey, Object& out);

double GetDifficulty(const CBlockIndex* blockindex)
{
    // Floating point number that is a multiple of the minimum difficulty,
    // minimum difficulty = 1.0.
    if (blockindex == NULL)
    {
        if (pindexBest == NULL)
            return 1.0;
        else
            blockindex = pindexBest;
    }

    int nShift = (blockindex->nBits >> 24) & 0xff;

    double dDiff =
        (double)0x0000ffff / (double)(blockindex->nBits & 0x00ffffff);

    while (nShift < 29)
    {
        dDiff *= 256.0;
        nShift++;
    }
    while (nShift > 29)
    {
        dDiff /= 256.0;
        nShift--;
    }

    return dDiff;
}

Object blockToJSON(const CBlock& block, const CBlockIndex* blockindex)
{
    Object result;
    result.push_back(Pair("hash", block.GetHash().GetHex()));
    CMerkleTx txGen(block.vtx[0]);
    txGen.SetMerkleBranch(&block);
    result.push_back(Pair("confirmations", (int)txGen.GetDepthInMainChain()));
    result.push_back(Pair("size", (int)::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION)));
    result.push_back(Pair("height", blockindex->nHeight));
    result.push_back(Pair("version", block.nVersion));
    result.push_back(Pair("merkleroot", block.hashMerkleRoot.GetHex()));
    Array txs;
    BOOST_FOREACH(const CTransaction&tx, block.vtx)
        txs.push_back(tx.GetHash().GetHex());
    result.push_back(Pair("tx", txs));
    result.push_back(Pair("time", (boost::int64_t)block.GetBlockTime()));
    result.push_back(Pair("nonce", (boost::uint64_t)block.nNonce));
    result.push_back(Pair("bits", HexBits(block.nBits)));
    result.push_back(Pair("difficulty", GetDifficulty(blockindex)));
    result.push_back(Pair("birthdayA", (boost::uint64_t)block.nBirthdayA));
    result.push_back(Pair("birthdayB", (boost::uint64_t)block.nBirthdayB));

    if (blockindex->pprev)
        result.push_back(Pair("previousblockhash", blockindex->pprev->GetBlockHash().GetHex()));
    if (blockindex->pnext)
        result.push_back(Pair("nextblockhash", blockindex->pnext->GetBlockHash().GetHex()));
    return result;
}

Value getblockcount(const Array& params, bool fHelp)
{
    if (fHelp || params.size() != 0)
        throw runtime_error(
            "getblockcount\n"
            "Returns the number of blocks in the longest block chain.");

    return nBestHeight;
}

Value getdifficulty(const Array& params, bool fHelp)
{
    if (fHelp || params.size() != 0)
        throw runtime_error(
            "getdifficulty\n"
            "Returns the proof-of-work difficulty as a multiple of the minimum difficulty.");

    return GetDifficulty();
}

Value settxfee(const Array& params, bool fHelp)
{
    if (fHelp || params.size() < 1 || params.size() > 1)
        throw runtime_error(
            "settxfee <amount>\n"
            "<amount> is a real and is rounded to the nearest 0.00000001");

    // Amount
    int64 nAmount = 0;
    if (params[0].get_real() != 0.0)
        nAmount = AmountFromValue(params[0]);        // rejects 0.0 amounts

    nTransactionFee = nAmount;
    return true;
}

Value getrawmempool(const Array& params, bool fHelp)
{
    if (fHelp || params.size() != 0)
        throw runtime_error(
            "getrawmempool\n"
            "Returns all transaction ids in memory pool.");

    vector<uint256> vtxid;
    mempool.queryHashes(vtxid);

    Array a;
    BOOST_FOREACH(const uint256& hash, vtxid)
        a.push_back(hash.ToString());

    return a;
}

Value getblockhash(const Array& params, bool fHelp)
{
    if (fHelp || params.size() != 1)
        throw runtime_error(
            "getblockhash <index>\n"
            "Returns hash of block in best-block-chain at <index>.");

    int nHeight = params[0].get_int();
    if (nHeight < 0 || nHeight > nBestHeight)
        throw runtime_error("Block number out of range.");

    CBlockIndex* pblockindex = FindBlockByHeight(nHeight);
    return pblockindex->phashBlock->GetHex();
}

Value getblock(const Array& params, bool fHelp)
{
    if (fHelp || params.size() != 1)
        throw runtime_error(
            "getblock <hash>\n"
            "Returns details of a block with given block-hash.");

    std::string strHash = params[0].get_str();
    uint256 hash(strHash);

    if (mapBlockIndex.count(hash) == 0)
        throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");

    CBlock block;
    CBlockIndex* pblockindex = mapBlockIndex[hash];
    block.ReadFromDisk(pblockindex);

    return blockToJSON(block, pblockindex);
}

Value gettxoutsetinfo(const Array& params, bool fHelp)
{
    if (fHelp || params.size() != 0)
        throw runtime_error(
            "gettxoutsetinfo\n"
            "Returns statistics about the unspent transaction output set.");

    Object ret;

    CCoinsStats stats;
    if (pcoinsTip->GetStats(stats)) {
        ret.push_back(Pair("height", (boost::int64_t)stats.nHeight));
        ret.push_back(Pair("bestblock", stats.hashBlock.GetHex()));
        ret.push_back(Pair("transactions", (boost::int64_t)stats.nTransactions));
        ret.push_back(Pair("txouts", (boost::int64_t)stats.nTransactionOutputs));
        ret.push_back(Pair("bytes_serialized", (boost::int64_t)stats.nSerializedSize));
        ret.push_back(Pair("hash_serialized", stats.hashSerialized.GetHex()));
        ret.push_back(Pair("total_amount", ValueFromAmount(stats.nTotalAmount)));
    }
    return ret;
}

Value gettxout(const Array& params, bool fHelp)
{
    if (fHelp || params.size() < 2 || params.size() > 3)
        throw runtime_error(
            "gettxout <txid> <n> [includemempool=true]\n"
            "Returns details about an unspent transaction output.");

    Object ret;

    std::string strHash = params[0].get_str();
    uint256 hash(strHash);
    int n = params[1].get_int();
    bool fMempool = true;
    if (params.size() > 2)
        fMempool = params[2].get_bool();

    CCoins coins;
    if (fMempool) {
        LOCK(mempool.cs);
        CCoinsViewMemPool view(*pcoinsTip, mempool);
        if (!view.GetCoins(hash, coins))
            return Value::null;
        mempool.pruneSpent(hash, coins); // TODO: this should be done by the CCoinsViewMemPool
    } else {
        if (!pcoinsTip->GetCoins(hash, coins))
            return Value::null;
    }
    if (n<0 || (unsigned int)n>=coins.vout.size() || coins.vout[n].IsNull())
        return Value::null;

    ret.push_back(Pair("bestblock", pcoinsTip->GetBestBlock()->GetBlockHash().GetHex()));
    if ((unsigned int)coins.nHeight == MEMPOOL_HEIGHT)
        ret.push_back(Pair("confirmations", 0));
    else
        ret.push_back(Pair("confirmations", pcoinsTip->GetBestBlock()->nHeight - coins.nHeight + 1));
    ret.push_back(Pair("value", ValueFromAmount(coins.vout[n].nValue)));
    Object o;
    ScriptPubKeyToJSON(coins.vout[n].scriptPubKey, o);
    ret.push_back(Pair("scriptPubKey", o));
    ret.push_back(Pair("version", coins.nVersion));
    ret.push_back(Pair("coinbase", coins.fCoinBase));

    return ret;
}

<|endoftext|>


<commit_before>#include "Array.h"
#include "Runtime.h"
#include "SnowString.h"
#include "Function.h"
#include <sstream>

#define DEFAULT_ARRAY_LENGTH 8

namespace snow {
	GC_ROOTS_IMPL(Array) {
		GC_SUPER(Object);

		// If m_AllocatedLength == 0, this is a wrapper around an external array.
		if (m_AllocatedLength)
			GC_ROOT(m_Data);

		for (size_t i = 0; i < m_Length; ++i) {
			GC_ROOT(m_Data[i]);
		}
	}

	void Array::resize(size_t new_size) {
		if (m_AllocatedLength >= new_size)
			return;

		// TODO: Grow more than strictly necessary to minimize allocations

		// This function contains an allocation, which might trigger a garbage collection,
		// so we need to guard the "this" pointer against this. This would be nice to improve.

		HandleScope _;
		Handle<Array> self = this;

		VALUE* old_pointer = self->m_Data;
		self->m_Data = gc_new_array<VALUE>(new_size);
		self->m_AllocatedLength = new_size;
		if (self->m_Length != 0 && old_pointer) {
			memcpy(self->m_Data, old_pointer, self->m_Length*sizeof(VALUE));
		}
	}

	void Array::preallocate(size_t len) {
		if (m_Length < len) {
			resize(len);
		}
	}

	Array::Array() : Object(array_prototype()), m_Data(NULL), m_Length(0), m_AllocatedLength(0) {}

	VALUE& Array::operator[](int64_t idx) {
		HandleScope _;
		Handle<Array> self = this;

		if (idx < 0)
			idx %= self->m_Length;
		if (idx >= (int64_t)self->m_Length)
		{
			self->preallocate(idx+1);
			auto old_length = self->m_Length;
			self->m_Length = idx+1;
			for (size_t i = old_length; i < self->m_Length; ++i) {
				self->m_Data[i] = nil();
			}
		}
		return self->m_Data[idx];
	}

	VALUE Array::operator[](int64_t idx) const {
		if (idx < 0)
			idx = m_Length + idx;
		if (idx < 0 || idx >= (int64_t)m_Length)
			return nil();
		return m_Data[idx];
	}

	VALUE Array::push(VALUE val) {
		HandleScope _;
		Handle<Array> self = this;

		self->preallocate(m_Length + 1);
		self->m_Data[self->m_Length] = val;
		++self->m_Length;
		return self;
	}

	VALUE Array::pop() {
		ASSERT(!is_frozen());
		if (m_Length == 0)
			return nil();
		VALUE val = m_Data[m_Length-1];
		--m_Length;
		return val;
	}

	VALUE Array::unshift(VALUE val) {
		HandleScope _;
		Handle<Array> self = this;

		self->preallocate(m_Length+1);
		// XXX: For some reason, memmove doesn't work here. Investigate!
		// Also, this might be acceptable, since it's faster than memmove.
		for (size_t i = 0; i < self->m_Length; ++i) {
			self->m_Data[self->m_Length-i] = self->m_Data[self->m_Length-1-i];
		}
		++self->m_Length;
		self->m_Data[0] = val;
		return self;
	}

	VALUE Array::shift() {
		ASSERT(!is_frozen());
		if (m_Length == 0)
			return nil();
		VALUE val = m_Data[0];
		--m_Length;
		for (size_t i = 0; i < m_Length; ++i) {
			m_Data[i] = m_Data[i+1];
		}
		return val;
	}

	VALUE Array::va_call(VALUE self, uint64_t num_args, va_list& args) {
		if (num_args == 0)
			return this;
		if (num_args == 1) {
			int64_t index = integer(va_arg(args, VALUE));
			return (*this)[index];
		}
		// TODO: ranges and such.
		TRAP();
		return this;
	}

	void Array::set_data(VALUE* data, size_t len) {
		preallocate(len);
		memcpy(m_Data, data, len*sizeof(VALUE));
		m_Length = len;
	}

	void Array::set_reference(VALUE* data, size_t len) {
		m_AllocatedLength = 0;
		m_Data = len ? data : NULL;
		m_Length = len;
	}

	Array* Array::copy(VALUE* array, size_t len) {
		HandleScope _;
		Handle<Array> self = gc_new<Array>();
		self->set_data(array, len);
		return self;
	}

	Array* Array::copy(const Array& array) {
		return copy(array.m_Data, array.m_Length);
	}

	Array* Array::reference(VALUE* array, size_t len) {
		HandleScope _;
		Handle<Array> self = gc_new<Array>();
		self->set_reference(array, len);
		return self;
	}

	Array* Array::reference(const Array& array) {
		return reference(array.m_Data, array.m_Length);
	}

	static VALUE array_new(VALUE self, uint64_t num_args, VALUE* args) {
		NORMAL_SCOPE();
		if (num_args)
			return Array::copy(args, num_args);
		return gc_new<Array>();
	}

	static VALUE array_get(VALUE self, uint64_t num_args, VALUE* args) {
		NORMAL_SCOPE();
		ASSERT_OBJECT(self, Array);
		ASSERT_ARGS(num_args == 1);
		auto array = object_cast<Array>(self);
		int64_t idx = integer(args[0]);
		return (*array)[idx];
	}

	static VALUE array_set(VALUE self, uint64_t num_args, VALUE* args) {
		NORMAL_SCOPE();
		ASSERT_OBJECT(self, Array);
		ASSERT_ARGS(num_args == 2);
		auto array = object_cast<Array>(self);
		int idx = integer(args[0]);
		VALUE new_value = args[1];
		return array->set_by_index(idx, new_value);
	}

	static VALUE array_each(VALUE self, uint64_t num_args, VALUE* args) {
		NORMAL_SCOPE();
		ASSERT_OBJECT(self, Array);
		ASSERT_ARGS(num_args >= 1);
		Handle<Array> array = object_cast<Array>(self);

		ValueHandle closure = args[0];
		for (size_t i = 0; i < array->length(); ++i) {
			snow::call(NULL, closure, 2, (*array)[i], value((int64_t)i));
		}
		return self;
	}

	static VALUE array_each_parallel(VALUE self, uint64_t num_args, VALUE* args) {
		NORMAL_SCOPE();
		ASSERT_OBJECT(self, Array);
		ASSERT_ARGS(num_args >= 1);
		Handle<Array> array = object_cast<Array>(self);

		ValueHandle closure = args[0];
		#pragma omp parallel for
		for (size_t i = 0; i < array->length(); ++i) {
			snow::call(NULL, closure, 2, (*array)[i], value((int64_t)i));
		}
		return self;
	}

	static VALUE array_map(VALUE self, uint64_t num_args, VALUE* args) {
		NORMAL_SCOPE();
		ASSERT_OBJECT(self, Array);
		ASSERT_ARGS(num_args >= 1);
		Handle<Array> array = object_cast<Array>(self);

		ValueHandle closure = args[0];
		Handle<Array> result = gc_new<Array>();
		result->preallocate(result->length());
		for (size_t i = 0; i < array->length(); ++i) {
			(*result)[i] = snow::call(NULL, closure, 2, (*array)[i], value((int64_t)i));
		}
		return result;
	}

	static VALUE array_map_parallel(VALUE self, uint64_t num_args, VALUE* args) {
		NORMAL_SCOPE();
		ASSERT_OBJECT(self, Array);
		ASSERT_ARGS(num_args >= 1);
		Handle<Array> array = object_cast<Array>(self);

		ValueHandle closure = args[0];
		Handle<Array> result = gc_new<Array>();
		result->preallocate(result->length());
		size_t len = array->length();
		#pragma omp parallel for
		for (size_t i = 0; i < len; ++i) {
			VALUE transformed = snow::call(NULL, closure, 2, (*array)[i], value((int64_t)i));
			(*result)[i] = transformed;
		}
		return result;
	}

	static VALUE array_length(VALUE self, uint64_t num_args, VALUE* args) {
		NORMAL_SCOPE();
		ASSERT_OBJECT(self, Array);
		auto array = object_cast<Array>(self);
		return value((int64_t)array->length());
	}

	static VALUE array_inspect(VALUE self, uint64_t num_args, VALUE* args) {
		NORMAL_SCOPE();
		ASSERT_OBJECT(self, Array);
		auto array = object_cast<Array>(self);
		std::stringstream ss;

		ss << "@(";
		for (size_t i = 0; i < array->length(); ++i) {
			ss << value_to_string(snow::call_method((*array)[i], "inspect", 0));
			if (i != array->length() - 1)
				ss << ", ";
		}
		ss << ")";

		return gc_new<String>(ss.str());
	}

	static VALUE array_push(VALUE self, uint64_t num_args, VALUE* args) {
		NORMAL_SCOPE();
		ASSERT_OBJECT(self, Array);
		ASSERT_ARGS(num_args == 1);
		auto array = object_cast<Array>(self);
		VALUE val = args[0];
		array->push(val);
		return self;
	}

	static VALUE array_pop(VALUE self, uint64_t num_args, VALUE* args) {
		NORMAL_SCOPE();
		ASSERT_OBJECT(self, Array);
		ASSERT_ARGS(num_args == 0);
		auto array = object_cast<Array>(self);
		return array->pop();
	}

	static VALUE array_unshift(VALUE self, uint64_t num_args, VALUE* args) {
		NORMAL_SCOPE();
		ASSERT_OBJECT(self, Array);
		ASSERT_ARGS(num_args == 1);
		auto array = object_cast<Array>(self);
		VALUE val = args[0];
		return array->unshift(val);
	}

	static VALUE array_shift(VALUE self, uint64_t num_args, VALUE* args) {
		NORMAL_SCOPE();
		ASSERT_OBJECT(self, Array);
		ASSERT_ARGS(num_args == 0);
		auto array = object_cast<Array>(self);
		return array->shift();
	}

	Object* array_prototype() {
		static Object* proto = NULL;
		if (proto) return proto;
		proto = malloc_new<Object>();
		return proto;
	}

	void array_prototype_init() {
		Object* proto = array_prototype();
		proto->set_raw_s("new", gc_new<Function>(array_new));
		proto->set_raw_s("get", gc_new<Function>(array_get));
		proto->set_raw_s("set", gc_new<Function>(array_set));
		proto->set_raw_s("each", gc_new<Function>(array_each));
		proto->set_raw_s("each_parallel", gc_new<Function>(array_each_parallel));
		proto->set_raw_s("map", gc_new<Function>(array_map));
		proto->set_raw_s("map_parallel", gc_new<Function>(array_map_parallel));
		proto->set_raw_s("push", gc_new<Function>(array_push));
		proto->set_raw_s("pop", gc_new<Function>(array_pop));
		proto->set_raw_s("unshift", gc_new<Function>(array_unshift));
		proto->set_raw_s("shift", gc_new<Function>(array_shift));
		proto->set_property_getter(symbol("length"), gc_new<Function>(array_length));
		proto->set_raw_s("inspect", gc_new<Function>(array_inspect));
		proto->set_raw_s("<<", gc_new<Function>(array_push));
	}
}
<commit_msg>Array.to_string<commit_after>#include "Array.h"
#include "Runtime.h"
#include "SnowString.h"
#include "Function.h"
#include <sstream>

#define DEFAULT_ARRAY_LENGTH 8

namespace snow {
	GC_ROOTS_IMPL(Array) {
		GC_SUPER(Object);

		// If m_AllocatedLength == 0, this is a wrapper around an external array.
		if (m_AllocatedLength)
			GC_ROOT(m_Data);

		for (size_t i = 0; i < m_Length; ++i) {
			GC_ROOT(m_Data[i]);
		}
	}

	void Array::resize(size_t new_size) {
		if (m_AllocatedLength >= new_size)
			return;

		// TODO: Grow more than strictly necessary to minimize allocations

		// This function contains an allocation, which might trigger a garbage collection,
		// so we need to guard the "this" pointer against this. This would be nice to improve.

		HandleScope _;
		Handle<Array> self = this;

		VALUE* old_pointer = self->m_Data;
		self->m_Data = gc_new_array<VALUE>(new_size);
		self->m_AllocatedLength = new_size;
		if (self->m_Length != 0 && old_pointer) {
			memcpy(self->m_Data, old_pointer, self->m_Length*sizeof(VALUE));
		}
	}

	void Array::preallocate(size_t len) {
		if (m_Length < len) {
			resize(len);
		}
	}

	Array::Array() : Object(array_prototype()), m_Data(NULL), m_Length(0), m_AllocatedLength(0) {}

	VALUE& Array::operator[](int64_t idx) {
		HandleScope _;
		Handle<Array> self = this;

		if (idx < 0)
			idx %= self->m_Length;
		if (idx >= (int64_t)self->m_Length)
		{
			self->preallocate(idx+1);
			auto old_length = self->m_Length;
			self->m_Length = idx+1;
			for (size_t i = old_length; i < self->m_Length; ++i) {
				self->m_Data[i] = nil();
			}
		}
		return self->m_Data[idx];
	}

	VALUE Array::operator[](int64_t idx) const {
		if (idx < 0)
			idx = m_Length + idx;
		if (idx < 0 || idx >= (int64_t)m_Length)
			return nil();
		return m_Data[idx];
	}

	VALUE Array::push(VALUE val) {
		HandleScope _;
		Handle<Array> self = this;

		self->preallocate(m_Length + 1);
		self->m_Data[self->m_Length] = val;
		++self->m_Length;
		return self;
	}

	VALUE Array::pop() {
		ASSERT(!is_frozen());
		if (m_Length == 0)
			return nil();
		VALUE val = m_Data[m_Length-1];
		--m_Length;
		return val;
	}

	VALUE Array::unshift(VALUE val) {
		HandleScope _;
		Handle<Array> self = this;

		self->preallocate(m_Length+1);
		// XXX: For some reason, memmove doesn't work here. Investigate!
		// Also, this might be acceptable, since it's faster than memmove.
		for (size_t i = 0; i < self->m_Length; ++i) {
			self->m_Data[self->m_Length-i] = self->m_Data[self->m_Length-1-i];
		}
		++self->m_Length;
		self->m_Data[0] = val;
		return self;
	}

	VALUE Array::shift() {
		ASSERT(!is_frozen());
		if (m_Length == 0)
			return nil();
		VALUE val = m_Data[0];
		--m_Length;
		for (size_t i = 0; i < m_Length; ++i) {
			m_Data[i] = m_Data[i+1];
		}
		return val;
	}

	VALUE Array::va_call(VALUE self, uint64_t num_args, va_list& args) {
		if (num_args == 0)
			return this;
		if (num_args == 1) {
			int64_t index = integer(va_arg(args, VALUE));
			return (*this)[index];
		}
		// TODO: ranges and such.
		TRAP();
		return this;
	}

	void Array::set_data(VALUE* data, size_t len) {
		preallocate(len);
		memcpy(m_Data, data, len*sizeof(VALUE));
		m_Length = len;
	}

	void Array::set_reference(VALUE* data, size_t len) {
		m_AllocatedLength = 0;
		m_Data = len ? data : NULL;
		m_Length = len;
	}

	Array* Array::copy(VALUE* array, size_t len) {
		HandleScope _;
		Handle<Array> self = gc_new<Array>();
		self->set_data(array, len);
		return self;
	}

	Array* Array::copy(const Array& array) {
		return copy(array.m_Data, array.m_Length);
	}

	Array* Array::reference(VALUE* array, size_t len) {
		HandleScope _;
		Handle<Array> self = gc_new<Array>();
		self->set_reference(array, len);
		return self;
	}

	Array* Array::reference(const Array& array) {
		return reference(array.m_Data, array.m_Length);
	}

	static VALUE array_new(VALUE self, uint64_t num_args, VALUE* args) {
		NORMAL_SCOPE();
		if (num_args)
			return Array::copy(args, num_args);
		return gc_new<Array>();
	}

	static VALUE array_get(VALUE self, uint64_t num_args, VALUE* args) {
		NORMAL_SCOPE();
		ASSERT_OBJECT(self, Array);
		ASSERT_ARGS(num_args == 1);
		auto array = object_cast<Array>(self);
		int64_t idx = integer(args[0]);
		return (*array)[idx];
	}

	static VALUE array_set(VALUE self, uint64_t num_args, VALUE* args) {
		NORMAL_SCOPE();
		ASSERT_OBJECT(self, Array);
		ASSERT_ARGS(num_args == 2);
		auto array = object_cast<Array>(self);
		int idx = integer(args[0]);
		VALUE new_value = args[1];
		return array->set_by_index(idx, new_value);
	}

	static VALUE array_each(VALUE self, uint64_t num_args, VALUE* args) {
		NORMAL_SCOPE();
		ASSERT_OBJECT(self, Array);
		ASSERT_ARGS(num_args >= 1);
		Handle<Array> array = object_cast<Array>(self);

		ValueHandle closure = args[0];
		for (size_t i = 0; i < array->length(); ++i) {
			snow::call(NULL, closure, 2, (*array)[i], value((int64_t)i));
		}
		return self;
	}

	static VALUE array_each_parallel(VALUE self, uint64_t num_args, VALUE* args) {
		NORMAL_SCOPE();
		ASSERT_OBJECT(self, Array);
		ASSERT_ARGS(num_args >= 1);
		Handle<Array> array = object_cast<Array>(self);

		ValueHandle closure = args[0];
		#pragma omp parallel for
		for (size_t i = 0; i < array->length(); ++i) {
			snow::call(NULL, closure, 2, (*array)[i], value((int64_t)i));
		}
		return self;
	}

	static VALUE array_map(VALUE self, uint64_t num_args, VALUE* args) {
		NORMAL_SCOPE();
		ASSERT_OBJECT(self, Array);
		ASSERT_ARGS(num_args >= 1);
		Handle<Array> array = object_cast<Array>(self);

		ValueHandle closure = args[0];
		Handle<Array> result = gc_new<Array>();
		result->preallocate(result->length());
		for (size_t i = 0; i < array->length(); ++i) {
			(*result)[i] = snow::call(NULL, closure, 2, (*array)[i], value((int64_t)i));
		}
		return result;
	}

	static VALUE array_map_parallel(VALUE self, uint64_t num_args, VALUE* args) {
		NORMAL_SCOPE();
		ASSERT_OBJECT(self, Array);
		ASSERT_ARGS(num_args >= 1);
		Handle<Array> array = object_cast<Array>(self);

		ValueHandle closure = args[0];
		Handle<Array> result = gc_new<Array>();
		result->preallocate(result->length());
		size_t len = array->length();
		#pragma omp parallel for
		for (size_t i = 0; i < len; ++i) {
			VALUE transformed = snow::call(NULL, closure, 2, (*array)[i], value((int64_t)i));
			(*result)[i] = transformed;
		}
		return result;
	}

	static VALUE array_length(VALUE self, uint64_t num_args, VALUE* args) {
		NORMAL_SCOPE();
		ASSERT_OBJECT(self, Array);
		auto array = object_cast<Array>(self);
		return value((int64_t)array->length());
	}

	static VALUE array_inspect(VALUE self, uint64_t num_args, VALUE* args) {
		NORMAL_SCOPE();
		ASSERT_OBJECT(self, Array);
		auto array = object_cast<Array>(self);
		std::stringstream ss;

		ss << "@(";
		for (size_t i = 0; i < array->length(); ++i) {
			ss << value_to_string(snow::call_method((*array)[i], "inspect", 0));
			if (i != array->length() - 1)
				ss << ", ";
		}
		ss << ")";

		return gc_new<String>(ss.str());
	}

	static VALUE array_push(VALUE self, uint64_t num_args, VALUE* args) {
		NORMAL_SCOPE();
		ASSERT_OBJECT(self, Array);
		ASSERT_ARGS(num_args == 1);
		auto array = object_cast<Array>(self);
		VALUE val = args[0];
		array->push(val);
		return self;
	}

	static VALUE array_pop(VALUE self, uint64_t num_args, VALUE* args) {
		NORMAL_SCOPE();
		ASSERT_OBJECT(self, Array);
		ASSERT_ARGS(num_args == 0);
		auto array = object_cast<Array>(self);
		return array->pop();
	}

	static VALUE array_unshift(VALUE self, uint64_t num_args, VALUE* args) {
		NORMAL_SCOPE();
		ASSERT_OBJECT(self, Array);
		ASSERT_ARGS(num_args == 1);
		auto array = object_cast<Array>(self);
		VALUE val = args[0];
		return array->unshift(val);
	}

	static VALUE array_shift(VALUE self, uint64_t num_args, VALUE* args) {
		NORMAL_SCOPE();
		ASSERT_OBJECT(self, Array);
		ASSERT_ARGS(num_args == 0);
		auto array = object_cast<Array>(self);
		return array->shift();
	}

	Object* array_prototype() {
		static Object* proto = NULL;
		if (proto) return proto;
		proto = malloc_new<Object>();
		return proto;
	}

	void array_prototype_init() {
		Object* proto = array_prototype();
		proto->set_raw_s("new", gc_new<Function>(array_new));
		proto->set_raw_s("get", gc_new<Function>(array_get));
		proto->set_raw_s("set", gc_new<Function>(array_set));
		proto->set_raw_s("each", gc_new<Function>(array_each));
		proto->set_raw_s("each_parallel", gc_new<Function>(array_each_parallel));
		proto->set_raw_s("map", gc_new<Function>(array_map));
		proto->set_raw_s("map_parallel", gc_new<Function>(array_map_parallel));
		proto->set_raw_s("push", gc_new<Function>(array_push));
		proto->set_raw_s("pop", gc_new<Function>(array_pop));
		proto->set_raw_s("unshift", gc_new<Function>(array_unshift));
		proto->set_raw_s("shift", gc_new<Function>(array_shift));
		proto->set_property_getter(symbol("length"), gc_new<Function>(array_length));
		proto->set_raw_s("inspect", gc_new<Function>(array_inspect));
		proto->set_raw_s("to_string", proto->get_raw_s("inspect"));
		proto->set_raw_s("<<", gc_new<Function>(array_push));
	}
}
<|endoftext|>


<commit_before>#include <iostream>
using namespace std;

int main(int argc, char const *argv[])
{
	int n;

	int s=0,a;
	while(cin >>n;){
		s=(n+1)*n/2;
		cout<<s;
	}
	return 0;
}
<commit_msg>update hdu1001<commit_after>#include <iostream>
using namespace std;

int main(int argc, char const *argv[])
{
	int n;

	int s=0,a;
	while(cin >>n){
		s=(n+1)*n/2;
		cout<<s;
	}
	return 0;
}
<|endoftext|>


<commit_before>#include "showtimemodel.h"
#include "show.h"
#include <QDateTime>

ShowTimeModel::ShowTimeModel(QObject *parent)
     : QAbstractListModel(parent)
{

}

QHash<int, QByteArray> ShowTimeModel::roleNames() const
{
    QHash<int, QByteArray> roles;
    roles[IdRole] = "id";
    roles[ShowStartRole] = "start";
    roles[ShowStartDateTimeRole] = "startdatetime";
    roles[ShowEndRole] = "end";
    roles[TheatreRole] = "theatre";
    roles[TheatreAuditoriumRole] = "auditorium";
    roles[ShowUrlRole] = "showurl";
    roles[EventUrlRole] = "eventurl";
    return roles;
}

void ShowTimeModel::addShow(Show* show)
{
    beginInsertRows(QModelIndex(), rowCount(), rowCount());
    shows_.append(show);
    endInsertRows();
}

int ShowTimeModel::rowCount(const QModelIndex & parent) const {

    // only shows which are in the future taken into account
    int count = 0;
    foreach(Show* show, shows_) {
        if(show->getStartTime() > QDateTime::currentDateTime()) {
            ++count;
        }
    }

    return count;
}

void ShowTimeModel::clear()
{
    beginResetModel();
    foreach(Show* show, shows_) {
        delete show;
        show = NULL;
    }
    shows_.clear();
    endResetModel();
}

QVariant ShowTimeModel::data(const QModelIndex & index, int role) const {

    if (index.row() < 0 || index.row() > shows_.count())
     return QVariant();

    Show *show = shows_[index.row()];

    if (role == IdRole)
        return show->getId();
    else if(role == ShowStartRole)
        return show->getStart();
    else if(role == ShowStartDateTimeRole)
        return show->getStartTime();
    else if(role == ShowEndRole)
        return show->getEnd();
    else if(role == TheatreRole)
        return show->getTheatre();
    else if(role == TheatreAuditoriumRole)
        return show->getAuditorium();
    else if(role == ShowUrlRole)
        return show->getShowUrl();
    else if(role == EventUrlRole)
        return show->getEventUrl();
    return QVariant();

}
<commit_msg>removed invalid filtering code<commit_after>#include "showtimemodel.h"
#include "show.h"
#include <QDateTime>

ShowTimeModel::ShowTimeModel(QObject *parent)
     : QAbstractListModel(parent)
{

}

QHash<int, QByteArray> ShowTimeModel::roleNames() const
{
    QHash<int, QByteArray> roles;
    roles[IdRole] = "id";
    roles[ShowStartRole] = "start";
    roles[ShowStartDateTimeRole] = "startdatetime";
    roles[ShowEndRole] = "end";
    roles[TheatreRole] = "theatre";
    roles[TheatreAuditoriumRole] = "auditorium";
    roles[ShowUrlRole] = "showurl";
    roles[EventUrlRole] = "eventurl";
    return roles;
}

void ShowTimeModel::addShow(Show* show)
{
    beginInsertRows(QModelIndex(), rowCount(), rowCount());
    shows_.append(show);
    endInsertRows();
}

int ShowTimeModel::rowCount(const QModelIndex & parent) const {

    return shows_.count();

}

void ShowTimeModel::clear()
{
    beginResetModel();
    foreach(Show* show, shows_) {
        delete show;
        show = NULL;
    }
    shows_.clear();
    endResetModel();
}

QVariant ShowTimeModel::data(const QModelIndex & index, int role) const {

    if (index.row() < 0 || index.row() > shows_.count())
     return QVariant();

    Show *show = shows_[index.row()];

    if (role == IdRole)
        return show->getId();
    else if(role == ShowStartRole)
        return show->getStart();
    else if(role == ShowStartDateTimeRole)
        return show->getStartTime();
    else if(role == ShowEndRole)
        return show->getEnd();
    else if(role == TheatreRole)
        return show->getTheatre();
    else if(role == TheatreAuditoriumRole)
        return show->getAuditorium();
    else if(role == ShowUrlRole)
        return show->getShowUrl();
    else if(role == EventUrlRole)
        return show->getEventUrl();
    return QVariant();

}
<|endoftext|>


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

#include "apic.hpp"
#include "ioapic.hpp"
#include "acpi.hpp"
#include "cpu.hpp"
#include "pic.hpp"
#include "smp.hpp"
#include <kernel/cpuid.hpp>
#include <kernel/irq_manager.hpp>
#include <cstdlib>
#include <debug>
#include <kprint>
#include <info>

extern "C" {
  // current selected EOI method
  void (*current_eoi_mechanism)();
  // KVM para PV-EOI feature
  void kvm_pv_eoi();
  // easier deduction of type
  void x2apic_send_eoi() {
    x86::x2apic::get().eoi();
  }
}

void kvm_pv_eoi_init();

namespace x86
{
  static IApic* current_apic = nullptr;
  IApic& APIC::get() noexcept {
    return *current_apic;
  }

  void APIC::init()
  {
    // disable the legacy 8259 PIC
    // by masking off all interrupts
    PIC::set_intr_mask(0xFFFF);

    // a PC without APIC is insane
    assert(CPUID::has_feature(CPUID::Feature::APIC)
        && "If this fails, the machine is insane");

    if (CPUID::has_feature(CPUID::Feature::X2APIC)) {
        current_apic = &x2apic::get();
        current_eoi_mechanism = x2apic_send_eoi;
    } else {
        current_apic = &xapic::get();
        current_eoi_mechanism = lapic_send_eoi;
    }

    // enable xAPIC/x2APIC on this cpu
    current_apic->enable();

    // initialize I/O APICs
    IOAPIC::init(ACPI::get_ioapics());

    // use KVMs paravirt EOI if supported
    //if (CPUID::kvm_feature(KVM_FEATURE_PV_EOI))
    //    kvm_pv_eoi_init();
  }

  void APIC::enable_irq(uint8_t irq)
  {
    auto& overrides = x86::ACPI::get_overrides();
    for (auto& redir : overrides)
    {
      // NOTE: @bus_source is the IOAPIC number
      if (redir.irq_source == irq)
      {
        INFO2("Enabled redirected IRQ %u -> %u on lapic %u",
            redir.irq_source, redir.global_intr, get().get_id());
        IOAPIC::enable(redir.global_intr, irq, get().get_id());
        return;
      }
    }
    INFO2("Enabled non-redirected IRQ %u on LAPIC %u", irq, get().get_id());
    IOAPIC::enable(irq, irq, get().get_id());
  }
  void APIC::disable_irq(uint8_t irq)
  {
    auto& overrides = x86::ACPI::get_overrides();
    for (auto& redir : overrides)
    {
      // NOTE: @bus_source is the IOAPIC number
      if (redir.irq_source == irq)
      {
        IOAPIC::disable(redir.global_intr);
        return;
      }
    }
    IOAPIC::disable(irq);
  }
}

// *** manual ***
// http://choon.net/forum/read.php?21,1123399
// https://www.kernel.org/doc/Documentation/virtual/kvm/cpuid.txt

#define KVM_MSR_ENABLED        1
#define MSR_KVM_PV_EOI_EN      0x4b564d04
#define KVM_PV_EOI_BIT         0
#define KVM_PV_EOI_MASK       (0x1 << KVM_PV_EOI_BIT)
#define KVM_PV_EOI_ENABLED     KVM_PV_EOI_MASK
#define KVM_PV_EOI_DISABLED    0x0

__attribute__ ((aligned(4)))
static volatile unsigned long kvm_exitless_eoi = KVM_PV_EOI_DISABLED;

void kvm_pv_eoi()
{
  uint8_t reg;
  asm("btr %2, %0; setc %1" : "+m"(kvm_exitless_eoi), "=rm"(reg) : "r"(0));
  if (reg) {
      kprintf("avoided\n");
      return;
  }
  // fallback to normal x2APIC EOI
  x2apic_send_eoi();
}
void kvm_pv_eoi_init()
{
  union {
    uint32_t msr[2];
    uint64_t whole;
  } guest;
  guest.whole = (uint64_t) &kvm_exitless_eoi;
  guest.whole |= KVM_MSR_ENABLED;
  x86::CPU::write_msr(MSR_KVM_PV_EOI_EN, guest.msr[0], guest.msr[1]);
  // verify that the feature was enabled
  uint64_t res = x86::CPU::read_msr(MSR_KVM_PV_EOI_EN);
  if (res & 1) {
    kprintf("* KVM paravirtual EOI enabled\n");
    // set new EOI handler
    current_eoi_mechanism = kvm_pv_eoi;
  }
}
<commit_msg>x86: Use x2apic EOI more directly<commit_after>// This file is a part of the IncludeOS unikernel - www.includeos.org
//
// Copyright 2015 Oslo and Akershus University College of Applied Sciences
// and Alfred Bratterud
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "apic.hpp"
#include "ioapic.hpp"
#include "acpi.hpp"
#include "cpu.hpp"
#include "pic.hpp"
#include "smp.hpp"
#include <kernel/cpuid.hpp>
#include <kernel/irq_manager.hpp>
#include <cstdlib>
#include <debug>
#include <kprint>
#include <info>

extern "C" {
  // current selected EOI method
  void (*current_eoi_mechanism)();
  // KVM para PV-EOI feature
  void kvm_pv_eoi();
  // shortcut that avoids virtual call
  void x2apic_send_eoi() {
    x86::CPU::write_msr(x86::x2apic::BASE_MSR + x2APIC_EOI, 0);
  }
}

void kvm_pv_eoi_init();

namespace x86
{
  static IApic* current_apic = nullptr;
  IApic& APIC::get() noexcept {
    return *current_apic;
  }

  void APIC::init()
  {
    // disable the legacy 8259 PIC
    // by masking off all interrupts
    PIC::set_intr_mask(0xFFFF);

    if (CPUID::has_feature(CPUID::Feature::X2APIC)) {
        current_apic = &x2apic::get();
        current_eoi_mechanism = x2apic_send_eoi;
    } else {
        // an x86 PC without APIC is insane
        assert(CPUID::has_feature(CPUID::Feature::APIC)
            && "If this fails, the machine is insane");
        current_apic = &xapic::get();
        current_eoi_mechanism = lapic_send_eoi;
    }

    // enable xAPIC/x2APIC on this cpu
    current_apic->enable();

    // initialize I/O APICs
    IOAPIC::init(ACPI::get_ioapics());

    // use KVMs paravirt EOI if supported
    //if (CPUID::kvm_feature(KVM_FEATURE_PV_EOI))
    //    kvm_pv_eoi_init();
  }

  void APIC::enable_irq(uint8_t irq)
  {
    auto& overrides = x86::ACPI::get_overrides();
    for (auto& redir : overrides)
    {
      // NOTE: @bus_source is the IOAPIC number
      if (redir.irq_source == irq)
      {
        INFO2("Enabled redirected IRQ %u -> %u on lapic %u",
            redir.irq_source, redir.global_intr, get().get_id());
        IOAPIC::enable(redir.global_intr, irq, get().get_id());
        return;
      }
    }
    INFO2("Enabled non-redirected IRQ %u on LAPIC %u", irq, get().get_id());
    IOAPIC::enable(irq, irq, get().get_id());
  }
  void APIC::disable_irq(uint8_t irq)
  {
    auto& overrides = x86::ACPI::get_overrides();
    for (auto& redir : overrides)
    {
      // NOTE: @bus_source is the IOAPIC number
      if (redir.irq_source == irq)
      {
        IOAPIC::disable(redir.global_intr);
        return;
      }
    }
    IOAPIC::disable(irq);
  }
}

// *** manual ***
// http://choon.net/forum/read.php?21,1123399
// https://www.kernel.org/doc/Documentation/virtual/kvm/cpuid.txt

#define KVM_MSR_ENABLED        1
#define MSR_KVM_PV_EOI_EN      0x4b564d04
#define KVM_PV_EOI_BIT         0
#define KVM_PV_EOI_MASK       (0x1 << KVM_PV_EOI_BIT)
#define KVM_PV_EOI_ENABLED     KVM_PV_EOI_MASK
#define KVM_PV_EOI_DISABLED    0x0

__attribute__ ((aligned(4)))
static volatile unsigned long kvm_exitless_eoi = KVM_PV_EOI_DISABLED;

void kvm_pv_eoi()
{
  uint8_t reg;
  asm("btr %2, %0; setc %1" : "+m"(kvm_exitless_eoi), "=rm"(reg) : "r"(0));
  if (reg) {
      kprintf("avoided\n");
      return;
  }
  // fallback to normal x2APIC EOI
  x2apic_send_eoi();
}
void kvm_pv_eoi_init()
{
  union {
    uint32_t msr[2];
    uint64_t whole;
  } guest;
  guest.whole = (uint64_t) &kvm_exitless_eoi;
  guest.whole |= KVM_MSR_ENABLED;
  x86::CPU::write_msr(MSR_KVM_PV_EOI_EN, guest.msr[0], guest.msr[1]);
  // verify that the feature was enabled
  uint64_t res = x86::CPU::read_msr(MSR_KVM_PV_EOI_EN);
  if (res & 1) {
    kprintf("* KVM paravirtual EOI enabled\n");
    // set new EOI handler
    current_eoi_mechanism = kvm_pv_eoi;
  }
}
<|endoftext|>


<commit_before>///-----------------------------------------------------------------------------
/// @FileName simple_speech
/// @Date 2014.08.10 / 2013.01.27
/// @author Yoonseok Pyo (passionvirus@gmail.com)
///-----------------------------------------------------------------------------

//------------------------------------------------------------------------------
#include <ros/ros.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <simple_speech/script.h>

//------------------------------------------------------------------------------
bool speech(simple_speech::script::Request  &req,
            simple_speech::script::Response &res)
{
  char cmd[30];
  char say[30];
  char tts[200];
  int  retval_tts;
  int  retval_say;

  strcpy(cmd,"pico2wave --wave ~/say.wav ");
  strcpy(say,"aplay ~/say.wav");

  snprintf(tts, 128, "%s\"%s\"", cmd, req.script.c_str());
  retval_tts = system(tts);
  retval_say = system(say);

  if(retval_tts == 127 || retval_say == 127) {        // shell invoke error
    res.result = 127;
  } else if (retval_tts ==  0 || retval_say ==  0) {  // null error
    res.result = 0;
  } else if (retval_tts == -1 || retval_say == -1) {  // error
    res.result = -1;
  } else
    res.result = 1;
}

//------------------------------------------------------------------------------
int main(int argc, char **argv)
{
  //--------------------------------------------------------------------------
  ros::init(argc, argv, "simple_speech");
  ros::NodeHandle nh;
  ros::ServiceServer service  = nh.advertiseService("simple_speech", speech);

  //--------------------------------------------------------------------------
  ros::Rate loop_rate(10); // 10Hz frequency (0.1 sec)
  while (ros::ok()) {
    ros::spinOnce();
    loop_rate.sleep();
  }
  return 0;
}

//------------------------------------------------------------------------------
<commit_msg>modified the return process<commit_after>///-----------------------------------------------------------------------------
/// @FileName simple_speech
/// @Date 2014.08.11 / 2013.01.27
/// @author Yoonseok Pyo (passionvirus@gmail.com)
///-----------------------------------------------------------------------------

//------------------------------------------------------------------------------
#include <ros/ros.h>
#include <stdlib.h>
#include <signal.h>
#include <string.h>
#include <stdio.h>
#include <simple_speech/script.h>

//------------------------------------------------------------------------------
bool speech(simple_speech::script::Request  &req,
            simple_speech::script::Response &res)
{
  char cmd[30];
  char say[30];
  char tts[200];
  int  ret;

  strcpy(cmd,"pico2wave --wave ~/say.wav ");
  strcpy(say,"aplay ~/say.wav");

  snprintf(tts, 200, "%s\"%s\"", cmd, req.script.c_str());

  ret = system(tts);  // make the wav file

  if (ret == -1 || ret == 127) { // fork failed and shell error
    res.result = 0;
    return false;
  }

  ret = system(say);  // play the wav file

  if (ret == -1 || ret == 127) { // fork failed and shell error
    res.result = 0;
    return false;
  }

  res.result = 1;
  return true;
}

//------------------------------------------------------------------------------
int main(int argc, char **argv)
{
  //--------------------------------------------------------------------------
  ros::init(argc, argv, "simple_speech");
  ros::NodeHandle nh;
  ros::ServiceServer service  = nh.advertiseService("simple_speech", speech);

  //--------------------------------------------------------------------------
  ros::Rate loop_rate(10); // 10Hz frequency (0.1 sec)
  while (ros::ok()) {
    ros::spinOnce();
    loop_rate.sleep();
  }
  return 0;
}

//------------------------------------------------------------------------------
<|endoftext|>


<commit_before>/*
   Copyright (c) 2010, The Mineserver Project
   All rights reserved.

   Redistribution and use in source and binary forms, with or without
   modification, are permitted provided that the following conditions are met:
 * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in the
      documentation and/or other materials provided with the distribution.
 * Neither the name of the The Mineserver Project nor the
      names of its contributors may be used to endorse or promote products
      derived from this software without specific prior written permission.

   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
   ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
   WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
   DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
   (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
   LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "tracks.h"
#include <iostream>

enum {
  FLAT_NS = 0,
  FLAT_EW,
  ASCEND_S,
  ASCEND_N,
  ASCEND_E,
  ASCEND_W,
  CORNER_SE,
  CORNER_SW,
  CORNER_NW,
  CORNER_NE
};

void BlockTracks::onStartedDigging(User* user, sint8 status, sint32 x, sint8 y, sint32 z, sint8 direction)
{

}

void BlockTracks::onDigging(User* user, sint8 status, sint32 x, sint8 y, sint32 z, sint8 direction)
{

}

void BlockTracks::onStoppedDigging(User* user, sint8 status, sint32 x, sint8 y, sint32 z, sint8 direction)
{

}

void BlockTracks::onBroken(User* user, sint8 status, sint32 x, sint8 y, sint32 z, sint8 direction)
{

}

void BlockTracks::onNeighbourBroken(User* user, sint8 oldblock, sint32 x, sint8 y, sint32 z, sint8 direction)
{
  uint8 block;
  uint8 meta;

  if (!Map::get()->getBlock(x, y, z, &block, &meta))
    return;

  if (this->isBlockEmpty(x, y-1, z))
  {
    // Break torch and spawn torch item
    Map::get()->sendBlockChange(x, y, z, BLOCK_AIR, 0);
    Map::get()->setBlock(x, y, z, BLOCK_AIR, 0);
    this->spawnBlockItem(x, y, z, block);
  }
}

void BlockTracks::onPlace(User* user, sint8 newblock, sint32 x, sint8 y, sint32 z, sint8 direction)
{
  uint8 block;
  uint8 meta;

  if (!Map::get()->getBlock(x, y, z, &block, &meta))
     return;

  /* Check block below allows blocks placed on top */
  if (!this->isBlockStackable(block))
     return;

  /* move the x,y,z coords dependent upon placement direction */
  if (!this->translateDirection(&x,&y,&z,direction))
     return;

  if (!this->isBlockEmpty(x,y,z))
     return;

  uint8 metadata = FLAT_NS;

  // SOUTH
  if(isTrack(x, y, z-1, meta) && isStartPiece(x, y, z-1))
  {
    std::cout << "SOUTH" << std::endl;
    metadata = FLAT_NS;

    if(isTrack(x+1, y, z, meta) && isStartPiece(x+1, y, z))
    {
      metadata = CORNER_NW;
    }
    if(isTrack(x-1, y, z, meta) && isStartPiece(x-1, y, z))
    {
      metadata = CORNER_SW;
    }

    // Modify previous trackpiece to form corner
    if(isTrack(x-1, y, z-1, meta) && meta != FLAT_NS && meta != CORNER_NW && meta != CORNER_SW)
    {
      Map::get()->setBlock(x, y, z-1, (char)newblock, CORNER_SW);
      Map::get()->sendBlockChange(x, y, z-1, (char)newblock, CORNER_SW);
    }
    else if(isTrack(x+1, y, z-1, meta) && meta != FLAT_NS && meta != CORNER_SW)
    {
      Map::get()->setBlock(x, y, z-1, (char)newblock, CORNER_SE);
      Map::get()->sendBlockChange(x, y, z-1, (char)newblock, CORNER_SE);
    }
  }

  // NORTH
  if(isTrack(x, y, z+1, meta) && isStartPiece(x, y, z+1))
  {
    std::cout << "NORTH" << std::endl;

    metadata = FLAT_NS;

    if(isTrack(x+1, y, z, meta) && isStartPiece(x+1, y, z))
    {
      metadata = CORNER_NE;
    }
    // NORTHWEST TURN (SE Corner)
    if(isTrack(x-1, y, z, meta) && isStartPiece(x-1, y, z))
    {
      metadata = CORNER_SE;
    }

    // Modify previous trackpiece to form corner
    if(isTrack(x+1, y, z+1, meta) && meta != FLAT_NS && meta != CORNER_NE && meta != CORNER_SE)
    {
      Map::get()->setBlock(x, y, z+1, (char)newblock, CORNER_NE);
      Map::get()->sendBlockChange(x, y, z+1, (char)newblock, CORNER_NE);
    }
    else if(isTrack(x-1, y, z+1, meta) && meta != FLAT_NS && meta != CORNER_NE && meta != CORNER_SE)
    {
      Map::get()->setBlock(x, y, z+1, (char)newblock, CORNER_NW);
      Map::get()->sendBlockChange(x, y, z+1, (char)newblock, CORNER_NW);
    }
  }

  // EAST
  if(isTrack(x-1, y, z, meta) && isStartPiece(x-1, y, z))
  {
    std::cout << "EAST" << std::endl;
    metadata = FLAT_EW;
    // Change previous block meta
    Map::get()->setBlock(x-1, y, z, (char)newblock, FLAT_EW);
    Map::get()->sendBlockChange(x-1, y, z, (char)newblock, FLAT_EW);

    if(isTrack(x, y, z+1, meta) && isStartPiece(x, y, z+1))
    {
      metadata = CORNER_SW;
    }
    if(isTrack(x, y, z-1, meta) && isStartPiece(x, y, z-1))
    {
      metadata = CORNER_NW;
    }

    // Modify previous trackpiece to form corner
    if(isTrack(x-1, y, z-1, meta) && meta != FLAT_EW && meta != CORNER_SE && meta != CORNER_SW)
    {
      Map::get()->setBlock(x-1, y, z, (char)newblock, CORNER_NE);
      Map::get()->sendBlockChange(x-1, y, z, (char)newblock, CORNER_NE);
    }
    else if(isTrack(x-1, y, z+1, meta) && meta != FLAT_EW && meta != CORNER_NW && meta != CORNER_SW)
    {
      Map::get()->setBlock(x-1, y, z, (char)newblock, CORNER_SE);
      Map::get()->sendBlockChange(x-1, y, z, (char)newblock, CORNER_SE);
    }
  }

  // WEST
  if(isTrack(x+1, y, z, meta) && isStartPiece(x+1, y, z))
  {
    std::cout << "WEST" << std::endl;
    metadata = FLAT_EW;
    // Change previous block meta

    Map::get()->setBlock(x+1, y, z, (char)newblock, FLAT_EW);
    Map::get()->sendBlockChange(x+1, y, z, (char)newblock, FLAT_EW);

    if(isTrack(x, y, z+1, meta) && isStartPiece(x, y, z+1))
    {
      metadata = CORNER_SE;
    }
    if(isTrack(x, y, z-1, meta) && isStartPiece(x, y, z-1))
    {
      metadata = CORNER_NE;
    }

    // Modify previous trackpiece to form corner
    if(isTrack(x+1, y, z-1, meta) && meta != FLAT_EW && meta != CORNER_NW && meta != CORNER_NE)
    {
      Map::get()->setBlock(x+1, y, z, (char)newblock, CORNER_NW);
      Map::get()->sendBlockChange(x+1, y, z, (char)newblock, CORNER_NW);
    }
    else if(isTrack(x+1, y, z+1, meta) && meta != FLAT_EW && meta != CORNER_SW && meta != CORNER_SE)
    {
      Map::get()->setBlock(x+1, y, z, (char)newblock, CORNER_SW);
      Map::get()->sendBlockChange(x+1, y, z, (char)newblock, CORNER_SW);
    }
  }

  std::cout << std::endl;
  Map::get()->setBlock(x, y, z, (char)newblock, metadata);
  Map::get()->sendBlockChange(x, y, z, (char)newblock, metadata);
}

void BlockTracks::onNeighbourPlace(User* user, sint8 newblock, sint32 x, sint8 y, sint32 z, sint8 direction)
{

}

void BlockTracks::onReplace(User* user, sint8 newblock, sint32 x, sint8 y, sint32 z, sint8 direction)
{

}

void BlockTracks::onNeighbourMove(User* user, sint8 oldblock, sint32 x, sint8 y, sint32 z, sint8 direction)
{

}

bool BlockTracks::isTrack(sint32 x, sint8 y, sint32 z, uint8& meta)
{
  uint8 block;
  Map::get()->getBlock(x, y, z, &block, &meta);
  return (block == BLOCK_MINECART_TRACKS);
}

bool BlockTracks::isStartPiece(sint32 x, sint8 y, sint32 z)
{
  uint8 block;
  uint8 meta;
  sint32 x1, x2, z1, z2;
  x1 = x2 = x;
  z1 = z2 = z;
  sint8 y1, y2;
  y1 = y2 = y;

  Map::get()->getBlock(x, y, z, &block, &meta);
  switch(meta)
  {
    case FLAT_EW:
      x1--;
      x2++;
      break;
    case FLAT_NS:
      z1--;
      z2++;
      break;
    case CORNER_SE:
      x1++;
      z2++;
      break;
    case CORNER_SW:
      z1++;
      x2--;
      break;
    case CORNER_NE:
      x1++;
      z2--;
      break;
    case CORNER_NW:
      x1--;
      z2--;
      break;
  }

  if((Map::get()->getBlock(x1, y1, z1, &block, &meta) && block != BLOCK_MINECART_TRACKS) ||
     (Map::get()->getBlock(x2, y2, z2, &block, &meta) && block != BLOCK_MINECART_TRACKS))
  {
    return true;
  }
  else
  {
    return false;
  }
}

<commit_msg>Planar tracks now fully working.<commit_after>/*
   Copyright (c) 2010, The Mineserver Project
   All rights reserved.

   Redistribution and use in source and binary forms, with or without
   modification, are permitted provided that the following conditions are met:
 * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in the
      documentation and/or other materials provided with the distribution.
 * Neither the name of the The Mineserver Project nor the
      names of its contributors may be used to endorse or promote products
      derived from this software without specific prior written permission.

   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
   ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
   WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
   DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
   (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
   LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "tracks.h"
//#include <iostream>

enum {
  FLAT_NS = 0,
  FLAT_EW,
  ASCEND_S,
  ASCEND_N,
  ASCEND_E,
  ASCEND_W,
  CORNER_SE,
  CORNER_SW,
  CORNER_NW,
  CORNER_NE
};

void BlockTracks::onStartedDigging(User* user, sint8 status, sint32 x, sint8 y, sint32 z, sint8 direction)
{

}

void BlockTracks::onDigging(User* user, sint8 status, sint32 x, sint8 y, sint32 z, sint8 direction)
{

}

void BlockTracks::onStoppedDigging(User* user, sint8 status, sint32 x, sint8 y, sint32 z, sint8 direction)
{

}

void BlockTracks::onBroken(User* user, sint8 status, sint32 x, sint8 y, sint32 z, sint8 direction)
{

}

void BlockTracks::onNeighbourBroken(User* user, sint8 oldblock, sint32 x, sint8 y, sint32 z, sint8 direction)
{
  uint8 block;
  uint8 meta;

  if (!Map::get()->getBlock(x, y, z, &block, &meta))
    return;

  if (this->isBlockEmpty(x, y-1, z))
  {
    // Break torch and spawn torch item
    Map::get()->sendBlockChange(x, y, z, BLOCK_AIR, 0);
    Map::get()->setBlock(x, y, z, BLOCK_AIR, 0);
    this->spawnBlockItem(x, y, z, block);
  }
}

void BlockTracks::onPlace(User* user, sint8 newblock, sint32 x, sint8 y, sint32 z, sint8 direction)
{
  uint8 block;
  uint8 meta;

  if (!Map::get()->getBlock(x, y, z, &block, &meta))
     return;

  /* Check block below allows blocks placed on top */
  if (!this->isBlockStackable(block))
     return;

  /* move the x,y,z coords dependent upon placement direction */
  if (!this->translateDirection(&x,&y,&z,direction))
     return;

  if (!this->isBlockEmpty(x,y,z))
     return;

  uint8 metadata = FLAT_NS;

  // SOUTH
  if(isTrack(x, y, z-1, meta) && isStartPiece(x, y, z-1))
  {
    //std::cout << "SOUTH" << std::endl;
    metadata = FLAT_NS;

    if(isTrack(x+1, y, z, meta) && isStartPiece(x+1, y, z))
    {
      metadata = CORNER_NE;
    }
    if(isTrack(x-1, y, z, meta) && isStartPiece(x-1, y, z))
    {
      metadata = CORNER_NW;
    }

    // Modify previous trackpiece to form corner
    if(isTrack(x-1, y, z-1, meta) && meta != FLAT_NS && meta != CORNER_NW && meta != CORNER_SW)
    {
      Map::get()->setBlock(x, y, z-1, (char)newblock, CORNER_SW);
      Map::get()->sendBlockChange(x, y, z-1, (char)newblock, CORNER_SW);
    }
    else if(isTrack(x+1, y, z-1, meta) && meta != FLAT_NS && meta != CORNER_NE && meta != CORNER_SE)
    {
      Map::get()->setBlock(x, y, z-1, (char)newblock, CORNER_SE);
      Map::get()->sendBlockChange(x, y, z-1, (char)newblock, CORNER_SE);
    }
  }

  // NORTH
  if(isTrack(x, y, z+1, meta) && isStartPiece(x, y, z+1))
  {
    //std::cout << "NORTH" << std::endl;

    metadata = FLAT_NS;

    if(isTrack(x+1, y, z, meta) && isStartPiece(x+1, y, z))
    {
      metadata = CORNER_SE;
    }
    if(isTrack(x-1, y, z, meta) && isStartPiece(x-1, y, z))
    {
      metadata = CORNER_SW;
    }

    // Modify previous trackpiece to form corner
    if(isTrack(x+1, y, z+1, meta) && meta != FLAT_NS && meta != CORNER_NE && meta != CORNER_SE)
    {
      Map::get()->setBlock(x, y, z+1, (char)newblock, CORNER_NE);
      Map::get()->sendBlockChange(x, y, z+1, (char)newblock, CORNER_NE);
    }
    else if(isTrack(x-1, y, z+1, meta) && meta != FLAT_NS && meta != CORNER_NW && meta != CORNER_SW)
    {
      Map::get()->setBlock(x, y, z+1, (char)newblock, CORNER_NW);
      Map::get()->sendBlockChange(x, y, z+1, (char)newblock, CORNER_NW);
    }
  }

  // EAST
  if(isTrack(x-1, y, z, meta) && isStartPiece(x-1, y, z))
  {
    //std::cout << "EAST" << std::endl;
    metadata = FLAT_EW;
    // Change previous block meta
    Map::get()->setBlock(x-1, y, z, (char)newblock, FLAT_EW);
    Map::get()->sendBlockChange(x-1, y, z, (char)newblock, FLAT_EW);

    if(isTrack(x, y, z+1, meta) && isStartPiece(x, y, z+1))
    {
      metadata = CORNER_SW;
    }
    if(isTrack(x, y, z-1, meta) && isStartPiece(x, y, z-1))
    {
      metadata = CORNER_NW;
    }

    // Modify previous trackpiece to form corner
    if(isTrack(x-1, y, z-1, meta) && meta != FLAT_EW && meta != CORNER_NE && meta != CORNER_NW)
    {
      Map::get()->setBlock(x-1, y, z, (char)newblock, CORNER_NE);
      Map::get()->sendBlockChange(x-1, y, z, (char)newblock, CORNER_NE);
    }
    else if(isTrack(x-1, y, z+1, meta) && meta != FLAT_EW && meta != CORNER_SW && meta != CORNER_SE)
    {
      Map::get()->setBlock(x-1, y, z, (char)newblock, CORNER_SE);
      Map::get()->sendBlockChange(x-1, y, z, (char)newblock, CORNER_SE);
    }
  }

  // WEST
  if(isTrack(x+1, y, z, meta) && isStartPiece(x+1, y, z))
  {
    //std::cout << "WEST" << std::endl;
    metadata = FLAT_EW;
    // Change previous block meta

    Map::get()->setBlock(x+1, y, z, (char)newblock, FLAT_EW);
    Map::get()->sendBlockChange(x+1, y, z, (char)newblock, FLAT_EW);

    if(isTrack(x, y, z+1, meta) && isStartPiece(x, y, z+1))
    {
      metadata = CORNER_SE;
    }
    if(isTrack(x, y, z-1, meta) && isStartPiece(x, y, z-1))
    {
      metadata = CORNER_NE;
    }

    // Modify previous trackpiece to form corner
    if(isTrack(x+1, y, z-1, meta) && meta != FLAT_EW && meta != CORNER_NW && meta != CORNER_NE)
    {
      Map::get()->setBlock(x+1, y, z, (char)newblock, CORNER_NW);
      Map::get()->sendBlockChange(x+1, y, z, (char)newblock, CORNER_NW);
    }
    else if(isTrack(x+1, y, z+1, meta) && meta != FLAT_EW && meta != CORNER_SW && meta != CORNER_SE)
    {
      Map::get()->setBlock(x+1, y, z, (char)newblock, CORNER_SW);
      Map::get()->sendBlockChange(x+1, y, z, (char)newblock, CORNER_SW);
    }
  }

  //std::cout << std::endl;
  Map::get()->setBlock(x, y, z, (char)newblock, metadata);
  Map::get()->sendBlockChange(x, y, z, (char)newblock, metadata);
}

void BlockTracks::onNeighbourPlace(User* user, sint8 newblock, sint32 x, sint8 y, sint32 z, sint8 direction)
{

}

void BlockTracks::onReplace(User* user, sint8 newblock, sint32 x, sint8 y, sint32 z, sint8 direction)
{

}

void BlockTracks::onNeighbourMove(User* user, sint8 oldblock, sint32 x, sint8 y, sint32 z, sint8 direction)
{

}

bool BlockTracks::isTrack(sint32 x, sint8 y, sint32 z, uint8& meta)
{
  uint8 block;
  Map::get()->getBlock(x, y, z, &block, &meta);
  return (block == BLOCK_MINECART_TRACKS);
}

bool BlockTracks::isStartPiece(sint32 x, sint8 y, sint32 z)
{
  uint8 block;
  uint8 meta;
  sint32 x1, x2, z1, z2;
  x1 = x2 = x;
  z1 = z2 = z;

  sint8 y1, y2;
  y1 = y2 = y;

  Map::get()->getBlock(x, y, z, &block, &meta);
  switch(meta)
  {
    case FLAT_EW:
      x1--;
      x2++;
      break;
    case FLAT_NS:
      z1--;
      z2++;
      break;
    case CORNER_SE:
      x1++;
      z2++;
      break;
    case CORNER_SW:
      z1++;
      x2--;
      break;
    case CORNER_NE:
      x1++;
      z2--;
      break;
    case CORNER_NW:
      x1--;
      z2--;
      break;
  }

  if((Map::get()->getBlock(x1, y1, z1, &block, &meta) && block != BLOCK_MINECART_TRACKS) ||
     (Map::get()->getBlock(x2, y2, z2, &block, &meta) && block != BLOCK_MINECART_TRACKS))
  {
    return true;
  }
  else
  {
    return false;
  }
}

<|endoftext|>


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

#include "instance.h"
#include <algorithm>
#include <functional>
#include <stdio.h>
#include <string>
#include <ppapi/c/pp_time.h>
#include <ppapi/cpp/core.h>
#include <ppapi/cpp/module.h>
#include <ppapi/cpp/input_event.h>
#include <ppapi/cpp/var.h>
#include <ppapi/lib/gl/gles2/gl2ext_ppapi.h>

#include "cpu/initializer_factory.h"
#include "gpu/initializer_factory.h"
#include "messages.h"
#include "simulation_config.h"
#include "simulation_thread.h"
#include "simulation_thread_options.h"
#include "task.h"
#include "view_base.h"

namespace {

const int kUpdateInterval = 1000;
const pp::Size kSimSize(512, 512);

double GetTimeTicks() {
  return pp::Module::Get()->core()->GetTimeTicks();
}

}  // namespace

Instance::Instance(PP_Instance instance)
    : pp::Instance(instance),
      factory_(this),
      view_(NULL),
      thread_(NULL),
      fullscreen_(this),
      is_initial_view_change_(true),
      brush_radius_(10),
      brush_color_(1.0) {
  // Request to receive input events.
  RequestInputEvents(PP_INPUTEVENT_CLASS_MOUSE | PP_INPUTEVENT_CLASS_KEYBOARD);
}

Instance::~Instance() {
  delete thread_;
  delete view_;
}

bool Instance::Init(uint32_t argc, const char* argn[],
                              const char* argv[]) {
  glInitializePPAPI(pp::Module::Get()->get_browser_interface());
  SimulationConfig config;
  config.size = kSimSize;

  InitializerFactoryBase* initializer_factory;
  initializer_factory = new cpu::InitializerFactory(config.size);
  //initializer_factory = new gpu::InitializerFactory(config.size);

  SimulationThreadContext context;
  context.config = config;
  context.run_options = kRunOptions_Simulation;
  context.draw_options = kDrawOptions_Simulation;
  context.initializer_factory = initializer_factory;

  thread_ = new SimulationThread(this, context);
  view_ = initializer_factory->CreateView();

  InitMessageMap();
  ParseInitMessages(argc, argn, argv);
  thread_->Start();

  return true;
}

void Instance::ParseInitMessages(
    uint32_t argc, const char* argn[], const char* argv[]) {
  for (uint32_t i = 0; i < argc; ++i) {
    if (strncmp(argn[i], "msg", 3) == 0) {
      HandleMessage(pp::Var(argv[i]));
    }
  }
}

void Instance::InitMessageMap() {
  using namespace std::placeholders;

#define MESSAGE(NAME, ...) \
  message_handler_.AddHandler(#NAME, std::bind(&msg::NAME, __VA_ARGS__));

  MESSAGE(Clear, thread_, _1);
  MESSAGE(GetBuffer, thread_, _1);
  MESSAGE(SetBrush, _1, &brush_radius_, &brush_color_);
  MESSAGE(SetDrawOptions, thread_, _1);
  MESSAGE(SetFullscreen, _1, &fullscreen_);
  MESSAGE(SetKernel, thread_, _1);
  MESSAGE(SetPalette, thread_, _1);
  MESSAGE(SetRunOptions, thread_, _1);
  MESSAGE(SetSmoother, thread_, _1);
  MESSAGE(Splat, thread_, _1);

#undef M
}

void Instance::DidChangeView(const pp::View& view) {
  if (!view_->DidChangeView(this, view)) {
    PostMessage(pp::Var(
        "ERROR DidChangeView failed. Could not bind graphics?"));
    return;
  }

  if (is_initial_view_change_) {
    ScheduleUpdate();
  }

  is_initial_view_change_ = false;
}

bool Instance::HandleInputEvent(const pp::InputEvent& event) {
  static bool left_down_ = false;

  switch (event.GetType()) {
    case PP_INPUTEVENT_TYPE_MOUSEUP:
    case PP_INPUTEVENT_TYPE_MOUSEDOWN:
    case PP_INPUTEVENT_TYPE_MOUSEMOVE: {
      pp::MouseInputEvent mouse_event(event);
      if (mouse_event.GetButton() == PP_INPUTEVENT_MOUSEBUTTON_LEFT)
        left_down_ = event.GetType() == PP_INPUTEVENT_TYPE_MOUSEDOWN;

      if (left_down_) {
        pp::Point sim_point =
            view_->ScreenToSim(mouse_event.GetPosition(), kSimSize);
        thread_->EnqueueTask(MakeFunctionTask(
              &SimulationThread::TaskDrawFilledCircle,
              sim_point.x(),
              sim_point.y(),
              brush_radius_,
              brush_color_));
      }
      return false;
    }
    default:
    case PP_INPUTEVENT_TYPE_KEYUP:
    case PP_INPUTEVENT_TYPE_KEYDOWN:
    case PP_INPUTEVENT_TYPE_UNDEFINED:
    case PP_INPUTEVENT_TYPE_MOUSEENTER:
    case PP_INPUTEVENT_TYPE_MOUSELEAVE:
    case PP_INPUTEVENT_TYPE_WHEEL:
    case PP_INPUTEVENT_TYPE_RAWKEYDOWN:
    case PP_INPUTEVENT_TYPE_CHAR:
    case PP_INPUTEVENT_TYPE_CONTEXTMENU:
    case PP_INPUTEVENT_TYPE_IME_COMPOSITION_START:
    case PP_INPUTEVENT_TYPE_IME_COMPOSITION_UPDATE:
    case PP_INPUTEVENT_TYPE_IME_COMPOSITION_END:
    case PP_INPUTEVENT_TYPE_IME_TEXT:
    case PP_INPUTEVENT_TYPE_TOUCHSTART:
    case PP_INPUTEVENT_TYPE_TOUCHMOVE:
    case PP_INPUTEVENT_TYPE_TOUCHEND:
    case PP_INPUTEVENT_TYPE_TOUCHCANCEL:
      return false;
  }
}

void Instance::HandleMessage(const pp::Var& var_message) {
  if (!var_message.is_string())
    return;
  std::string message = var_message.AsString();
  message_handler_.HandleMessage(message);
}

void Instance::ScheduleUpdate() {
  pp::Module::Get()->core()->CallOnMainThread(
      kUpdateInterval,
      factory_.NewCallback(&Instance::UpdateCallback));
}

void Instance::UpdateCallback(int32_t result) {
  // This is the game loop; UpdateCallback schedules another call to itself to
  // occur kUpdateInterval milliseconds later.
  ScheduleUpdate();
  static PP_TimeTicks first_time;
  static PP_TimeTicks last_time = 0;
  if (last_time) {
    PP_TimeTicks this_time = GetTimeTicks();
    int num_frames = thread_->GetFramesDrawnAndReset();
    float fps = num_frames / (this_time - last_time);
    char buffer[20];
    sprintf(&buffer[0], "FPS: %.3f", fps);
    PostMessage(pp::Var(buffer));

    last_time = this_time;
  } else {
    first_time = GetTimeTicks();
    last_time = GetTimeTicks();
  }
}
<commit_msg>Fix mouse drawing bug.<commit_after>// Copyright 2013 Ben Smith. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "instance.h"
#include <algorithm>
#include <functional>
#include <stdio.h>
#include <string>
#include <ppapi/c/pp_time.h>
#include <ppapi/cpp/core.h>
#include <ppapi/cpp/module.h>
#include <ppapi/cpp/input_event.h>
#include <ppapi/cpp/var.h>
#include <ppapi/lib/gl/gles2/gl2ext_ppapi.h>

#include "cpu/initializer_factory.h"
#include "gpu/initializer_factory.h"
#include "messages.h"
#include "simulation_config.h"
#include "simulation_thread.h"
#include "simulation_thread_options.h"
#include "task.h"
#include "view_base.h"

namespace {

const int kUpdateInterval = 1000;
const pp::Size kSimSize(512, 512);

double GetTimeTicks() {
  return pp::Module::Get()->core()->GetTimeTicks();
}

}  // namespace

Instance::Instance(PP_Instance instance)
    : pp::Instance(instance),
      factory_(this),
      view_(NULL),
      thread_(NULL),
      fullscreen_(this),
      is_initial_view_change_(true),
      brush_radius_(10),
      brush_color_(1.0) {
  // Request to receive input events.
  RequestInputEvents(PP_INPUTEVENT_CLASS_MOUSE | PP_INPUTEVENT_CLASS_KEYBOARD);
}

Instance::~Instance() {
  delete thread_;
  delete view_;
}

bool Instance::Init(uint32_t argc, const char* argn[],
                              const char* argv[]) {
  glInitializePPAPI(pp::Module::Get()->get_browser_interface());
  SimulationConfig config;
  config.size = kSimSize;

  InitializerFactoryBase* initializer_factory;
  initializer_factory = new cpu::InitializerFactory(config.size);
  //initializer_factory = new gpu::InitializerFactory(config.size);

  SimulationThreadContext context;
  context.config = config;
  context.run_options = kRunOptions_Simulation;
  context.draw_options = kDrawOptions_Simulation;
  context.initializer_factory = initializer_factory;

  thread_ = new SimulationThread(this, context);
  view_ = initializer_factory->CreateView();

  InitMessageMap();
  ParseInitMessages(argc, argn, argv);
  thread_->Start();

  return true;
}

void Instance::ParseInitMessages(
    uint32_t argc, const char* argn[], const char* argv[]) {
  for (uint32_t i = 0; i < argc; ++i) {
    if (strncmp(argn[i], "msg", 3) == 0) {
      HandleMessage(pp::Var(argv[i]));
    }
  }
}

void Instance::InitMessageMap() {
  using namespace std::placeholders;

#define MESSAGE(NAME, ...) \
  message_handler_.AddHandler(#NAME, std::bind(&msg::NAME, __VA_ARGS__));

  MESSAGE(Clear, thread_, _1);
  MESSAGE(GetBuffer, thread_, _1);
  MESSAGE(SetBrush, _1, &brush_radius_, &brush_color_);
  MESSAGE(SetDrawOptions, thread_, _1);
  MESSAGE(SetFullscreen, _1, &fullscreen_);
  MESSAGE(SetKernel, thread_, _1);
  MESSAGE(SetPalette, thread_, _1);
  MESSAGE(SetRunOptions, thread_, _1);
  MESSAGE(SetSmoother, thread_, _1);
  MESSAGE(Splat, thread_, _1);

#undef M
}

void Instance::DidChangeView(const pp::View& view) {
  if (!view_->DidChangeView(this, view)) {
    PostMessage(pp::Var(
        "ERROR DidChangeView failed. Could not bind graphics?"));
    return;
  }

  if (is_initial_view_change_) {
    ScheduleUpdate();
  }

  is_initial_view_change_ = false;
}

bool Instance::HandleInputEvent(const pp::InputEvent& event) {
  static bool left_down_ = false;

  switch (event.GetType()) {
    case PP_INPUTEVENT_TYPE_MOUSEUP: {
      pp::MouseInputEvent mouse_event(event);
      if (mouse_event.GetButton() == PP_INPUTEVENT_MOUSEBUTTON_LEFT)
        left_down_ = false;
      break;
    }

    case PP_INPUTEVENT_TYPE_MOUSEDOWN: {
      pp::MouseInputEvent mouse_event(event);
      if (mouse_event.GetButton() == PP_INPUTEVENT_MOUSEBUTTON_LEFT)
        left_down_ = true;
      // fall through
    }

    case PP_INPUTEVENT_TYPE_MOUSEMOVE: {
      pp::MouseInputEvent mouse_event(event);

      if (left_down_) {
        pp::Point sim_point =
            view_->ScreenToSim(mouse_event.GetPosition(), kSimSize);
        thread_->EnqueueTask(MakeFunctionTask(
            &SimulationThread::TaskDrawFilledCircle,
            sim_point.x(),
            sim_point.y(),
            brush_radius_,
            brush_color_));
      }
      return false;
    }
    default:
    case PP_INPUTEVENT_TYPE_KEYUP:
    case PP_INPUTEVENT_TYPE_KEYDOWN:
    case PP_INPUTEVENT_TYPE_UNDEFINED:
    case PP_INPUTEVENT_TYPE_MOUSEENTER:
    case PP_INPUTEVENT_TYPE_MOUSELEAVE:
    case PP_INPUTEVENT_TYPE_WHEEL:
    case PP_INPUTEVENT_TYPE_RAWKEYDOWN:
    case PP_INPUTEVENT_TYPE_CHAR:
    case PP_INPUTEVENT_TYPE_CONTEXTMENU:
    case PP_INPUTEVENT_TYPE_IME_COMPOSITION_START:
    case PP_INPUTEVENT_TYPE_IME_COMPOSITION_UPDATE:
    case PP_INPUTEVENT_TYPE_IME_COMPOSITION_END:
    case PP_INPUTEVENT_TYPE_IME_TEXT:
    case PP_INPUTEVENT_TYPE_TOUCHSTART:
    case PP_INPUTEVENT_TYPE_TOUCHMOVE:
    case PP_INPUTEVENT_TYPE_TOUCHEND:
    case PP_INPUTEVENT_TYPE_TOUCHCANCEL:
      return false;
  }
}

void Instance::HandleMessage(const pp::Var& var_message) {
  if (!var_message.is_string())
    return;
  std::string message = var_message.AsString();
  message_handler_.HandleMessage(message);
}

void Instance::ScheduleUpdate() {
  pp::Module::Get()->core()->CallOnMainThread(
      kUpdateInterval,
      factory_.NewCallback(&Instance::UpdateCallback));
}

void Instance::UpdateCallback(int32_t result) {
  // This is the game loop; UpdateCallback schedules another call to itself to
  // occur kUpdateInterval milliseconds later.
  ScheduleUpdate();
  static PP_TimeTicks first_time;
  static PP_TimeTicks last_time = 0;
  if (last_time) {
    PP_TimeTicks this_time = GetTimeTicks();
    int num_frames = thread_->GetFramesDrawnAndReset();
    float fps = num_frames / (this_time - last_time);
    char buffer[20];
    sprintf(&buffer[0], "FPS: %.3f", fps);
    PostMessage(pp::Var(buffer));

    last_time = this_time;
  } else {
    first_time = GetTimeTicks();
    last_time = GetTimeTicks();
  }
}
<|endoftext|>