Repository: bitcoin/bitcoin
File: src/script/script.h (C/C++)

Code before:
    {
      if (vch.empty())
          return 0;

      int64_t result = 0;
      for (size_t i = 0; i != vch.size(); ++i)
          result |= static_cast<int64_t>(vch[i]) << 8*i;

      // If the input vector's most significant byte is 0x80, remove it from
      // the result's msb and return a negative.
      if (vch.back() & 0x80)
          return -((int64_t)(result & ~(0x80ULL << (8 * (vch.size() - 1)))));

      return result;
    }

    int64_t m_value;
};

/**
 * We use a prevector for the script to reduce the considerable memory overhead
 *  of vectors in cases where they normally contain a small number of small elements.
 * Tests in October 2015 showed use of this reduced dbcache memory usage by 23%
 *  and made an initial sync 13% faster.
 */
typedef prevector<28, unsigned char> CScriptBase;

bool GetScriptOp(CScriptBase::const_iterator& pc, CScriptBase::const_iterator end, opcodetype& opcodeRet, std::vector<unsigned char>* pvchRet);

/** Serialized script, used inside transaction inputs and outputs */
class CScript : public CScriptBase
{
private:
    inline void AppendDataSize(const uint32_t size)
    {
        if (size < OP_PUSHDATA1) {
            insert(end(), static_cast<value_type>(size));
        } else if (size <= 0xff) {
            insert(end(), OP_PUSHDATA1);
            insert(end(), static_cast<value_type>(size));
        } else if (size <= 0xffff) {
            insert(end(), OP_PUSHDATA2);
            value_type data[2];
            WriteLE16(data, size);
            insert(end(), std::cbegin(data), std::cend(data));
        } else {
            insert(end(), OP_PUSHDATA4);
            value_type data[4];
            WriteLE32(data, size);
            insert(end(), std::cbegin(data), std::cend(data));
        }

Review comment (suggestion):


nit in the first commit: Should this be called `script_base_size` instead? There are other uses of prevector (`CompressedScript`, netaddr, ...), so defining this globally could be confusing.

Code after:
    {
      if (vch.empty())
          return 0;

      int64_t result = 0;
      for (size_t i = 0; i != vch.size(); ++i)
          result |= static_cast<int64_t>(vch[i]) << 8*i;

      // If the input vector's most significant byte is 0x80, remove it from
      // the result's msb and return a negative.
      if (vch.back() & 0x80)
          return -((int64_t)(result & ~(0x80ULL << (8 * (vch.size() - 1)))));

      return result;
    }

    int64_t m_value;
};

/**
 * We use a prevector for the script to reduce the considerable memory overhead
 *  of vectors in cases where they normally contain a small number of small elements.
 */
using CScriptBase = prevector<36, uint8_t>;

bool GetScriptOp(CScriptBase::const_iterator& pc, CScriptBase::const_iterator end, opcodetype& opcodeRet, std::vector<unsigned char>* pvchRet);

/** Serialized script, used inside transaction inputs and outputs */
class CScript : public CScriptBase
{
private:
    inline void AppendDataSize(const uint32_t size)
    {
        if (size < OP_PUSHDATA1) {
            insert(end(), static_cast<value_type>(size));
        } else if (size <= 0xff) {
            insert(end(), OP_PUSHDATA1);
            insert(end(), static_cast<value_type>(size));
        } else if (size <= 0xffff) {
            insert(end(), OP_PUSHDATA2);
            value_type data[2];
            WriteLE16(data, size);
            insert(end(), std::cbegin(data), std::cend(data));
        } else {
            insert(end(), OP_PUSHDATA4);
            value_type data[4];
            WriteLE32(data, size);
            insert(end(), std::cbegin(data), std::cend(data));
        }
    }