@ -1,6 +1,6 @@
@@ -1,6 +1,6 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2013 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// Copyright (c) 2009-2014 The Bitcoin developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
# ifndef BITCOIN_SERIALIZE_H
@ -22,23 +22,28 @@ class CScript;
@@ -22,23 +22,28 @@ class CScript;
static const unsigned int MAX_SIZE = 0x02000000 ;
// Used to bypass the rule against non-const reference to temporary
// where it makes sense with wrappers such as CFlatData or CTxDB
/**
* Used to bypass the rule against non - const reference to temporary
* where it makes sense with wrappers such as CFlatData or CTxDB
*/
template < typename T >
inline T & REF ( const T & val )
{
return const_cast < T & > ( val ) ;
}
// Used to acquire a non-const pointer "this" to generate bodies
// of const serialization operations from a template
/**
* Used to acquire a non - const pointer " this " to generate bodies
* of const serialization operations from a template
*/
template < typename T >
inline T * NCONST_PTR ( const T * val )
{
return const_cast < T * > ( val ) ;
}
/** Get begin pointer of vector (non-const version).
/**
* Get begin pointer of vector ( non - const version ) .
* @ note These functions avoid the undefined case of indexing into an empty
* vector , as well as that of indexing after the end of the vector .
*/
@ -82,10 +87,12 @@ enum
@@ -82,10 +87,12 @@ enum
# define READWRITE(obj) (::SerReadWrite(s, (obj), nType, nVersion, ser_action))
/* Implement three methods for serializable objects. These are actually wrappers over
/**
* Implement three methods for serializable objects . These are actually wrappers over
* " SerializationOp " template , which implements the body of each class ' serialization
* code . Adding " ADD_SERIALIZE_METHODS " in the body of the class causes these wrappers to be
* added as members . */
* added as members .
*/
# define ADD_SERIALIZE_METHODS \
size_t GetSerializeSize ( int nType , int nVersion ) const { \
CSizeComputer s ( nType , nVersion ) ; \
@ -103,9 +110,9 @@ enum
@@ -103,9 +110,9 @@ enum
//
// Basic types
//
/*
* Basic Types
*/
# define WRITEDATA(s, obj) s.write((char*)&(obj), sizeof(obj))
# define READDATA(s, obj) s.read((char*)&(obj), sizeof(obj))
@ -160,13 +167,13 @@ template<typename Stream> inline void Unserialize(Stream& s, bool& a, int, int=0
@@ -160,13 +167,13 @@ template<typename Stream> inline void Unserialize(Stream& s, bool& a, int, int=0
//
// Compact size
// size < 253 -- 1 byte
// size <= USHRT_MAX -- 3 bytes (253 + 2 bytes)
// size <= UINT_MAX -- 5 bytes (254 + 4 bytes)
// size > UINT_MAX -- 9 bytes (255 + 8 bytes)
//
/**
* Compact Size
* size < 253 - - 1 byte
* size < = USHRT_MAX - - 3 bytes ( 253 + 2 bytes )
* size < = UINT_MAX - - 5 bytes ( 254 + 4 bytes )
* size > UINT_MAX - - 9 bytes ( 255 + 8 bytes )
*/
inline unsigned int GetSizeOfCompactSize ( uint64_t nSize )
{
if ( nSize < 253 ) return sizeof ( unsigned char ) ;
@ -246,27 +253,29 @@ uint64_t ReadCompactSize(Stream& is)
@@ -246,27 +253,29 @@ uint64_t ReadCompactSize(Stream& is)
return nSizeRet ;
}
// Variable-length integers: bytes are a MSB base-128 encoding of the number.
// The high bit in each byte signifies whether another digit follows. To make
// the encoding is one-to-one, one is subtracted from all but the last digit.
// Thus, the byte sequence a[] with length len, where all but the last byte
// has bit 128 set, encodes the number:
//
// (a[len-1] & 0x7F) + sum(i=1..len-1, 128^i*((a[len-i-1] & 0x7F)+1))
//
// Properties:
// * Very small (0-127: 1 byte, 128-16511: 2 bytes, 16512-2113663: 3 bytes)
// * Every integer has exactly one encoding
// * Encoding does not depend on size of original integer type
// * No redundancy: every (infinite) byte sequence corresponds to a list
// of encoded integers.
//
// 0: [0x00] 256: [0x81 0x00]
// 1: [0x01] 16383: [0xFE 0x7F]
// 127: [0x7F] 16384: [0xFF 0x00]
// 128: [0x80 0x00] 16511: [0x80 0xFF 0x7F]
// 255: [0x80 0x7F] 65535: [0x82 0xFD 0x7F]
// 2^32: [0x8E 0xFE 0xFE 0xFF 0x00]
/**
* Variable - length integers : bytes are a MSB base - 128 encoding of the number .
* The high bit in each byte signifies whether another digit follows . To make
* sure the encoding is one - to - one , one is subtracted from all but the last digit .
* Thus , the byte sequence a [ ] with length len , where all but the last byte
* has bit 128 set , encodes the number :
*
* ( a [ len - 1 ] & 0x7F ) + sum ( i = 1. . len - 1 , 128 ^ i * ( ( a [ len - i - 1 ] & 0x7F ) + 1 ) )
*
* Properties :
* * Very small ( 0 - 127 : 1 byte , 128 - 16511 : 2 bytes , 16512 - 2113663 : 3 bytes )
* * Every integer has exactly one encoding
* * Encoding does not depend on size of original integer type
* * No redundancy : every ( infinite ) byte sequence corresponds to a list
* of encoded integers .
*
* 0 : [ 0x00 ] 256 : [ 0x81 0x00 ]
* 1 : [ 0x01 ] 16383 : [ 0xFE 0x7F ]
* 127 : [ 0x7F ] 16384 : [ 0xFF 0x00 ]
* 128 : [ 0x80 0x00 ] 16511 : [ 0x80 0xFF 0x7F ]
* 255 : [ 0x80 0x7F ] 65535 : [ 0x82 0xFD 0x7F ]
* 2 ^ 32 : [ 0x8E 0xFE 0xFE 0xFF 0x00 ]
*/
template < typename I >
inline unsigned int GetSizeOfVarInt ( I n )
@ -317,7 +326,8 @@ I ReadVarInt(Stream& is)
@@ -317,7 +326,8 @@ I ReadVarInt(Stream& is)
# define VARINT(obj) REF(WrapVarInt(REF(obj)))
# define LIMITED_STRING(obj,n) REF(LimitedString< n >(REF(obj)))
/** Wrapper for serializing arrays and POD.
/**
* Wrapper for serializing arrays and POD .
*/
class CFlatData
{
@ -415,17 +425,21 @@ public:
@@ -415,17 +425,21 @@ public:
template < typename I >
CVarInt < I > WrapVarInt ( I & n ) { return CVarInt < I > ( n ) ; }
//
// Forward declarations
//
/**
* Forward declarations
*/
// string
/**
* string
*/
template < typename C > unsigned int GetSerializeSize ( const std : : basic_string < C > & str , int , int = 0 ) ;
template < typename Stream , typename C > void Serialize ( Stream & os , const std : : basic_string < C > & str , int , int = 0 ) ;
template < typename Stream , typename C > void Unserialize ( Stream & is , std : : basic_string < C > & str , int , int = 0 ) ;
// vector
// vectors of unsigned char are a special case and are intended to be serialized as a single opaque blob.
/**
* vector
* vectors of unsigned char are a special case and are intended to be serialized as a single opaque blob .
*/
template < typename T , typename A > unsigned int GetSerializeSize_impl ( const std : : vector < T , A > & v , int nType , int nVersion , const unsigned char & ) ;
template < typename T , typename A , typename V > unsigned int GetSerializeSize_impl ( const std : : vector < T , A > & v , int nType , int nVersion , const V & ) ;
template < typename T , typename A > inline unsigned int GetSerializeSize ( const std : : vector < T , A > & v , int nType , int nVersion ) ;
@ -436,22 +450,30 @@ template<typename Stream, typename T, typename A> void Unserialize_impl(Stream&
@@ -436,22 +450,30 @@ template<typename Stream, typename T, typename A> void Unserialize_impl(Stream&
template < typename Stream , typename T , typename A , typename V > void Unserialize_impl ( Stream & is , std : : vector < T , A > & v , int nType , int nVersion , const V & ) ;
template < typename Stream , typename T , typename A > inline void Unserialize ( Stream & is , std : : vector < T , A > & v , int nType , int nVersion ) ;
// others derived from vector
/**
* others derived from vector
*/
extern inline unsigned int GetSerializeSize ( const CScript & v , int nType , int nVersion ) ;
template < typename Stream > void Serialize ( Stream & os , const CScript & v , int nType , int nVersion ) ;
template < typename Stream > void Unserialize ( Stream & is , CScript & v , int nType , int nVersion ) ;
// pair
/**
* pair
*/
template < typename K , typename T > unsigned int GetSerializeSize ( const std : : pair < K , T > & item , int nType , int nVersion ) ;
template < typename Stream , typename K , typename T > void Serialize ( Stream & os , const std : : pair < K , T > & item , int nType , int nVersion ) ;
template < typename Stream , typename K , typename T > void Unserialize ( Stream & is , std : : pair < K , T > & item , int nType , int nVersion ) ;
// map
/**
* map
*/
template < typename K , typename T , typename Pred , typename A > unsigned int GetSerializeSize ( const std : : map < K , T , Pred , A > & m , int nType , int nVersion ) ;
template < typename Stream , typename K , typename T , typename Pred , typename A > void Serialize ( Stream & os , const std : : map < K , T , Pred , A > & m , int nType , int nVersion ) ;
template < typename Stream , typename K , typename T , typename Pred , typename A > void Unserialize ( Stream & is , std : : map < K , T , Pred , A > & m , int nType , int nVersion ) ;
// set
/**
* set
*/
template < typename K , typename Pred , typename A > unsigned int GetSerializeSize ( const std : : set < K , Pred , A > & m , int nType , int nVersion ) ;
template < typename Stream , typename K , typename Pred , typename A > void Serialize ( Stream & os , const std : : set < K , Pred , A > & m , int nType , int nVersion ) ;
template < typename Stream , typename K , typename Pred , typename A > void Unserialize ( Stream & is , std : : set < K , Pred , A > & m , int nType , int nVersion ) ;
@ -460,12 +482,12 @@ template<typename Stream, typename K, typename Pred, typename A> void Unserializ
@@ -460,12 +482,12 @@ template<typename Stream, typename K, typename Pred, typename A> void Unserializ
//
// If none of the specialized versions above matched, default to calling member function.
// "int nType" is changed to "long nType" to keep from getting an ambiguous overload error.
// The compiler will only cast int to long if none of the other templates matched.
// Thanks to Boost serialization for this idea.
//
/**
* If none of the specialized versions above matched , default to calling member function .
* " int nType " is changed to " long nType " to keep from getting an ambiguous overload error .
* The compiler will only cast int to long if none of the other templates matched .
* Thanks to Boost serialization for this idea .
*/
template < typename T >
inline unsigned int GetSerializeSize ( const T & a , long nType , int nVersion )
{
@ -488,9 +510,9 @@ inline void Unserialize(Stream& is, T& a, long nType, int nVersion)
@@ -488,9 +510,9 @@ inline void Unserialize(Stream& is, T& a, long nType, int nVersion)
//
// string
//
/**
* string
*/
template < typename C >
unsigned int GetSerializeSize ( const std : : basic_string < C > & str , int , int )
{
@ -516,9 +538,9 @@ void Unserialize(Stream& is, std::basic_string<C>& str, int, int)
@@ -516,9 +538,9 @@ void Unserialize(Stream& is, std::basic_string<C>& str, int, int)
//
// vector
//
/**
* vector
*/
template < typename T , typename A >
unsigned int GetSerializeSize_impl ( const std : : vector < T , A > & v , int nType , int nVersion , const unsigned char & )
{
@ -606,9 +628,9 @@ inline void Unserialize(Stream& is, std::vector<T, A>& v, int nType, int nVersio
@@ -606,9 +628,9 @@ inline void Unserialize(Stream& is, std::vector<T, A>& v, int nType, int nVersio
//
// others derived from vector
//
/**
* others derived from vector
*/
inline unsigned int GetSerializeSize ( const CScript & v , int nType , int nVersion )
{
return GetSerializeSize ( ( const std : : vector < unsigned char > & ) v , nType , nVersion ) ;
@ -628,9 +650,9 @@ void Unserialize(Stream& is, CScript& v, int nType, int nVersion)
@@ -628,9 +650,9 @@ void Unserialize(Stream& is, CScript& v, int nType, int nVersion)
//
// pair
//
/**
* pair
*/
template < typename K , typename T >
unsigned int GetSerializeSize ( const std : : pair < K , T > & item , int nType , int nVersion )
{
@ -653,9 +675,9 @@ void Unserialize(Stream& is, std::pair<K, T>& item, int nType, int nVersion)
@@ -653,9 +675,9 @@ void Unserialize(Stream& is, std::pair<K, T>& item, int nType, int nVersion)
//
// map
//
/**
* map
*/
template < typename K , typename T , typename Pred , typename A >
unsigned int GetSerializeSize ( const std : : map < K , T , Pred , A > & m , int nType , int nVersion )
{
@ -689,9 +711,9 @@ void Unserialize(Stream& is, std::map<K, T, Pred, A>& m, int nType, int nVersion
@@ -689,9 +711,9 @@ void Unserialize(Stream& is, std::map<K, T, Pred, A>& m, int nType, int nVersion
//
// set
//
/**
* set
*/
template < typename K , typename Pred , typename A >
unsigned int GetSerializeSize ( const std : : set < K , Pred , A > & m , int nType , int nVersion )
{
@ -725,9 +747,9 @@ void Unserialize(Stream& is, std::set<K, Pred, A>& m, int nType, int nVersion)
@@ -725,9 +747,9 @@ void Unserialize(Stream& is, std::set<K, Pred, A>& m, int nType, int nVersion)
//
// Support for ADD_SERIALIZE_METHODS and READWRITE macro
//
/**
* Support for ADD_SERIALIZE_METHODS and READWRITE macro
*/
struct CSerActionSerialize
{
bool ForRead ( ) const { return false ; }