<commit_before>// Copyright (c) 2003 Daniel Wallin and Arvid Norberg

// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:

// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.

// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
// ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
// SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
// ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
// OR OTHER DEALINGS IN THE SOFTWARE.

#define LUABIND_BUILDING

#include <luabind/detail/object_rep.hpp>
#include <luabind/detail/class_rep.hpp>

#if LUA_VERSION_NUM < 502
# define lua_getuservalue lua_getfenv
# define lua_setuservalue lua_setfenv
#endif

namespace luabind { namespace detail
{

	// dest is a function that is called to delete the c++ object this struct holds
	object_rep::object_rep(instance_holder* instance, class_rep* crep)
		: m_instance(instance)
		, m_classrep(crep)
		, m_dependency_cnt(0)
	{}

	object_rep::~object_rep()
	{
        if (!m_instance)
            return;
        m_instance->~instance_holder();
        deallocate(m_instance);
	}

	void object_rep::add_dependency(lua_State* L, int index)
	{
        assert(m_dependency_cnt < sizeof(object_rep));

        void* key = (char*)this + m_dependency_cnt;

        lua_pushlightuserdata(L, key);
        lua_pushvalue(L, index);
        lua_rawset(L, LUA_REGISTRYINDEX);

        ++m_dependency_cnt;
	}

    void object_rep::release_dependency_refs(lua_State* L)
    {
        for (std::size_t i = 0; i < m_dependency_cnt; ++i)
        {
            void* key = (char*)this + i;
            lua_pushlightuserdata(L, key);
            lua_pushnil(L);
            lua_rawset(L, LUA_REGISTRYINDEX);
        }
    }

    int destroy_instance(lua_State* L)
    {
        object_rep* instance = static_cast<object_rep*>(lua_touserdata(L, 1));

        lua_pushstring(L, "__finalize");
        lua_gettable(L, 1);

        if (lua_isnil(L, -1))
        {
            lua_pop(L, 1);
        }
        else
        {
            lua_pushvalue(L, 1);
            lua_call(L, 1, 0);
        }

        instance->release_dependency_refs(L);
        instance->~object_rep();
        return 0;
    }

    namespace
    {

      int set_instance_value(lua_State* L)
      {
          lua_getuservalue(L, 1);
          lua_pushvalue(L, 2);
          lua_rawget(L, -2);

          if (lua_isnil(L, -1) && lua_getmetatable(L, -2))
          {
              lua_pushvalue(L, 2);
              lua_rawget(L, -2);
              lua_replace(L, -3);
              lua_pop(L, 1);
          }

          if (lua_tocfunction(L, -1) == &property_tag)
          {
              // this member is a property, extract the "set" function and call it.
              lua_getupvalue(L, -1, 2);

              if (lua_isnil(L, -1))
              {
                  lua_pushfstring(L, "property '%s' is read only", lua_tostring(L, 2));
                  lua_error(L);
              }

              lua_pushvalue(L, 1);
              lua_pushvalue(L, 3);
              lua_call(L, 2, 0);
              return 0;
          }

          lua_pop(L, 1);

          if (!lua_getmetatable(L, 4))
          {
              lua_newtable(L);
              lua_pushvalue(L, -1);
              lua_setuservalue(L, 1);
              lua_pushvalue(L, 4);
              lua_setmetatable(L, -2);
          }
          else
          {
              lua_pop(L, 1);
          }

          lua_pushvalue(L, 2);
          lua_pushvalue(L, 3);
          lua_rawset(L, -3);

          return 0;
      }

      int get_instance_value(lua_State* L)
      {
          lua_getuservalue(L, 1);
          lua_pushvalue(L, 2);
          lua_rawget(L, -2);

          if (lua_isnil(L, -1) && lua_getmetatable(L, -2))
          {
              lua_pushvalue(L, 2);
              lua_rawget(L, -2);
          }

          if (lua_tocfunction(L, -1) == &property_tag)
          {
              // this member is a property, extract the "get" function and call it.
              lua_getupvalue(L, -1, 1);
              lua_pushvalue(L, 1);
              lua_call(L, 1, 1);
          }

          return 1;
      }

      int dispatch_operator(lua_State* L)
      {
          for (int i = 0; i < 2; ++i)
          {
              if (get_instance(L, 1 + i))
              {
                  int nargs = lua_gettop(L);

                  lua_pushvalue(L, lua_upvalueindex(1));
                  lua_gettable(L, 1 + i);

                  if (lua_isnil(L, -1))
                  {
                      lua_pop(L, 1);
                      continue;
                  }

                  lua_insert(L, 1); // move the function to the bottom

                  nargs = lua_toboolean(L, lua_upvalueindex(2)) ? 1 : nargs;

                  if (lua_toboolean(L, lua_upvalueindex(2))) // remove trailing nil
                  lua_remove(L, 3);

                  lua_call(L, nargs, 1);
                  return 1;
              }
          }

          lua_pop(L, lua_gettop(L));
          lua_pushstring(L, "No such operator defined");
          lua_error(L);

          return 0;
      }

    } // namespace unnamed

    LUABIND_API void push_instance_metatable(lua_State* L)
    {
        lua_newtable(L);

        // just indicate that this really is a class and not just
        // any user data
        lua_pushboolean(L, 1);
        lua_setfield(L, -2, "__luabind_class");

        // This is used as a tag to determine if a userdata is a luabind
        // instance. We use a numeric key and a cclosure for fast comparision.
        lua_pushnumber(L, 1);
        lua_pushcclosure(L, get_instance_value, 0);
        lua_rawset(L, -3);

        lua_pushcclosure(L, destroy_instance, 0);
        lua_setfield(L, -2, "__gc");

        lua_pushcclosure(L, get_instance_value, 0);
        lua_setfield(L, -2, "__index");

        lua_pushcclosure(L, set_instance_value, 0);
        lua_setfield(L, -2, "__newindex");

        for (int op = 0; op < number_of_operators; ++op)
        {
            lua_pushstring(L, get_operator_name(op));
            lua_pushvalue(L, -1);
            lua_pushboolean(L, op == op_unm || op == op_len);
            lua_pushcclosure(L, &dispatch_operator, 2);
            lua_settable(L, -3);
        }
    }

    LUABIND_API object_rep* get_instance(lua_State* L, int index)
    {
        object_rep* result = static_cast<object_rep*>(lua_touserdata(L, index));

        if (!result || !lua_getmetatable(L, index))
            return 0;

        lua_rawgeti(L, -1, 1);

        if (lua_tocfunction(L, -1) != &get_instance_value)
            result = 0;

        lua_pop(L, 2);

        return result;
    }

    LUABIND_API object_rep* push_new_instance(lua_State* L, class_rep* cls)
    {
        void* storage = lua_newuserdata(L, sizeof(object_rep));
        object_rep* result = new (storage) object_rep(0, cls);
        cls->get_table(L);
        lua_setuservalue(L, -2);
        lua_rawgeti(L, LUA_REGISTRYINDEX, cls->metatable_ref());
        lua_setmetatable(L, -2);
        return result;
    }

}}

<commit_msg>Unset metatable when destroying C++-objects.<commit_after>// Copyright (c) 2003 Daniel Wallin and Arvid Norberg

// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:

// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.

// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
// ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
// SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
// ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
// OR OTHER DEALINGS IN THE SOFTWARE.

#define LUABIND_BUILDING

#include <luabind/detail/object_rep.hpp>
#include <luabind/detail/class_rep.hpp>

#if LUA_VERSION_NUM < 502
# define lua_getuservalue lua_getfenv
# define lua_setuservalue lua_setfenv
#endif

namespace luabind { namespace detail
{

	// dest is a function that is called to delete the c++ object this struct holds
	object_rep::object_rep(instance_holder* instance, class_rep* crep)
		: m_instance(instance)
		, m_classrep(crep)
		, m_dependency_cnt(0)
	{}

	object_rep::~object_rep()
	{
        if (!m_instance)
            return;
        m_instance->~instance_holder();
        deallocate(m_instance);
	}

	void object_rep::add_dependency(lua_State* L, int index)
	{
        assert(m_dependency_cnt < sizeof(object_rep));

        void* key = (char*)this + m_dependency_cnt;

        lua_pushlightuserdata(L, key);
        lua_pushvalue(L, index);
        lua_rawset(L, LUA_REGISTRYINDEX);

        ++m_dependency_cnt;
	}

    void object_rep::release_dependency_refs(lua_State* L)
    {
        for (std::size_t i = 0; i < m_dependency_cnt; ++i)
        {
            void* key = (char*)this + i;
            lua_pushlightuserdata(L, key);
            lua_pushnil(L);
            lua_rawset(L, LUA_REGISTRYINDEX);
        }
    }

    int destroy_instance(lua_State* L)
    {
        object_rep* instance = static_cast<object_rep*>(lua_touserdata(L, 1));

        lua_pushstring(L, "__finalize");
        lua_gettable(L, 1);

        if (lua_isnil(L, -1))
        {
            lua_pop(L, 1);
        }
        else
        {
            lua_pushvalue(L, 1);
            lua_call(L, 1, 0);
        }

        instance->release_dependency_refs(L);
        instance->~object_rep();

        lua_pushnil(L);
        lua_setmetatable(L, 1);
        return 0;
    }

    namespace
    {

      int set_instance_value(lua_State* L)
      {
          lua_getuservalue(L, 1);
          lua_pushvalue(L, 2);
          lua_rawget(L, -2);

          if (lua_isnil(L, -1) && lua_getmetatable(L, -2))
          {
              lua_pushvalue(L, 2);
              lua_rawget(L, -2);
              lua_replace(L, -3);
              lua_pop(L, 1);
          }

          if (lua_tocfunction(L, -1) == &property_tag)
          {
              // this member is a property, extract the "set" function and call it.
              lua_getupvalue(L, -1, 2);

              if (lua_isnil(L, -1))
              {
                  lua_pushfstring(L, "property '%s' is read only", lua_tostring(L, 2));
                  lua_error(L);
              }

              lua_pushvalue(L, 1);
              lua_pushvalue(L, 3);
              lua_call(L, 2, 0);
              return 0;
          }

          lua_pop(L, 1);

          if (!lua_getmetatable(L, 4))
          {
              lua_newtable(L);
              lua_pushvalue(L, -1);
              lua_setuservalue(L, 1);
              lua_pushvalue(L, 4);
              lua_setmetatable(L, -2);
          }
          else
          {
              lua_pop(L, 1);
          }

          lua_pushvalue(L, 2);
          lua_pushvalue(L, 3);
          lua_rawset(L, -3);

          return 0;
      }

      int get_instance_value(lua_State* L)
      {
          lua_getuservalue(L, 1);
          lua_pushvalue(L, 2);
          lua_rawget(L, -2);

          if (lua_isnil(L, -1) && lua_getmetatable(L, -2))
          {
              lua_pushvalue(L, 2);
              lua_rawget(L, -2);
          }

          if (lua_tocfunction(L, -1) == &property_tag)
          {
              // this member is a property, extract the "get" function and call it.
              lua_getupvalue(L, -1, 1);
              lua_pushvalue(L, 1);
              lua_call(L, 1, 1);
          }

          return 1;
      }

      int dispatch_operator(lua_State* L)
      {
          for (int i = 0; i < 2; ++i)
          {
              if (get_instance(L, 1 + i))
              {
                  int nargs = lua_gettop(L);

                  lua_pushvalue(L, lua_upvalueindex(1));
                  lua_gettable(L, 1 + i);

                  if (lua_isnil(L, -1))
                  {
                      lua_pop(L, 1);
                      continue;
                  }

                  lua_insert(L, 1); // move the function to the bottom

                  nargs = lua_toboolean(L, lua_upvalueindex(2)) ? 1 : nargs;

                  if (lua_toboolean(L, lua_upvalueindex(2))) // remove trailing nil
                  lua_remove(L, 3);

                  lua_call(L, nargs, 1);
                  return 1;
              }
          }

          lua_pop(L, lua_gettop(L));
          lua_pushstring(L, "No such operator defined");
          lua_error(L);

          return 0;
      }

    } // namespace unnamed

    LUABIND_API void push_instance_metatable(lua_State* L)
    {
        lua_newtable(L);

        // just indicate that this really is a class and not just
        // any user data
        lua_pushboolean(L, 1);
        lua_setfield(L, -2, "__luabind_class");

        // This is used as a tag to determine if a userdata is a luabind
        // instance. We use a numeric key and a cclosure for fast comparision.
        lua_pushnumber(L, 1);
        lua_pushcclosure(L, get_instance_value, 0);
        lua_rawset(L, -3);

        lua_pushcclosure(L, destroy_instance, 0);
        lua_setfield(L, -2, "__gc");

        lua_pushcclosure(L, get_instance_value, 0);
        lua_setfield(L, -2, "__index");

        lua_pushcclosure(L, set_instance_value, 0);
        lua_setfield(L, -2, "__newindex");

        for (int op = 0; op < number_of_operators; ++op)
        {
            lua_pushstring(L, get_operator_name(op));
            lua_pushvalue(L, -1);
            lua_pushboolean(L, op == op_unm || op == op_len);
            lua_pushcclosure(L, &dispatch_operator, 2);
            lua_settable(L, -3);
        }
    }

    LUABIND_API object_rep* get_instance(lua_State* L, int index)
    {
        object_rep* result = static_cast<object_rep*>(lua_touserdata(L, index));

        if (!result || !lua_getmetatable(L, index))
            return 0;

        lua_rawgeti(L, -1, 1);

        if (lua_tocfunction(L, -1) != &get_instance_value)
            result = 0;

        lua_pop(L, 2);

        return result;
    }

    LUABIND_API object_rep* push_new_instance(lua_State* L, class_rep* cls)
    {
        void* storage = lua_newuserdata(L, sizeof(object_rep));
        object_rep* result = new (storage) object_rep(0, cls);
        cls->get_table(L);
        lua_setuservalue(L, -2);
        lua_rawgeti(L, LUA_REGISTRYINDEX, cls->metatable_ref());
        lua_setmetatable(L, -2);
        return result;
    }

}}

<|endoftext|>


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

// NOTE: This file is intended to be customised by the end user, and includes only local node policy logic

#include "policy/policy.h"

#include "main.h"
#include "tinyformat.h"
#include "util.h"
#include "utilstrencodings.h"

#include <boost/foreach.hpp>
// SYSCOIN need constant SYSCOIN_TX_VERSION
extern int GetSyscoinTxVersion();
    /**
     * Check transaction inputs to mitigate two
     * potential denial-of-service attacks:
     *
     * 1. scriptSigs with extra data stuffed into them,
     *    not consumed by scriptPubKey (or P2SH script)
     * 2. P2SH scripts with a crazy number of expensive
     *    CHECKSIG/CHECKMULTISIG operations
     *
     * Why bother? To avoid denial-of-service attacks; an attacker
     * can submit a standard HASH... OP_EQUAL transaction,
     * which will get accepted into blocks. The redemption
     * script can be anything; an attacker could use a very
     * expensive-to-check-upon-redemption script like:
     *   DUP CHECKSIG DROP ... repeated 100 times... OP_1
     */

bool IsStandard(const CScript& scriptPubKey, txnouttype& whichType, const bool witnessEnabled)
{
    std::vector<std::vector<unsigned char> > vSolutions;
    if (!Solver(scriptPubKey, whichType, vSolutions))
        return false;

    if (whichType == TX_MULTISIG)
    {
        unsigned char m = vSolutions.front()[0];
        unsigned char n = vSolutions.back()[0];
		// Support up to x-of-3 multisig txns as standard
        if (n < 1 || n > 3)
            return false;
        if (m < 1 || m > n)
            return false;
	// SYSCOIN check for size of sys tx, normal tx size is checked in isstandardtx now
    } else if (whichType == TX_NULL_DATA &&
               (!fAcceptDatacarrier || scriptPubKey.size() > nMaxDatacarrierBytes*75))
          return false;

    else if (!witnessEnabled && (whichType == TX_WITNESS_V0_KEYHASH || whichType == TX_WITNESS_V0_SCRIPTHASH))
        return false;

    return whichType != TX_NONSTANDARD;
}

bool IsStandardTx(const CTransaction& tx, std::string& reason, const bool witnessEnabled)
{
	// SYSCOIN check for syscoin or bitcoin tx
    if ((tx.nVersion > CTransaction::CURRENT_VERSION || tx.nVersion < 1) && tx.nVersion != GetSyscoinTxVersion()) {
        reason = "version";
        return false;
    }

    // Extremely large transactions with lots of inputs can cost the network
    // almost as much to process as they cost the sender in fees, because
    // computing signature hashes is O(ninputs*txsize). Limiting transactions
    // to MAX_STANDARD_TX_SIZE mitigates CPU exhaustion attacks.
    unsigned int sz = GetTransactionWeight(tx);
    if (sz >= MAX_STANDARD_TX_WEIGHT) {
        reason = "tx-size";
        return false;
    }

    BOOST_FOREACH(const CTxIn& txin, tx.vin)
    {
        // Biggest 'standard' txin is a 15-of-15 P2SH multisig with compressed
        // keys (remember the 520 byte limit on redeemScript size). That works
        // out to a (15*(33+1))+3=513 byte redeemScript, 513+1+15*(73+1)+3=1627
        // bytes of scriptSig, which we round off to 1650 bytes for some minor
        // future-proofing. That's also enough to spend a 20-of-20
        // CHECKMULTISIG scriptPubKey, though such a scriptPubKey is not
        // considered standard.
        if (txin.scriptSig.size() > 1650) {
            reason = "scriptsig-size";
            return false;
        }
        if (!txin.scriptSig.IsPushOnly()) {
            reason = "scriptsig-not-pushonly";
            return false;
        }
    }

    unsigned int nDataOut = 0;
    txnouttype whichType;
    BOOST_FOREACH(const CTxOut& txout, tx.vout) {
        if (!::IsStandard(txout.scriptPubKey, whichType, witnessEnabled)) {
            reason = "scriptpubkey";
            return false;
        }

        if (whichType == TX_NULL_DATA)
		{
			// SYSCOIN if not syscoin tx and opreturn size is bigger than maxcarrier bytes, return false
			// we need this because if it is a sys tx then we allow 75x maxcarrier bytes.
			if(tx.nVersion != GetSyscoinTxVersion() && txout.scriptPubKey.size() > nMaxDatacarrierBytes)
			{
				reason = "scriptpubkey";
				return false;
			}

            nDataOut++;
		}
        else if ((whichType == TX_MULTISIG) && (!fIsBareMultisigStd)) {
            reason = "bare-multisig";
            return false;
        } else if (txout.IsDust(::minRelayTxFee)) {
            reason = "dust";
            return false;
        }
    }

    // only one OP_RETURN txout is permitted
    if (nDataOut > 1) {
        reason = "multi-op-return";
        return false;
    }

    return true;
}

bool AreInputsStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs)
{
    if (tx.IsCoinBase())
        return true; // Coinbases don't use vin normally

    for (unsigned int i = 0; i < tx.vin.size(); i++)
    {
        const CTxOut& prev = mapInputs.GetOutputFor(tx.vin[i]);

        std::vector<std::vector<unsigned char> > vSolutions;
        txnouttype whichType;
        // get the scriptPubKey corresponding to this input:
        const CScript& prevScript = prev.scriptPubKey;
        if (!Solver(prevScript, whichType, vSolutions))
            return false;

        if (whichType == TX_SCRIPTHASH)
        {
            std::vector<std::vector<unsigned char> > stack;
            // convert the scriptSig into a stack, so we can inspect the redeemScript
            if (!EvalScript(stack, tx.vin[i].scriptSig, SCRIPT_VERIFY_NONE, BaseSignatureChecker(), SIGVERSION_BASE))
                return false;
            if (stack.empty())
                return false;
            CScript subscript(stack.back().begin(), stack.back().end());
            if (subscript.GetSigOpCount(true) > MAX_P2SH_SIGOPS) {
                return false;
            }
        }
    }

    return true;
}
bool IsWitnessStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs)
{
    if (tx.IsCoinBase())
        return true; // Coinbases are skipped

    for (unsigned int i = 0; i < tx.vin.size(); i++)
    {
        // We don't care if witness for this input is empty, since it must not be bloated.
        // If the script is invalid without witness, it would be caught sooner or later during validation.
        if (tx.wit.vtxinwit[i].IsNull())
            continue;

        const CTxOut &prev = mapInputs.GetOutputFor(tx.vin[i]);

        // get the scriptPubKey corresponding to this input:
        CScript prevScript = prev.scriptPubKey;

        if (prevScript.IsPayToScriptHash()) {
            std::vector <std::vector<unsigned char> > stack;
            // If the scriptPubKey is P2SH, we try to extract the redeemScript casually by converting the scriptSig
            // into a stack. We do not check IsPushOnly nor compare the hash as these will be done later anyway.
            // If the check fails at this stage, we know that this txid must be a bad one.
            if (!EvalScript(stack, tx.vin[i].scriptSig, SCRIPT_VERIFY_NONE, BaseSignatureChecker(), SIGVERSION_BASE))
                return false;
            if (stack.empty())
                return false;
            prevScript = CScript(stack.back().begin(), stack.back().end());
        }

        int witnessversion = 0;
        std::vector<unsigned char> witnessprogram;

        // Non-witness program must not be associated with any witness
        if (!prevScript.IsWitnessProgram(witnessversion, witnessprogram))
            return false;

        // Check P2WSH standard limits
        if (witnessversion == 0 && witnessprogram.size() == 32) {
            if (tx.wit.vtxinwit[i].scriptWitness.stack.back().size() > MAX_STANDARD_P2WSH_SCRIPT_SIZE)
                return false;
            size_t sizeWitnessStack = tx.wit.vtxinwit[i].scriptWitness.stack.size() - 1;
            if (sizeWitnessStack > MAX_STANDARD_P2WSH_STACK_ITEMS)
                return false;
            for (unsigned int j = 0; j < sizeWitnessStack; j++) {
                if (tx.wit.vtxinwit[i].scriptWitness.stack[j].size() > MAX_STANDARD_P2WSH_STACK_ITEM_SIZE)
                    return false;
            }
        }
    }
    return true;
}
unsigned int nBytesPerSigOp = DEFAULT_BYTES_PER_SIGOP;

int64_t GetVirtualTransactionSize(int64_t nWeight, int64_t nSigOpCost)
{
    return (std::max(nWeight, nSigOpCost * nBytesPerSigOp) + WITNESS_SCALE_FACTOR - 1) / WITNESS_SCALE_FACTOR;
}

int64_t GetVirtualTransactionSize(const CTransaction& tx, int64_t nSigOpCost)
{
    return GetVirtualTransactionSize(GetTransactionWeight(tx), nSigOpCost);
}
<commit_msg>fix version check<commit_after>// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2015 The Syscoin developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

// NOTE: This file is intended to be customised by the end user, and includes only local node policy logic

#include "policy/policy.h"

#include "main.h"
#include "tinyformat.h"
#include "util.h"
#include "utilstrencodings.h"

#include <boost/foreach.hpp>
// SYSCOIN need constant SYSCOIN_TX_VERSION
extern int GetSyscoinTxVersion();
    /**
     * Check transaction inputs to mitigate two
     * potential denial-of-service attacks:
     *
     * 1. scriptSigs with extra data stuffed into them,
     *    not consumed by scriptPubKey (or P2SH script)
     * 2. P2SH scripts with a crazy number of expensive
     *    CHECKSIG/CHECKMULTISIG operations
     *
     * Why bother? To avoid denial-of-service attacks; an attacker
     * can submit a standard HASH... OP_EQUAL transaction,
     * which will get accepted into blocks. The redemption
     * script can be anything; an attacker could use a very
     * expensive-to-check-upon-redemption script like:
     *   DUP CHECKSIG DROP ... repeated 100 times... OP_1
     */

bool IsStandard(const CScript& scriptPubKey, txnouttype& whichType, const bool witnessEnabled)
{
    std::vector<std::vector<unsigned char> > vSolutions;
    if (!Solver(scriptPubKey, whichType, vSolutions))
        return false;

    if (whichType == TX_MULTISIG)
    {
        unsigned char m = vSolutions.front()[0];
        unsigned char n = vSolutions.back()[0];
		// Support up to x-of-3 multisig txns as standard
        if (n < 1 || n > 3)
            return false;
        if (m < 1 || m > n)
            return false;
	// SYSCOIN check for size of sys tx, normal tx size is checked in isstandardtx now
    } else if (whichType == TX_NULL_DATA &&
               (!fAcceptDatacarrier || scriptPubKey.size() > nMaxDatacarrierBytes*75))
          return false;

    else if (!witnessEnabled && (whichType == TX_WITNESS_V0_KEYHASH || whichType == TX_WITNESS_V0_SCRIPTHASH))
        return false;

    return whichType != TX_NONSTANDARD;
}

bool IsStandardTx(const CTransaction& tx, std::string& reason, const bool witnessEnabled)
{
	// SYSCOIN check for syscoin or bitcoin tx
    if ((tx.nVersion > CTransaction::MAX_STANDARD_VERSION || tx.nVersion < 1) && tx.nVersion != GetSyscoinTxVersion()) {
        reason = "version";
        return false;
    }

    // Extremely large transactions with lots of inputs can cost the network
    // almost as much to process as they cost the sender in fees, because
    // computing signature hashes is O(ninputs*txsize). Limiting transactions
    // to MAX_STANDARD_TX_SIZE mitigates CPU exhaustion attacks.
    unsigned int sz = GetTransactionWeight(tx);
    if (sz >= MAX_STANDARD_TX_WEIGHT) {
        reason = "tx-size";
        return false;
    }

    BOOST_FOREACH(const CTxIn& txin, tx.vin)
    {
        // Biggest 'standard' txin is a 15-of-15 P2SH multisig with compressed
        // keys (remember the 520 byte limit on redeemScript size). That works
        // out to a (15*(33+1))+3=513 byte redeemScript, 513+1+15*(73+1)+3=1627
        // bytes of scriptSig, which we round off to 1650 bytes for some minor
        // future-proofing. That's also enough to spend a 20-of-20
        // CHECKMULTISIG scriptPubKey, though such a scriptPubKey is not
        // considered standard.
        if (txin.scriptSig.size() > 1650) {
            reason = "scriptsig-size";
            return false;
        }
        if (!txin.scriptSig.IsPushOnly()) {
            reason = "scriptsig-not-pushonly";
            return false;
        }
    }

    unsigned int nDataOut = 0;
    txnouttype whichType;
    BOOST_FOREACH(const CTxOut& txout, tx.vout) {
        if (!::IsStandard(txout.scriptPubKey, whichType, witnessEnabled)) {
            reason = "scriptpubkey";
            return false;
        }

        if (whichType == TX_NULL_DATA)
		{
			// SYSCOIN if not syscoin tx and opreturn size is bigger than maxcarrier bytes, return false
			// we need this because if it is a sys tx then we allow 75x maxcarrier bytes.
			if(tx.nVersion != GetSyscoinTxVersion() && txout.scriptPubKey.size() > nMaxDatacarrierBytes)
			{
				reason = "scriptpubkey";
				return false;
			}

            nDataOut++;
		}
        else if ((whichType == TX_MULTISIG) && (!fIsBareMultisigStd)) {
            reason = "bare-multisig";
            return false;
        } else if (txout.IsDust(::minRelayTxFee)) {
            reason = "dust";
            return false;
        }
    }

    // only one OP_RETURN txout is permitted
    if (nDataOut > 1) {
        reason = "multi-op-return";
        return false;
    }

    return true;
}

bool AreInputsStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs)
{
    if (tx.IsCoinBase())
        return true; // Coinbases don't use vin normally

    for (unsigned int i = 0; i < tx.vin.size(); i++)
    {
        const CTxOut& prev = mapInputs.GetOutputFor(tx.vin[i]);

        std::vector<std::vector<unsigned char> > vSolutions;
        txnouttype whichType;
        // get the scriptPubKey corresponding to this input:
        const CScript& prevScript = prev.scriptPubKey;
        if (!Solver(prevScript, whichType, vSolutions))
            return false;

        if (whichType == TX_SCRIPTHASH)
        {
            std::vector<std::vector<unsigned char> > stack;
            // convert the scriptSig into a stack, so we can inspect the redeemScript
            if (!EvalScript(stack, tx.vin[i].scriptSig, SCRIPT_VERIFY_NONE, BaseSignatureChecker(), SIGVERSION_BASE))
                return false;
            if (stack.empty())
                return false;
            CScript subscript(stack.back().begin(), stack.back().end());
            if (subscript.GetSigOpCount(true) > MAX_P2SH_SIGOPS) {
                return false;
            }
        }
    }

    return true;
}
bool IsWitnessStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs)
{
    if (tx.IsCoinBase())
        return true; // Coinbases are skipped

    for (unsigned int i = 0; i < tx.vin.size(); i++)
    {
        // We don't care if witness for this input is empty, since it must not be bloated.
        // If the script is invalid without witness, it would be caught sooner or later during validation.
        if (tx.wit.vtxinwit[i].IsNull())
            continue;

        const CTxOut &prev = mapInputs.GetOutputFor(tx.vin[i]);

        // get the scriptPubKey corresponding to this input:
        CScript prevScript = prev.scriptPubKey;

        if (prevScript.IsPayToScriptHash()) {
            std::vector <std::vector<unsigned char> > stack;
            // If the scriptPubKey is P2SH, we try to extract the redeemScript casually by converting the scriptSig
            // into a stack. We do not check IsPushOnly nor compare the hash as these will be done later anyway.
            // If the check fails at this stage, we know that this txid must be a bad one.
            if (!EvalScript(stack, tx.vin[i].scriptSig, SCRIPT_VERIFY_NONE, BaseSignatureChecker(), SIGVERSION_BASE))
                return false;
            if (stack.empty())
                return false;
            prevScript = CScript(stack.back().begin(), stack.back().end());
        }

        int witnessversion = 0;
        std::vector<unsigned char> witnessprogram;

        // Non-witness program must not be associated with any witness
        if (!prevScript.IsWitnessProgram(witnessversion, witnessprogram))
            return false;

        // Check P2WSH standard limits
        if (witnessversion == 0 && witnessprogram.size() == 32) {
            if (tx.wit.vtxinwit[i].scriptWitness.stack.back().size() > MAX_STANDARD_P2WSH_SCRIPT_SIZE)
                return false;
            size_t sizeWitnessStack = tx.wit.vtxinwit[i].scriptWitness.stack.size() - 1;
            if (sizeWitnessStack > MAX_STANDARD_P2WSH_STACK_ITEMS)
                return false;
            for (unsigned int j = 0; j < sizeWitnessStack; j++) {
                if (tx.wit.vtxinwit[i].scriptWitness.stack[j].size() > MAX_STANDARD_P2WSH_STACK_ITEM_SIZE)
                    return false;
            }
        }
    }
    return true;
}
unsigned int nBytesPerSigOp = DEFAULT_BYTES_PER_SIGOP;

int64_t GetVirtualTransactionSize(int64_t nWeight, int64_t nSigOpCost)
{
    return (std::max(nWeight, nSigOpCost * nBytesPerSigOp) + WITNESS_SCALE_FACTOR - 1) / WITNESS_SCALE_FACTOR;
}

int64_t GetVirtualTransactionSize(const CTransaction& tx, int64_t nSigOpCost)
{
    return GetVirtualTransactionSize(GetTransactionWeight(tx), nSigOpCost);
}
<|endoftext|>


<commit_before>#include "orrerybody.hpp"

namespace sim
{

orrery_body_vec_t  load_debugging_orrery()
{
  /*
    std::string  name,
    std::string  description,
    double       GM,
    double       radius,
    double       ra,
    double       dec,
    double       rotational_rate,
    double       orbit_radius,    // for the debugging version
    double       orbit_rate
  */

  orrery_body_vec_t orrery = {
    {
      "Star",
      "The center of the solar system",
      1,                // GM
      1,                // radius
      0.0, 0.0, 0.5,    // ra, dec, rotation
      0.0,              // orbit radius
      0.0               // orbital rate
    },
    {
      "Planet1",
      "The first warring clan",
      0.1,              // GM
      0.1,              // radius
      0.0, 0.0, 0.5,    // ra, dec, rotation
      1.0,              // orbit radius
      1.0               // orbital rate
    },
    {
      "Planet2",
      "The second warring clan",
      0.1,              // GM
      0.05,              // radius
      0.0, 0.0, 0.5,    // ra, dec, rotation
      2.0,              // orbit radius
      0.5               // orbital rate
    },
  };

  return orrery;
}

}<commit_msg>Test solarsystem has three planets marking out 1, 10 and 40 AU.<commit_after>#include "orrerybody.hpp"
#include "units.hpp"

namespace sim
{

orrery_body_vec_t  load_debugging_orrery()
{
  /*
    std::string  name,
    std::string  description,
    double       GM,
    double       radius,
    double       ra,
    double       dec,
    double       rotational_rate,
    double       orbit_radius,    // for the debugging version
    double       orbit_rate
  */

  orrery_body_vec_t orrery = {
    {
      "Star",
      "The center of the solar system",
      1,                // GM
      1,                // radius
      0.0, 0.0, 0.5,    // ra, dec, rotation
      0.0,              // orbit radius
      0.0               // orbital rate
    },
    {
      "Planet0",
      "A barren wasteland",
      1,                // GM
      1,                // radius
      0.0, 0.0, 0.5,    // ra, dec, rotation
      1.0_AU,              // orbit radius
      0.1               // orbital rate
    },
    {
      "Planet1",
      "The first warring clan",
      0.1,              // GM
      0.1,              // radius
      0.0, 0.0, 0.5,    // ra, dec, rotation
      10.0_AU,              // orbit radius
      0.05               // orbital rate
    },
    {
      "Planet2",
      "The second warring clan",
      0.1,              // GM
      0.05,              // radius
      0.0, 0.0, 0.5,    // ra, dec, rotation
      40.0_AU,              // orbit radius
      0.01               // orbital rate
    },
  };

  return orrery;
}

}<|endoftext|>


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

#include "desktop/win/dxgi_frame.h"

#include "base/logging.h"
#include "desktop/frame_aligned.h"
#include "desktop/shared_memory_frame.h"

namespace desktop {

DxgiFrame::DxgiFrame(std::shared_ptr<DxgiDuplicatorController> controller,
                     ipc::SharedMemoryFactory* shared_memory_factory)
    : context_(std::move(controller)),
      shared_memory_factory_(shared_memory_factory)
{
    // Nothing
}

DxgiFrame::~DxgiFrame() = default;

bool DxgiFrame::prepare(const Size& size, ScreenCapturer::ScreenId source_id)
{
    if (source_id != source_id_)
    {
        // Once the source has been changed, the entire source should be copied.
        source_id_ = source_id;
        context_.reset();
    }

    if (!last_frame_size_.has_value() || last_frame_size_ != size)
    {
        // Save the last frame size.
        last_frame_size_.emplace(size);

        // Once the output size changed, recreate the SharedFrame.
        frame_.reset();
    }

    if (!frame_)
    {
        std::unique_ptr<Frame> frame;

        if (shared_memory_factory_)
        {
            frame = SharedMemoryFrame::create(size, PixelFormat::ARGB(), shared_memory_factory_);
        }
        else
        {
            frame = FrameAligned::create(size, PixelFormat::ARGB(), 32);
        }

        if (!frame)
        {
            LOG(LS_WARNING) << "DxgiFrame cannot create a new DesktopFrame";
            return false;
        }

        const Size& frame_size = frame->size();

        // DirectX capturer won't paint each pixel in the frame due to its one
        // capturer per monitor design. So once the new frame is created, we should
        // clear it to avoid the legacy image to be remained on it. See
        // http://crbug.com/708766.
        DCHECK_EQ(frame->stride(), frame_size.width() * frame->format().bytesPerPixel());
        memset(frame->frameData(), 0, frame->stride() * frame_size.height());

        frame_ = SharedFrame::wrap(std::move(frame));
    }

    return !!frame_;
}

SharedFrame* DxgiFrame::frame() const
{
    DCHECK(frame_);
    return frame_.get();
}

DxgiFrame::Context* DxgiFrame::context()
{
    DCHECK(frame_);
    return &context_;
}

} // namespace desktop
<commit_msg>Reset frame when changing screen.<commit_after>//
// Aspia Project
// Copyright (C) 2020 Dmitry Chapyshev <dmitry@aspia.ru>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
//

#include "desktop/win/dxgi_frame.h"

#include "base/logging.h"
#include "desktop/frame_aligned.h"
#include "desktop/shared_memory_frame.h"

namespace desktop {

DxgiFrame::DxgiFrame(std::shared_ptr<DxgiDuplicatorController> controller,
                     ipc::SharedMemoryFactory* shared_memory_factory)
    : context_(std::move(controller)),
      shared_memory_factory_(shared_memory_factory)
{
    // Nothing
}

DxgiFrame::~DxgiFrame() = default;

bool DxgiFrame::prepare(const Size& size, ScreenCapturer::ScreenId source_id)
{
    if (source_id != source_id_)
    {
        // Once the source has been changed, the entire source should be copied.
        source_id_ = source_id;
        context_.reset();
        frame_.reset();
    }

    if (!last_frame_size_.has_value() || last_frame_size_ != size)
    {
        // Save the last frame size.
        last_frame_size_.emplace(size);

        // Once the output size changed, recreate the SharedFrame.
        frame_.reset();
    }

    if (!frame_)
    {
        std::unique_ptr<Frame> frame;

        if (shared_memory_factory_)
        {
            frame = SharedMemoryFrame::create(size, PixelFormat::ARGB(), shared_memory_factory_);
        }
        else
        {
            frame = FrameAligned::create(size, PixelFormat::ARGB(), 32);
        }

        if (!frame)
        {
            LOG(LS_WARNING) << "DxgiFrame cannot create a new DesktopFrame";
            return false;
        }

        const Size& frame_size = frame->size();

        // DirectX capturer won't paint each pixel in the frame due to its one
        // capturer per monitor design. So once the new frame is created, we should
        // clear it to avoid the legacy image to be remained on it. See
        // http://crbug.com/708766.
        DCHECK_EQ(frame->stride(), frame_size.width() * frame->format().bytesPerPixel());
        memset(frame->frameData(), 0, frame->stride() * frame_size.height());

        frame_ = SharedFrame::wrap(std::move(frame));
    }

    return !!frame_;
}

SharedFrame* DxgiFrame::frame() const
{
    DCHECK(frame_);
    return frame_.get();
}

DxgiFrame::Context* DxgiFrame::context()
{
    DCHECK(frame_);
    return &context_;
}

} // namespace desktop
<|endoftext|>


<commit_before>#include "EBCReader.h"
#include "TransparencyGroup.h"
#include "DepthPeeling.h"
#include <cstdio>
#include <sstream>
#include <osg/LightModel>
#include <osgGA/StateSetManipulator>
#include <osgDB/ReadFile>
#include <osgDB/WriteFile>
#include <osgViewer/Viewer>
#include <osgViewer/ViewerEventHandlers>
#include <string.h>
typedef std::vector<std::string> EBCFiles;

#define HELP_ARGS(args) args.getApplicationUsage()->write( \
	osg::notify(osg::NOTICE), \
	osg::ApplicationUsage::COMMAND_LINE_OPTION \
)

class EventHandler: public osgGA::GUIEventHandler {
public:
	EventHandler(osgtt::TransparencyGroup* group):
	_group(group) {
	}

	virtual bool handle(
		const osgGA::GUIEventAdapter& gea,
		osgGA::GUIActionAdapter&	  gaa,
		osg::Object*				  obj,
		osg::NodeVisitor*			  nv
	) {
		if(!_group) return false;

		osgtt::DepthPeeling* dp = _group->getDepthPeeling();

		if(!dp) return false;

		if(gea.getEventType() == osgGA::GUIEventAdapter::RESIZE) {
			unsigned int ww = gea.getWindowWidth();
			unsigned int wh = gea.getWindowHeight();

			dp->resize(ww, wh);

			return true;
		}

		if(gea.getEventType() == osgGA::GUIEventAdapter::KEYDOWN) {
			int key = gea.getKey();

			if(key == 'q') {
				dp->setNumPasses(dp->getNumPasses() + 1);
				printf("number of passes: %d\n",dp->getNumPasses());
			}

			else if(key == 'w') dp->setNumPasses(dp->getNumPasses() - 1);

			else if(key == 'a') dp->setOffsetValue(dp->getOffsetValue() + 1);

			else if(key == 's') dp->setOffsetValue(dp->getOffsetValue() - 1);

			else if(key == 'z') _group->setTransparencyMode(osgtt::TransparencyGroup::DEPTH_SORTED_BIN);

			else if(key == 'x') _group->setTransparencyMode(osgtt::TransparencyGroup::DEPTH_PEELING);

			else if(key == 'c') _group->setTransparencyMode(osgtt::TransparencyGroup::DELAYED_BLEND);

			else if(key == 'v') _group->setTransparencyMode(osgtt::TransparencyGroup::NO_TRANSPARENCY);

			else return false;

			return true;
		}

		return false;
	}

protected:
	osg::ref_ptr<osgtt::TransparencyGroup> _group;
};

int main(int argc, char** argv) {
    osg::ArgumentParser args(&argc, argv);
    args.getApplicationUsage()->setCommandLineUsage(args.getApplicationName() + " <Input file>");

    while(args.read("--help")) {
        HELP_ARGS(args);

        return 0;
    }

    if(args.argc() != 2) {
        HELP_ARGS(args);
        return 1;
    }

    char buff[1024];
    FILE* fp = std::fopen(args[1], "r");
    char* ptr = 0;
    if (!fp) {
        printf("can not open file: %s\n",args[1]);
        return 0;
    }

    // Create a Reader object and a Viewer; begin constructing our scene.
    osgtt::EBCReader reader;
    ptr = std::fgets(buff,1024, fp);
    std::string crd;
    sscanf(buff, "%s", &crd);

    EBCFiles ebcFiles;
    osg::ref_ptr<osg::Vec4Array> Color = new osg::Vec4Array;
    osgtt::TransparencyGroup* group = new osgtt::TransparencyGroup();
    std::vector<int> side_flag;

    char	*p;
    char	*q;
    while((ptr = std::fgets(buff, 1024, fp))) {
        p = buff;
        /* strip any space,# or new line */
        if ((q = strchr(p,' ')) != NULL ||(q = strchr(p,'#')) != NULL ||(q = strchr(p,'\n'))!= NULL )
            *q = '\0';
        ebcFiles.push_back(buff);

        ptr = std::fgets(buff, 1024, fp);
        int flag;
        sscanf(buff, "%d", &flag);
        side_flag.push_back(flag);

        ptr = std::fgets(buff, 1024, fp);
        float alpha;
        sscanf(buff, "%f", &alpha);

        ptr = std::fgets(buff, 1024, fp);
        float r,g,b;
        sscanf(buff, "%f %f %f", &r,&g,&b);
        Color->push_back( osg::Vec4( r,g,b,alpha ) );
    }
    std::fclose(fp);

    if(!reader.setCRDFile(crd)) {
        OSG_FATAL << "Couldn't load CRD file '" << crd << "'; fatal." << std::endl;
        return 2;
    }

    int id = 0;
    // Iterate over all the EBC files and add them to our group.
    for(EBCFiles::iterator i = ebcFiles.begin(); i != ebcFiles.end(); i++) {
        osgtt::EBCNode* node = reader.readEBCFile(*i, osg::PrimitiveSet::TRIANGLES);
        osg::Vec4 color = (*Color)[id];
        int flag = (side_flag)[id];

        printf("%s\n",(*i).c_str());

        if (flag) printf("single-sided\n");
        else printf("double-sided\n");

        printf("color %f %f %f %f\n",color.x(),color.y(),color.z(), color.w());

        if(color.w()<1){
            group->addChild(node, true); // true = render as transparent
        }
        else{
            group->addChild(node, false); // false = hint that it's not transparent
        }
        node->setColor(color);
        id++;
    }
    // Set a two-sided FFP LightModel.
    osg::StateSet*	 stateSet	= group->getOrCreateStateSet();
    osg::LightModel* lightModel = new osg::LightModel();

    lightModel->setTwoSided(true);

    stateSet->setAttribute(lightModel);

    osgViewer::Viewer viewer;

    // eliminate callback-related crash on exit
    viewer.setThreadingModel(osgViewer::ViewerBase::SingleThreaded);

    group->setDepthPeeling(new osgtt::DepthPeeling(512, 512));
    group->setTransparencyMode(osgtt::TransparencyGroup::DEPTH_PEELING);
    group->setName("TransparencyGroup");

    viewer.addEventHandler(new EventHandler(group));
    viewer.setSceneData(group);
    viewer.setUpViewInWindow(50, 50, 512, 512);
    viewer.getCamera()->setComputeNearFarMode(osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR);

    return viewer.run();
}

<commit_msg>Switches from std::string to char[] for crd filename.<commit_after>#include "EBCReader.h"
#include "TransparencyGroup.h"
#include "DepthPeeling.h"
#include <cstdio>
#include <sstream>
#include <osg/LightModel>
#include <osgGA/StateSetManipulator>
#include <osgDB/ReadFile>
#include <osgDB/WriteFile>
#include <osgViewer/Viewer>
#include <osgViewer/ViewerEventHandlers>
#include <string.h>
typedef std::vector<std::string> EBCFiles;

#define HELP_ARGS(args) args.getApplicationUsage()->write( \
	osg::notify(osg::NOTICE), \
	osg::ApplicationUsage::COMMAND_LINE_OPTION \
)

class EventHandler: public osgGA::GUIEventHandler {
public:
	EventHandler(osgtt::TransparencyGroup* group):
	_group(group) {
	}

	virtual bool handle(
		const osgGA::GUIEventAdapter& gea,
		osgGA::GUIActionAdapter&	  gaa,
		osg::Object*				  obj,
		osg::NodeVisitor*			  nv
	) {
		if(!_group) return false;

		osgtt::DepthPeeling* dp = _group->getDepthPeeling();

		if(!dp) return false;

		if(gea.getEventType() == osgGA::GUIEventAdapter::RESIZE) {
			unsigned int ww = gea.getWindowWidth();
			unsigned int wh = gea.getWindowHeight();

			dp->resize(ww, wh);

			return true;
		}

		if(gea.getEventType() == osgGA::GUIEventAdapter::KEYDOWN) {
			int key = gea.getKey();

			if(key == 'q') {
				dp->setNumPasses(dp->getNumPasses() + 1);
				printf("number of passes: %d\n",dp->getNumPasses());
			}

			else if(key == 'w') dp->setNumPasses(dp->getNumPasses() - 1);

			else if(key == 'a') dp->setOffsetValue(dp->getOffsetValue() + 1);

			else if(key == 's') dp->setOffsetValue(dp->getOffsetValue() - 1);

			else if(key == 'z') _group->setTransparencyMode(osgtt::TransparencyGroup::DEPTH_SORTED_BIN);

			else if(key == 'x') _group->setTransparencyMode(osgtt::TransparencyGroup::DEPTH_PEELING);

			else if(key == 'c') _group->setTransparencyMode(osgtt::TransparencyGroup::DELAYED_BLEND);

			else if(key == 'v') _group->setTransparencyMode(osgtt::TransparencyGroup::NO_TRANSPARENCY);

			else return false;

			return true;
		}

		return false;
	}

protected:
	osg::ref_ptr<osgtt::TransparencyGroup> _group;
};

int main(int argc, char** argv) {
    osg::ArgumentParser args(&argc, argv);
    args.getApplicationUsage()->setCommandLineUsage(args.getApplicationName() + " <Input file>");

    while(args.read("--help")) {
        HELP_ARGS(args);

        return 0;
    }

    if(args.argc() != 2) {
        HELP_ARGS(args);
        return 1;
    }

    char buff[1024];
    FILE* fp = std::fopen(args[1], "r");
    char* ptr = 0;
    if (!fp) {
        printf("can not open file: %s\n",args[1]);
        return 0;
    }

    // Create a Reader object and a Viewer; begin constructing our scene.
    osgtt::EBCReader reader;
    ptr = std::fgets(buff,1024, fp);
    char crd[1024];
    sscanf(buff, "%s", &crd);

    EBCFiles ebcFiles;
    osg::ref_ptr<osg::Vec4Array> Color = new osg::Vec4Array;
    osgtt::TransparencyGroup* group = new osgtt::TransparencyGroup();
    std::vector<int> side_flag;

    char	*p;
    char	*q;
    while((ptr = std::fgets(buff, 1024, fp))) {
        p = buff;
        /* strip any space,# or new line */
        if ((q = strchr(p,' ')) != NULL ||(q = strchr(p,'#')) != NULL ||(q = strchr(p,'\n'))!= NULL )
            *q = '\0';
        ebcFiles.push_back(buff);

        ptr = std::fgets(buff, 1024, fp);
        int flag;
        sscanf(buff, "%d", &flag);
        side_flag.push_back(flag);

        ptr = std::fgets(buff, 1024, fp);
        float alpha;
        sscanf(buff, "%f", &alpha);

        ptr = std::fgets(buff, 1024, fp);
        float r,g,b;
        sscanf(buff, "%f %f %f", &r,&g,&b);
        Color->push_back( osg::Vec4( r,g,b,alpha ) );
    }
    std::fclose(fp);

    if(!reader.setCRDFile(crd)) {
        OSG_FATAL << "Couldn't load CRD file '" << crd << "'; fatal." << std::endl;
        return 2;
    }

    int id = 0;
    // Iterate over all the EBC files and add them to our group.
    for(EBCFiles::iterator i = ebcFiles.begin(); i != ebcFiles.end(); i++) {
        osgtt::EBCNode* node = reader.readEBCFile(*i, osg::PrimitiveSet::TRIANGLES);
        osg::Vec4 color = (*Color)[id];
        int flag = (side_flag)[id];

        printf("%s\n",(*i).c_str());

        if (flag) printf("single-sided\n");
        else printf("double-sided\n");

        printf("color %f %f %f %f\n",color.x(),color.y(),color.z(), color.w());

        if(color.w()<1){
            group->addChild(node, true); // true = render as transparent
        }
        else{
            group->addChild(node, false); // false = hint that it's not transparent
        }
        node->setColor(color);
        id++;
    }
    // Set a two-sided FFP LightModel.
    osg::StateSet*	 stateSet	= group->getOrCreateStateSet();
    osg::LightModel* lightModel = new osg::LightModel();

    lightModel->setTwoSided(true);

    stateSet->setAttribute(lightModel);

    osgViewer::Viewer viewer;

    // eliminate callback-related crash on exit
    viewer.setThreadingModel(osgViewer::ViewerBase::SingleThreaded);

    group->setDepthPeeling(new osgtt::DepthPeeling(512, 512));
    group->setTransparencyMode(osgtt::TransparencyGroup::DEPTH_PEELING);
    group->setName("TransparencyGroup");

    viewer.addEventHandler(new EventHandler(group));
    viewer.setSceneData(group);
    viewer.setUpViewInWindow(50, 50, 512, 512);
    viewer.getCamera()->setComputeNearFarMode(osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR);

    return viewer.run();
}

<|endoftext|>


<commit_before>/***************************************************************************//**
 * @file optimisation.hpp
 *
 * Minimisation object for performing optimisation algorithm from description
 * in Cmiss_optimisation.
 *
 * @see-also api/cmiss_optimisation.h
 *
 */
/* ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (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.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is cmgui.
 *
 * The Initial Developer of the Original Code is
 * Auckland Uniservices Ltd, Auckland, New Zealand.
 * Portions created by the Initial Developer are Copyright (C) 2005
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *
 * Alternatively, the contents of this file may be used under the terms of
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 * in which case the provisions of the GPL or the LGPL are applicable instead
 * of those above. If you wish to allow use of your version of this file only
 * under the terms of either the GPL or the LGPL, and not to allow others to
 * use your version of this file under the terms of the MPL, indicate your
 * decision by deleting the provisions above and replace them with the notice
 * and other provisions required by the GPL or the LGPL. If you do not delete
 * the provisions above, a recipient may use your version of this file under
 * the terms of any one of the MPL, the GPL or the LGPL.
 *
 * ***** END LICENSE BLOCK ***** */

#ifndef OPTIMISATION_HPP_
#define OPTIMISATION_HPP_

#include <vector>
#include "minimise/cmiss_optimisation_private.hpp"

class ObjectiveFieldData
{
public:
	Cmiss_field_id field;
	int numComponents;
	int numTerms;
	int bufferSize;
	FE_value *buffer;

	ObjectiveFieldData(Cmiss_field_id objectiveField) :
		field(Cmiss_field_access(objectiveField)),
		numComponents(Cmiss_field_get_number_of_components(field)),
		numTerms(0),
		bufferSize(0),
		buffer(0)
	{
	}

	~ObjectiveFieldData()
	{
		Cmiss_field_destroy(&field);
		delete[] buffer;
	}

	int prepareTerms();
};

typedef std::vector<Cmiss_field_id> FieldVector;
typedef std::vector<ObjectiveFieldData*> ObjectiveFieldDataVector;

class Minimisation
{
private:
	Cmiss_optimisation& optimisation;

public:
	Cmiss_field_module_id field_module;
	Cmiss_field_cache_id field_cache;
	FE_value current_time;
	int total_dof;
	ObjectiveFieldDataVector objectiveFields;

private:
	FE_value **dof_storage_array;
	FE_value *dof_initial_values;
	FieldVector independentFields;
	int totalObjectiveFieldComponents;
	int totalLeastSquaresTerms;
	FE_value *objectiveValues;

public:
	Minimisation(Cmiss_optimisation& optimisation) :
		optimisation(optimisation)
	{
		field_module = optimisation.fieldModule;
		field_cache = Cmiss_field_module_create_cache(field_module);
		current_time = 0.0;
		total_dof = 0;
		dof_storage_array = static_cast<FE_value**> (NULL);
		dof_initial_values = static_cast<FE_value*> (NULL);
		for (FieldList::iterator iter = optimisation.independentFields.begin();
			iter != optimisation.independentFields.end(); ++iter)
		{
			Cmiss_field_access(*iter);
			independentFields.push_back(*iter);
		}
		totalObjectiveFieldComponents = 0;
		for (FieldList::iterator iter = optimisation.objectiveFields.begin();
			iter != optimisation.objectiveFields.end(); ++iter)
		{
			Cmiss_field_id objectiveField = *iter;
			totalObjectiveFieldComponents += Cmiss_field_get_number_of_components(objectiveField);
			objectiveFields.push_back(new ObjectiveFieldData(objectiveField));
		}
		objectiveValues = new FE_value[totalObjectiveFieldComponents];
		totalLeastSquaresTerms = 0;
	};

	~Minimisation();

	/** Prepare data structures for optimisation
	 * @return  1 on success, 0 on failure */
	int prepareOptimisation();

	/** Perform optimisation until ending condition met or error
	 * Must have successfully called prepareOptimisation() first.
	 * @return  1 on success, 0 on failure */
	int runOptimisation();

	FE_value *get_dof_initial_values()
	{
		return dof_initial_values;
	}

	inline void set_dof_value(int dof_index, FE_value new_value)
	{
		*dof_storage_array[dof_index] = new_value;
	}

	void list_dof_values();

	void invalidate_independent_field_caches();

	/** @return  1 on success, 0 on failure */
	int evaluate_objective_function(FE_value *valueAddress);

private:

	int construct_dof_arrays();

	void touch_independent_fields();

	int minimise_QN();

	int minimise_LSQN();

};

#endif /* OPTIMISATION_HPP_ */
<commit_msg>Fix bug of destroying field module without first accessing it in optimisation object. https://tracker.physiomeproject.org/show_bug.cgi?id=1844<commit_after>/***************************************************************************//**
 * @file optimisation.hpp
 *
 * Minimisation object for performing optimisation algorithm from description
 * in Cmiss_optimisation.
 *
 * @see-also api/cmiss_optimisation.h
 *
 */
/* ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (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.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is cmgui.
 *
 * The Initial Developer of the Original Code is
 * Auckland Uniservices Ltd, Auckland, New Zealand.
 * Portions created by the Initial Developer are Copyright (C) 2005
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *
 * Alternatively, the contents of this file may be used under the terms of
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 * in which case the provisions of the GPL or the LGPL are applicable instead
 * of those above. If you wish to allow use of your version of this file only
 * under the terms of either the GPL or the LGPL, and not to allow others to
 * use your version of this file under the terms of the MPL, indicate your
 * decision by deleting the provisions above and replace them with the notice
 * and other provisions required by the GPL or the LGPL. If you do not delete
 * the provisions above, a recipient may use your version of this file under
 * the terms of any one of the MPL, the GPL or the LGPL.
 *
 * ***** END LICENSE BLOCK ***** */

#ifndef OPTIMISATION_HPP_
#define OPTIMISATION_HPP_

#include <vector>
#include "minimise/cmiss_optimisation_private.hpp"

class ObjectiveFieldData
{
public:
	Cmiss_field_id field;
	int numComponents;
	int numTerms;
	int bufferSize;
	FE_value *buffer;

	ObjectiveFieldData(Cmiss_field_id objectiveField) :
		field(Cmiss_field_access(objectiveField)),
		numComponents(Cmiss_field_get_number_of_components(field)),
		numTerms(0),
		bufferSize(0),
		buffer(0)
	{
	}

	~ObjectiveFieldData()
	{
		Cmiss_field_destroy(&field);
		delete[] buffer;
	}

	int prepareTerms();
};

typedef std::vector<Cmiss_field_id> FieldVector;
typedef std::vector<ObjectiveFieldData*> ObjectiveFieldDataVector;

class Minimisation
{
private:
	Cmiss_optimisation& optimisation;

public:
	Cmiss_field_module_id field_module;
	Cmiss_field_cache_id field_cache;
	FE_value current_time;
	int total_dof;
	ObjectiveFieldDataVector objectiveFields;

private:
	FE_value **dof_storage_array;
	FE_value *dof_initial_values;
	FieldVector independentFields;
	int totalObjectiveFieldComponents;
	int totalLeastSquaresTerms;
	FE_value *objectiveValues;

public:
	Minimisation(Cmiss_optimisation& optimisation) :
		optimisation(optimisation)
	{
		field_module = Cmiss_field_module_access(optimisation.fieldModule);
		field_cache = Cmiss_field_module_create_cache(field_module);
		current_time = 0.0;
		total_dof = 0;
		dof_storage_array = static_cast<FE_value**> (NULL);
		dof_initial_values = static_cast<FE_value*> (NULL);
		for (FieldList::iterator iter = optimisation.independentFields.begin();
			iter != optimisation.independentFields.end(); ++iter)
		{
			Cmiss_field_access(*iter);
			independentFields.push_back(*iter);
		}
		totalObjectiveFieldComponents = 0;
		for (FieldList::iterator iter = optimisation.objectiveFields.begin();
			iter != optimisation.objectiveFields.end(); ++iter)
		{
			Cmiss_field_id objectiveField = *iter;
			totalObjectiveFieldComponents += Cmiss_field_get_number_of_components(objectiveField);
			objectiveFields.push_back(new ObjectiveFieldData(objectiveField));
		}
		objectiveValues = new FE_value[totalObjectiveFieldComponents];
		totalLeastSquaresTerms = 0;
	};

	~Minimisation();

	/** Prepare data structures for optimisation
	 * @return  1 on success, 0 on failure */
	int prepareOptimisation();

	/** Perform optimisation until ending condition met or error
	 * Must have successfully called prepareOptimisation() first.
	 * @return  1 on success, 0 on failure */
	int runOptimisation();

	FE_value *get_dof_initial_values()
	{
		return dof_initial_values;
	}

	inline void set_dof_value(int dof_index, FE_value new_value)
	{
		*dof_storage_array[dof_index] = new_value;
	}

	void list_dof_values();

	void invalidate_independent_field_caches();

	/** @return  1 on success, 0 on failure */
	int evaluate_objective_function(FE_value *valueAddress);

private:

	int construct_dof_arrays();

	void touch_independent_fields();

	int minimise_QN();

	int minimise_LSQN();

};

#endif /* OPTIMISATION_HPP_ */
<|endoftext|>


<commit_before>/*
* Public Key Base
* (C) 1999-2010 Jack Lloyd
*
* Distributed under the terms of the Botan license
*/

#include <botan/pubkey.h>
#include <botan/der_enc.h>
#include <botan/ber_dec.h>
#include <botan/bigint.h>
#include <botan/parsing.h>
#include <botan/libstate.h>
#include <botan/engine.h>
#include <botan/lookup.h>
#include <botan/internal/bit_ops.h>
#include <memory>

namespace Botan {

/*
* PK_Encryptor_EME Constructor
*/
PK_Encryptor_EME::PK_Encryptor_EME(const Public_Key& key,
                                   const std::string& eme_name)
   {
   Algorithm_Factory::Engine_Iterator i(global_state().algorithm_factory());

   while(const Engine* engine = i.next())
      {
      op = engine->get_encryption_op(key);
      if(op)
         break;
      }

   if(!op)
      throw Lookup_Error("PK_Encryptor_EME: No working engine for " +
                         key.algo_name());

   eme = get_eme(eme_name);
   }

/*
* Encrypt a message
*/
SecureVector<byte>
PK_Encryptor_EME::enc(const byte msg[],
                      u32bit length,
                      RandomNumberGenerator& rng) const
   {
   SecureVector<byte> message;
   if(eme)
      message = eme->encode(msg, length, op->max_input_bits(), rng);
   else
      message.set(msg, length);

   if(8*(message.size() - 1) + high_bit(message[0]) > op->max_input_bits())
      throw Invalid_Argument("PK_Encryptor_EME: Input is too large");

   return op->encrypt(message, message.size(), rng);
   }

/*
* Return the max size, in bytes, of a message
*/
u32bit PK_Encryptor_EME::maximum_input_size() const
   {
   if(!eme)
      return (op->max_input_bits() / 8);
   else
      return eme->maximum_input_size(op->max_input_bits());
   }

/*
* PK_Decryptor_EME Constructor
*/
PK_Decryptor_EME::PK_Decryptor_EME(const Private_Key& key,
                                   const std::string& eme_name)
   {
   Algorithm_Factory::Engine_Iterator i(global_state().algorithm_factory());

   while(const Engine* engine = i.next())
      {
      op = engine->get_decryption_op(key);
      if(op)
         break;
      }

   if(!op)
      throw Lookup_Error("PK_Decryptor_EME: No working engine for " +
                         key.algo_name());

   eme = get_eme(eme_name);
   }

/*
* Decrypt a message
*/
SecureVector<byte> PK_Decryptor_EME::dec(const byte msg[],
                                         u32bit length) const
   {
   try {
      SecureVector<byte> decrypted = op->decrypt(msg, length);
      if(eme)
         return eme->decode(decrypted, op->max_input_bits());
      else
         return decrypted;
      }
   catch(Invalid_Argument)
      {
      throw Decoding_Error("PK_Decryptor_EME: Input is invalid");
      }
   }

/*
* PK_Signer Constructor
*/
PK_Signer::PK_Signer(const Private_Key& key,
                     const std::string& emsa_name,
                     Signature_Format format,
                     Fault_Protection prot)
   {
   Algorithm_Factory::Engine_Iterator i(global_state().algorithm_factory());

   op = 0;
   verify_op = 0;

   while(const Engine* engine = i.next())
      {
      if(!op)
         op = engine->get_signature_op(key);

      if(!verify_op && prot == ENABLE_FAULT_PROTECTION)
         verify_op = engine->get_verify_op(key);

      if(op && (verify_op || prot == DISABLE_FAULT_PROTECTION))
         break;
      }

   if(!op || (!verify_op && prot == ENABLE_FAULT_PROTECTION))
      throw Lookup_Error("PK_Signer: No working engine for " +
                         key.algo_name());

   emsa = get_emsa(emsa_name);
   sig_format = format;
   }

/*
* Sign a message
*/
SecureVector<byte> PK_Signer::sign_message(const byte msg[], u32bit length,
                                           RandomNumberGenerator& rng)
   {
   update(msg, length);
   return signature(rng);
   }

/*
* Add more to the message to be signed
*/
void PK_Signer::update(const byte in[], u32bit length)
   {
   emsa->update(in, length);
   }

/*
* Check the signature we just created, to help prevent fault attacks
*/
bool PK_Signer::self_test_signature(const MemoryRegion<byte>& msg,
                                    const MemoryRegion<byte>& sig) const
   {
   if(verify_op->with_recovery())
      {
      SecureVector<byte> recovered =
         verify_op->verify_mr(&sig[0], sig.size());

      if(msg.size() > recovered.size())
         {
         u32bit extra_0s = msg.size() - recovered.size();

         for(size_t i = 0; i != extra_0s; ++i)
            if(msg[i] != 0)
               return false;

         return same_mem(&msg[extra_0s], &recovered[0], recovered.size());
         }

      return (recovered == msg);
      }
   else
      return verify_op->verify(&msg[0], msg.size(),
                               &sig[0], sig.size());
   }

/*
* Create a signature
*/
SecureVector<byte> PK_Signer::signature(RandomNumberGenerator& rng)
   {
   SecureVector<byte> encoded = emsa->encoding_of(emsa->raw_data(),
                                                  op->max_input_bits(),
                                                  rng);

   SecureVector<byte> plain_sig = op->sign(encoded, encoded.size(), rng);

   if(verify_op && !self_test_signature(encoded, plain_sig))
      throw Internal_Error("PK_Signer consistency check failed");

   if(op->message_parts() == 1 || sig_format == IEEE_1363)
      return plain_sig;

   if(sig_format == DER_SEQUENCE)
      {
      if(plain_sig.size() % op->message_parts())
         throw Encoding_Error("PK_Signer: strange signature size found");
      const u32bit SIZE_OF_PART = plain_sig.size() / op->message_parts();

      std::vector<BigInt> sig_parts(op->message_parts());
      for(u32bit j = 0; j != sig_parts.size(); ++j)
         sig_parts[j].binary_decode(plain_sig + SIZE_OF_PART*j, SIZE_OF_PART);

      return DER_Encoder()
         .start_cons(SEQUENCE)
            .encode_list(sig_parts)
         .end_cons()
      .get_contents();
      }
   else
      throw Encoding_Error("PK_Signer: Unknown signature format " +
                           to_string(sig_format));
   }

/*
* PK_Verifier Constructor
*/
PK_Verifier::PK_Verifier(const Public_Key& key,
                         const std::string& emsa_name,
                         Signature_Format format)
   {
   Algorithm_Factory::Engine_Iterator i(global_state().algorithm_factory());

   while(const Engine* engine = i.next())
      {
      op = engine->get_verify_op(key);
      if(op)
         break;
      }

   if(!op)
      throw Lookup_Error("PK_Verifier: No working engine for " +
                         key.algo_name());

   emsa = get_emsa(emsa_name);
   sig_format = format;
   }

/*
* Set the signature format
*/
void PK_Verifier::set_input_format(Signature_Format format)
   {
   if(op->message_parts() == 1 && format != IEEE_1363)
      throw Invalid_State("PK_Verifier: This algorithm always uses IEEE 1363");
   sig_format = format;
   }

/*
* Verify a message
*/
bool PK_Verifier::verify_message(const byte msg[], u32bit msg_length,
                                 const byte sig[], u32bit sig_length)
   {
   update(msg, msg_length);
   return check_signature(sig, sig_length);
   }

/*
* Append to the message
*/
void PK_Verifier::update(const byte in[], u32bit length)
   {
   emsa->update(in, length);
   }

/*
* Check a signature
*/
bool PK_Verifier::check_signature(const byte sig[], u32bit length)
   {
   try {
      if(sig_format == IEEE_1363)
         return validate_signature(emsa->raw_data(), sig, length);
      else if(sig_format == DER_SEQUENCE)
         {
         BER_Decoder decoder(sig, length);
         BER_Decoder ber_sig = decoder.start_cons(SEQUENCE);

         u32bit count = 0;
         SecureVector<byte> real_sig;
         while(ber_sig.more_items())
            {
            BigInt sig_part;
            ber_sig.decode(sig_part);
            real_sig.append(BigInt::encode_1363(sig_part,
                                                op->message_part_size()));
            ++count;
            }

         if(count != op->message_parts())
            throw Decoding_Error("PK_Verifier: signature size invalid");

         return validate_signature(emsa->raw_data(),
                                   real_sig, real_sig.size());
         }
      else
         throw Decoding_Error("PK_Verifier: Unknown signature format " +
                              to_string(sig_format));
      }
   catch(Invalid_Argument) { return false; }
   }

/*
* Verify a signature
*/
bool PK_Verifier::validate_signature(const MemoryRegion<byte>& msg,
                                     const byte sig[], u32bit sig_len)
   {
   if(op->with_recovery())
      {
      SecureVector<byte> output_of_key = op->verify_mr(sig, sig_len);
      return emsa->verify(output_of_key, msg, op->max_input_bits());
      }
   else
      {
      Null_RNG rng;

      SecureVector<byte> encoded =
         emsa->encoding_of(msg, op->max_input_bits(), rng);

      return op->verify(encoded, encoded.size(), sig, sig_len);
      }
   }

/*
* PK_Key_Agreement Constructor
*/
PK_Key_Agreement::PK_Key_Agreement(const PK_Key_Agreement_Key& key,
                                   const std::string& kdf_name)
   {
   Algorithm_Factory::Engine_Iterator i(global_state().algorithm_factory());

   while(const Engine* engine = i.next())
      {
      op = engine->get_key_agreement_op(key);
      if(op)
         break;
      }

   if(!op)
      throw Lookup_Error("PK_Key_Agreement: No working engine for " +
                         key.algo_name());

   kdf = get_kdf(kdf_name);
   }

SymmetricKey PK_Key_Agreement::derive_key(u32bit key_len, const byte in[],
                                          u32bit in_len, const byte params[],
                                          u32bit params_len) const
   {
   SecureVector<byte> z = op->agree(in, in_len);

   if(!kdf)
      return z;

   return kdf->derive_key(key_len, z, params, params_len);
   }

}
<commit_msg>Don't call get_eme or get_kdf with name "Raw" (returns NULL); ideally would like to replace these functions with generic engine code instead of hardcoded lookup, and NULL return value would be impossible to disambiguate.<commit_after>/*
* Public Key Base
* (C) 1999-2010 Jack Lloyd
*
* Distributed under the terms of the Botan license
*/

#include <botan/pubkey.h>
#include <botan/der_enc.h>
#include <botan/ber_dec.h>
#include <botan/bigint.h>
#include <botan/parsing.h>
#include <botan/libstate.h>
#include <botan/engine.h>
#include <botan/lookup.h>
#include <botan/internal/bit_ops.h>
#include <memory>

namespace Botan {

/*
* PK_Encryptor_EME Constructor
*/
PK_Encryptor_EME::PK_Encryptor_EME(const Public_Key& key,
                                   const std::string& eme_name)
   {
   Algorithm_Factory::Engine_Iterator i(global_state().algorithm_factory());

   while(const Engine* engine = i.next())
      {
      op = engine->get_encryption_op(key);
      if(op)
         break;
      }

   if(!op)
      throw Lookup_Error("PK_Encryptor_EME: No working engine for " +
                         key.algo_name());

   eme = (eme_name == "Raw") ? 0 : get_eme(eme_name);
   }

/*
* Encrypt a message
*/
SecureVector<byte>
PK_Encryptor_EME::enc(const byte msg[],
                      u32bit length,
                      RandomNumberGenerator& rng) const
   {
   SecureVector<byte> message;
   if(eme)
      message = eme->encode(msg, length, op->max_input_bits(), rng);
   else
      message.set(msg, length);

   if(8*(message.size() - 1) + high_bit(message[0]) > op->max_input_bits())
      throw Invalid_Argument("PK_Encryptor_EME: Input is too large");

   return op->encrypt(message, message.size(), rng);
   }

/*
* Return the max size, in bytes, of a message
*/
u32bit PK_Encryptor_EME::maximum_input_size() const
   {
   if(!eme)
      return (op->max_input_bits() / 8);
   else
      return eme->maximum_input_size(op->max_input_bits());
   }

/*
* PK_Decryptor_EME Constructor
*/
PK_Decryptor_EME::PK_Decryptor_EME(const Private_Key& key,
                                   const std::string& eme_name)
   {
   Algorithm_Factory::Engine_Iterator i(global_state().algorithm_factory());

   while(const Engine* engine = i.next())
      {
      op = engine->get_decryption_op(key);
      if(op)
         break;
      }

   if(!op)
      throw Lookup_Error("PK_Decryptor_EME: No working engine for " +
                         key.algo_name());

   eme = (eme_name == "Raw") ? 0 : get_eme(eme_name);
   }

/*
* Decrypt a message
*/
SecureVector<byte> PK_Decryptor_EME::dec(const byte msg[],
                                         u32bit length) const
   {
   try {
      SecureVector<byte> decrypted = op->decrypt(msg, length);
      if(eme)
         return eme->decode(decrypted, op->max_input_bits());
      else
         return decrypted;
      }
   catch(Invalid_Argument)
      {
      throw Decoding_Error("PK_Decryptor_EME: Input is invalid");
      }
   }

/*
* PK_Signer Constructor
*/
PK_Signer::PK_Signer(const Private_Key& key,
                     const std::string& emsa_name,
                     Signature_Format format,
                     Fault_Protection prot)
   {
   Algorithm_Factory::Engine_Iterator i(global_state().algorithm_factory());

   op = 0;
   verify_op = 0;

   while(const Engine* engine = i.next())
      {
      if(!op)
         op = engine->get_signature_op(key);

      if(!verify_op && prot == ENABLE_FAULT_PROTECTION)
         verify_op = engine->get_verify_op(key);

      if(op && (verify_op || prot == DISABLE_FAULT_PROTECTION))
         break;
      }

   if(!op || (!verify_op && prot == ENABLE_FAULT_PROTECTION))
      throw Lookup_Error("PK_Signer: No working engine for " +
                         key.algo_name());

   emsa = get_emsa(emsa_name);
   sig_format = format;
   }

/*
* Sign a message
*/
SecureVector<byte> PK_Signer::sign_message(const byte msg[], u32bit length,
                                           RandomNumberGenerator& rng)
   {
   update(msg, length);
   return signature(rng);
   }

/*
* Add more to the message to be signed
*/
void PK_Signer::update(const byte in[], u32bit length)
   {
   emsa->update(in, length);
   }

/*
* Check the signature we just created, to help prevent fault attacks
*/
bool PK_Signer::self_test_signature(const MemoryRegion<byte>& msg,
                                    const MemoryRegion<byte>& sig) const
   {
   if(verify_op->with_recovery())
      {
      SecureVector<byte> recovered =
         verify_op->verify_mr(&sig[0], sig.size());

      if(msg.size() > recovered.size())
         {
         u32bit extra_0s = msg.size() - recovered.size();

         for(size_t i = 0; i != extra_0s; ++i)
            if(msg[i] != 0)
               return false;

         return same_mem(&msg[extra_0s], &recovered[0], recovered.size());
         }

      return (recovered == msg);
      }
   else
      return verify_op->verify(&msg[0], msg.size(),
                               &sig[0], sig.size());
   }

/*
* Create a signature
*/
SecureVector<byte> PK_Signer::signature(RandomNumberGenerator& rng)
   {
   SecureVector<byte> encoded = emsa->encoding_of(emsa->raw_data(),
                                                  op->max_input_bits(),
                                                  rng);

   SecureVector<byte> plain_sig = op->sign(encoded, encoded.size(), rng);

   if(verify_op && !self_test_signature(encoded, plain_sig))
      throw Internal_Error("PK_Signer consistency check failed");

   if(op->message_parts() == 1 || sig_format == IEEE_1363)
      return plain_sig;

   if(sig_format == DER_SEQUENCE)
      {
      if(plain_sig.size() % op->message_parts())
         throw Encoding_Error("PK_Signer: strange signature size found");
      const u32bit SIZE_OF_PART = plain_sig.size() / op->message_parts();

      std::vector<BigInt> sig_parts(op->message_parts());
      for(u32bit j = 0; j != sig_parts.size(); ++j)
         sig_parts[j].binary_decode(plain_sig + SIZE_OF_PART*j, SIZE_OF_PART);

      return DER_Encoder()
         .start_cons(SEQUENCE)
            .encode_list(sig_parts)
         .end_cons()
      .get_contents();
      }
   else
      throw Encoding_Error("PK_Signer: Unknown signature format " +
                           to_string(sig_format));
   }

/*
* PK_Verifier Constructor
*/
PK_Verifier::PK_Verifier(const Public_Key& key,
                         const std::string& emsa_name,
                         Signature_Format format)
   {
   Algorithm_Factory::Engine_Iterator i(global_state().algorithm_factory());

   while(const Engine* engine = i.next())
      {
      op = engine->get_verify_op(key);
      if(op)
         break;
      }

   if(!op)
      throw Lookup_Error("PK_Verifier: No working engine for " +
                         key.algo_name());

   emsa = get_emsa(emsa_name);
   sig_format = format;
   }

/*
* Set the signature format
*/
void PK_Verifier::set_input_format(Signature_Format format)
   {
   if(op->message_parts() == 1 && format != IEEE_1363)
      throw Invalid_State("PK_Verifier: This algorithm always uses IEEE 1363");
   sig_format = format;
   }

/*
* Verify a message
*/
bool PK_Verifier::verify_message(const byte msg[], u32bit msg_length,
                                 const byte sig[], u32bit sig_length)
   {
   update(msg, msg_length);
   return check_signature(sig, sig_length);
   }

/*
* Append to the message
*/
void PK_Verifier::update(const byte in[], u32bit length)
   {
   emsa->update(in, length);
   }

/*
* Check a signature
*/
bool PK_Verifier::check_signature(const byte sig[], u32bit length)
   {
   try {
      if(sig_format == IEEE_1363)
         return validate_signature(emsa->raw_data(), sig, length);
      else if(sig_format == DER_SEQUENCE)
         {
         BER_Decoder decoder(sig, length);
         BER_Decoder ber_sig = decoder.start_cons(SEQUENCE);

         u32bit count = 0;
         SecureVector<byte> real_sig;
         while(ber_sig.more_items())
            {
            BigInt sig_part;
            ber_sig.decode(sig_part);
            real_sig.append(BigInt::encode_1363(sig_part,
                                                op->message_part_size()));
            ++count;
            }

         if(count != op->message_parts())
            throw Decoding_Error("PK_Verifier: signature size invalid");

         return validate_signature(emsa->raw_data(),
                                   real_sig, real_sig.size());
         }
      else
         throw Decoding_Error("PK_Verifier: Unknown signature format " +
                              to_string(sig_format));
      }
   catch(Invalid_Argument) { return false; }
   }

/*
* Verify a signature
*/
bool PK_Verifier::validate_signature(const MemoryRegion<byte>& msg,
                                     const byte sig[], u32bit sig_len)
   {
   if(op->with_recovery())
      {
      SecureVector<byte> output_of_key = op->verify_mr(sig, sig_len);
      return emsa->verify(output_of_key, msg, op->max_input_bits());
      }
   else
      {
      Null_RNG rng;

      SecureVector<byte> encoded =
         emsa->encoding_of(msg, op->max_input_bits(), rng);

      return op->verify(encoded, encoded.size(), sig, sig_len);
      }
   }

/*
* PK_Key_Agreement Constructor
*/
PK_Key_Agreement::PK_Key_Agreement(const PK_Key_Agreement_Key& key,
                                   const std::string& kdf_name)
   {
   Algorithm_Factory::Engine_Iterator i(global_state().algorithm_factory());

   while(const Engine* engine = i.next())
      {
      op = engine->get_key_agreement_op(key);
      if(op)
         break;
      }

   if(!op)
      throw Lookup_Error("PK_Key_Agreement: No working engine for " +
                         key.algo_name());

   kdf = (kdf_name == "Raw") ? 0 : get_kdf(kdf_name);
   }

SymmetricKey PK_Key_Agreement::derive_key(u32bit key_len, const byte in[],
                                          u32bit in_len, const byte params[],
                                          u32bit params_len) const
   {
   SecureVector<byte> z = op->agree(in, in_len);

   if(!kdf)
      return z;

   return kdf->derive_key(key_len, z, params, params_len);
   }

}
<|endoftext|>


<commit_before>/*
    Persons Model Item
    Represents one person in the model
    Copyright (C) 2012  Martin Klapetek <martin.klapetek@gmail.com>

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

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

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

#include "personitem.h"
#include "contactitem.h"

#include <Nepomuk2/Vocabulary/PIMO>
#include <Nepomuk2/Vocabulary/NCO>
#include <Nepomuk2/Resource>
#include <Nepomuk2/Variant>
#include <Soprano/Vocabulary/NAO>
#include <KDebug>

PersonItem::PersonItem(const QUrl &personUri)
{
    setData(personUri, PersonsModel::UriRole);
}

PersonItem::PersonItem(const Nepomuk2::Resource &person)
{
    setData(person.uri(), PersonsModel::UriRole);
    setContacts(person.property(Nepomuk2::Vocabulary::PIMO::groundingOccurrence()).toUrlList());
    kDebug() << "new person" << text() << rowCount();
}

QVariant PersonItem::queryChildrenForRole(int role) const
{
    QVariant ret;
    for (int i = 0; i < rowCount(); i++) {
        QVariant value = child(i)->data(role);
        if (!value.isNull()) {
            ret = value;
            break;
        }
    }
    return ret;
}

QVariantList PersonItem::queryChildrenForRoleList(int role) const
{
    QVariantList ret;
    for (int i = 0; i < rowCount(); i++) {
        QVariant value = child(i)->data(role);
        if (value.type() == QVariant::List) {
            ret += value.toList();
        } else if (!value.isNull()) {
            ret += value;
        }
    }
    return ret;
}

QVariant PersonItem::data(int role) const
{
    if (role == PersonsModel::PresenceTypeRole) {
        QVariantList presences = queryChildrenForRoleList(PersonsModel::PresenceTypeRole);
        //FIXME? this is convenient, but in the worst case it has to go through the list 6x and do lots of comparisons
        //       possible optimization would be to go through it once and find the "most online value", this would need
        //       helper function with priorities for each string presence
        if (presences.contains("available")) {
            return QVariant("available");
        }
        if (presences.contains("away")) {
            return QVariant("away");
        }
        if (presences.contains("busy") || presences.contains("dnd")) {
            return QVariant("busy");
        }
        if (presences.contains("xa")) {
            return QVariant("xa");
        }
        if (presences.contains("unknown")) {
            return QVariant("unknown");
        }

        return QVariant("offline");
    }

    if (role == PersonsModel::UriRole) {
        //uri for PersonItem is set using setData(...), so we need to query it from there
        return QStandardItem::data(role);
    }

    QVariantList ret;
    for (int i = 0; i < rowCount(); i++) {
        QVariant value = child(i)->data(role);
        //these roles must return single QVariant
        if ((role == Qt::DisplayRole || role == Qt::DecorationRole || role == PersonsModel::ChildContactUriRole) && !value.isNull()) {
            return value;
        }
        if (value.type() == QVariant::List) {
            ret += value.toList();
        } else if (!value.isNull()) {
            ret += value;
        }
    }

    if (ret.isEmpty()) {
        //we need to return empty qvariant here, otherwise we'd get a qvariant
        //with empty qvariantlist, which would get parsed as non-empty qvariant
        return QVariant();
    }

    return ret;
}

void PersonItem::removeContacts(const QList<QUrl> &contacts)
{
    kDebug() << "remove contacts" << contacts;
    for (int i = 0; i < rowCount(); ) {
        QStandardItem *item = child(i);
        if (item && contacts.contains(item->data(PersonsModel::UriRole).toUrl())) {
            model()->invisibleRootItem()->appendRow(takeRow(i));
        } else {
            ++i;
        }
    }
    emitDataChanged();
}

void PersonItem::addContacts(const QList<QUrl> &_contacts)
{
    QList<QUrl> contacts(_contacts);
    //get existing child-contacts and remove them from the new ones
    QVariantList uris = queryChildrenForRoleList(PersonsModel::UriRole);
    foreach (const QVariant &uri, uris) {
        contacts.removeOne(uri.toUrl());
    }

    //query the model for the contacts, if they are present, then need to be just moved
    QList<QStandardItem*> toplevelContacts;
    foreach (const QUrl &uri, contacts) {
        QModelIndex contactIndex = qobject_cast<PersonsModel*>(model())->indexForUri(uri);
        if (contactIndex.isValid()) {
             toplevelContacts.append(qobject_cast<PersonsModel*>(model())->takeRow(contactIndex.row()));
        }
    }

    //append the moved contacts to this person and remove them from 'contacts'
    //so they are not added twice
    foreach (QStandardItem *contactItem, toplevelContacts) {
        //FIXME: we need to remove the fake person item here
        ContactItem *contact = dynamic_cast<ContactItem*>(contactItem);
        appendRow(contact);
        contacts.removeOne(contact->uri());
    }

    QList<ContactItem*> rows;
    foreach (const QUrl &uri, contacts) {
        ContactItem *item = new ContactItem(uri);
        item->loadData();
        appendRow(item);
    }
    emitDataChanged();
}

void PersonItem::setContacts(const QList<QUrl> &contacts)
{
    kDebug() << "set contacts" << contacts;
    if (contacts.isEmpty()) {
        //nothing to do here
        return;
    }

    if (hasChildren()) {
        QList<QUrl> toRemove;
        QVariantList uris = queryChildrenForRoleList(PersonsModel::UriRole);
        foreach (const QVariant &contact, uris) {
            if (!contacts.contains(contact.toUrl()))
                toRemove += contact.toUrl();
        }
        removeContacts(toRemove);
    }

    QList<QUrl> toAdd;
    foreach (const QUrl &contact, contacts) {
        toAdd += contact;
    }
    addContacts(toAdd);
    Q_ASSERT(hasChildren());
}
<commit_msg>Query child contacts for UriRole when ChildContactsUriRole is requested<commit_after>/*
    Persons Model Item
    Represents one person in the model
    Copyright (C) 2012  Martin Klapetek <martin.klapetek@gmail.com>

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

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

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

#include "personitem.h"
#include "contactitem.h"

#include <Nepomuk2/Vocabulary/PIMO>
#include <Nepomuk2/Vocabulary/NCO>
#include <Nepomuk2/Resource>
#include <Nepomuk2/Variant>
#include <Soprano/Vocabulary/NAO>
#include <KDebug>

PersonItem::PersonItem(const QUrl &personUri)
{
    setData(personUri, PersonsModel::UriRole);
}

PersonItem::PersonItem(const Nepomuk2::Resource &person)
{
    setData(person.uri(), PersonsModel::UriRole);
    setContacts(person.property(Nepomuk2::Vocabulary::PIMO::groundingOccurrence()).toUrlList());
    kDebug() << "new person" << text() << rowCount();
}

QVariant PersonItem::queryChildrenForRole(int role) const
{
    QVariant ret;
    for (int i = 0; i < rowCount(); i++) {
        QVariant value = child(i)->data(role);
        if (!value.isNull()) {
            ret = value;
            break;
        }
    }
    return ret;
}

QVariantList PersonItem::queryChildrenForRoleList(int role) const
{
    QVariantList ret;
    for (int i = 0; i < rowCount(); i++) {
        QVariant value = child(i)->data(role);
        if (value.type() == QVariant::List) {
            ret += value.toList();
        } else if (!value.isNull()) {
            ret += value;
        }
    }
    return ret;
}

QVariant PersonItem::data(int role) const
{
    if (role == PersonsModel::PresenceTypeRole) {
        QVariantList presences = queryChildrenForRoleList(PersonsModel::PresenceTypeRole);
        //FIXME? this is convenient, but in the worst case it has to go through the list 6x and do lots of comparisons
        //       possible optimization would be to go through it once and find the "most online value", this would need
        //       helper function with priorities for each string presence
        if (presences.contains("available")) {
            return QVariant("available");
        }
        if (presences.contains("away")) {
            return QVariant("away");
        }
        if (presences.contains("busy") || presences.contains("dnd")) {
            return QVariant("busy");
        }
        if (presences.contains("xa")) {
            return QVariant("xa");
        }
        if (presences.contains("unknown")) {
            return QVariant("unknown");
        }

        return QVariant("offline");
    }

    if (role == PersonsModel::UriRole) {
        //uri for PersonItem is set using setData(...), so we need to query it from there
        return QStandardItem::data(role);
    }

    QVariantList ret;
    for (int i = 0; i < rowCount(); i++) {
        QVariant value;
        //if we're being asked for the child contacts uris,
        //we need to query the children for their UriRole
        if (role == PersonsModel::ChildContactsUriRole) {
            value = child(i)->data(PersonsModel::UriRole);
        } else {
            value = child(i)->data(role);
        }
        //these roles must return single QVariant
        if ((role == Qt::DisplayRole || role == Qt::DecorationRole) && !value.isNull()) {
            return value;
        }
        if (value.type() == QVariant::List) {
            ret += value.toList();
        } else if (!value.isNull()) {
            ret += value;
        }
    }

    if (ret.isEmpty()) {
        //we need to return empty qvariant here, otherwise we'd get a qvariant
        //with empty qvariantlist, which would get parsed as non-empty qvariant
        return QVariant();
    }

    return ret;
}

void PersonItem::removeContacts(const QList<QUrl> &contacts)
{
    kDebug() << "remove contacts" << contacts;
    for (int i = 0; i < rowCount(); ) {
        QStandardItem *item = child(i);
        if (item && contacts.contains(item->data(PersonsModel::UriRole).toUrl())) {
            model()->invisibleRootItem()->appendRow(takeRow(i));
        } else {
            ++i;
        }
    }
    emitDataChanged();
}

void PersonItem::addContacts(const QList<QUrl> &_contacts)
{
    QList<QUrl> contacts(_contacts);
    //get existing child-contacts and remove them from the new ones
    QVariantList uris = queryChildrenForRoleList(PersonsModel::UriRole);
    foreach (const QVariant &uri, uris) {
        contacts.removeOne(uri.toUrl());
    }

    //query the model for the contacts, if they are present, then need to be just moved
    QList<QStandardItem*> toplevelContacts;
    foreach (const QUrl &uri, contacts) {
        QModelIndex contactIndex = qobject_cast<PersonsModel*>(model())->indexForUri(uri);
        if (contactIndex.isValid()) {
             toplevelContacts.append(qobject_cast<PersonsModel*>(model())->takeRow(contactIndex.row()));
        }
    }

    //append the moved contacts to this person and remove them from 'contacts'
    //so they are not added twice
    foreach (QStandardItem *contactItem, toplevelContacts) {
        //FIXME: we need to remove the fake person item here
        ContactItem *contact = dynamic_cast<ContactItem*>(contactItem);
        appendRow(contact);
        contacts.removeOne(contact->uri());
    }

    QList<ContactItem*> rows;
    foreach (const QUrl &uri, contacts) {
        ContactItem *item = new ContactItem(uri);
        item->loadData();
        appendRow(item);
    }
    emitDataChanged();
}

void PersonItem::setContacts(const QList<QUrl> &contacts)
{
    kDebug() << "set contacts" << contacts;
    if (contacts.isEmpty()) {
        //nothing to do here
        return;
    }

    if (hasChildren()) {
        QList<QUrl> toRemove;
        QVariantList uris = queryChildrenForRoleList(PersonsModel::UriRole);
        foreach (const QVariant &contact, uris) {
            if (!contacts.contains(contact.toUrl()))
                toRemove += contact.toUrl();
        }
        removeContacts(toRemove);
    }

    QList<QUrl> toAdd;
    foreach (const QUrl &contact, contacts) {
        toAdd += contact;
    }
    addContacts(toAdd);
    Q_ASSERT(hasChildren());
}
<|endoftext|>


<commit_before>#include "phone_book.hpp"

namespace gmock_sample
{

bool
phone_book::empty() const
{
	return this->size() == 0;
}

void
phone_book::insert(const std::string& name, const std::string& phone_nr)
{
	this->numbers_[name] = phone_nr;
}

size_t
phone_book::size() const
{
	return this->numbers_.size();
}

std::string
phone_book::get_nr(const std::string& name)
{
	return this->numbers_[name];
}

bool
phone_book::has_nr(const std::string& name) const
{
	(void)name;
	return false;
}

}
<commit_msg>Implements phone_book.has_nr().<commit_after>#include <iterator>

#include "phone_book.hpp"

namespace gmock_sample
{

bool
phone_book::empty() const
{
	return this->size() == 0;
}

void
phone_book::insert(const std::string& name, const std::string& phone_nr)
{
	this->numbers_[name] = phone_nr;
}

size_t
phone_book::size() const
{
	return this->numbers_.size();
}

std::string
phone_book::get_nr(const std::string& name)
{
	return this->numbers_[name];
}

bool
phone_book::has_nr(const std::string& name) const
{
	return this->numbers_.find(name) != std::end(this->numbers_);
}

}
<|endoftext|>