diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/serialize.h | 178 |
1 files changed, 100 insertions, 78 deletions
diff --git a/src/serialize.h b/src/serialize.h index 877ef8640a..ad38a3fa22 100644 --- a/src/serialize.h +++ b/src/serialize.h @@ -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; 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 #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 -// -// 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 -// -// 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) 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) #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: 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& 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 -// -// 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) -// -// 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) -// -// 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 -// -// 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) -// -// 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) -// -// 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 -// -// 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) -// -// Support for ADD_SERIALIZE_METHODS and READWRITE macro -// +/** + * Support for ADD_SERIALIZE_METHODS and READWRITE macro + */ struct CSerActionSerialize { bool ForRead() const { return false; } |