Browse Source

Merge pull request #5198

1c0aa91 Update serialize comments to be doxygen compatible (Michael Ford)
0.10
Wladimir J. van der Laan 10 years ago
parent
commit
3d3ce7421e
No known key found for this signature in database
GPG Key ID: 74810B012346C9A6
  1. 178
      src/serialize.h

178
src/serialize.h

@ -1,6 +1,6 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2013 The Bitcoin developers // Copyright (c) 2009-2014 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying // Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_SERIALIZE_H #ifndef BITCOIN_SERIALIZE_H
@ -22,23 +22,28 @@ class CScript;
static const unsigned int MAX_SIZE = 0x02000000; 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> template<typename T>
inline T& REF(const T& val) inline T& REF(const T& val)
{ {
return const_cast<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> template<typename T>
inline T* NCONST_PTR(const T* val) inline T* NCONST_PTR(const T* val)
{ {
return const_cast<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 * @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. * 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)) #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 * "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 * 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 \ #define ADD_SERIALIZE_METHODS \
size_t GetSerializeSize(int nType, int nVersion) const { \ size_t GetSerializeSize(int nType, int nVersion) const { \
CSizeComputer s(nType, nVersion); \ CSizeComputer s(nType, nVersion); \
@ -103,9 +110,9 @@ enum
// /*
// Basic types * Basic Types
// */
#define WRITEDATA(s, obj) s.write((char*)&(obj), sizeof(obj)) #define WRITEDATA(s, obj) s.write((char*)&(obj), sizeof(obj))
#define READDATA(s, obj) s.read((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 * Compact Size
// size < 253 -- 1 byte * size < 253 -- 1 byte
// size <= USHRT_MAX -- 3 bytes (253 + 2 bytes) * size <= USHRT_MAX -- 3 bytes (253 + 2 bytes)
// size <= UINT_MAX -- 5 bytes (254 + 4 bytes) * size <= UINT_MAX -- 5 bytes (254 + 4 bytes)
// size > UINT_MAX -- 9 bytes (255 + 8 bytes) * size > UINT_MAX -- 9 bytes (255 + 8 bytes)
// */
inline unsigned int GetSizeOfCompactSize(uint64_t nSize) inline unsigned int GetSizeOfCompactSize(uint64_t nSize)
{ {
if (nSize < 253) return sizeof(unsigned char); if (nSize < 253) return sizeof(unsigned char);
@ -246,27 +253,29 @@ uint64_t ReadCompactSize(Stream& is)
return nSizeRet; 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 * Variable-length integers: bytes are a MSB base-128 encoding of the number.
// the encoding is one-to-one, one is subtracted from all but the last digit. * The high bit in each byte signifies whether another digit follows. To make
// Thus, the byte sequence a[] with length len, where all but the last byte * sure the encoding is one-to-one, one is subtracted from all but the last digit.
// has bit 128 set, encodes the number: * 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)) *
// * (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) * Properties:
// * Every integer has exactly one encoding * * Very small (0-127: 1 byte, 128-16511: 2 bytes, 16512-2113663: 3 bytes)
// * Encoding does not depend on size of original integer type * * Every integer has exactly one encoding
// * No redundancy: every (infinite) byte sequence corresponds to a list * * Encoding does not depend on size of original integer type
// of encoded integers. * * No redundancy: every (infinite) byte sequence corresponds to a list
// * of encoded integers.
// 0: [0x00] 256: [0x81 0x00] *
// 1: [0x01] 16383: [0xFE 0x7F] * 0: [0x00] 256: [0x81 0x00]
// 127: [0x7F] 16384: [0xFF 0x00] * 1: [0x01] 16383: [0xFE 0x7F]
// 128: [0x80 0x00] 16511: [0x80 0xFF 0x7F] * 127: [0x7F] 16384: [0xFF 0x00]
// 255: [0x80 0x7F] 65535: [0x82 0xFD 0x7F] * 128: [0x80 0x00] 16511: [0x80 0xFF 0x7F]
// 2^32: [0x8E 0xFE 0xFE 0xFF 0x00] * 255: [0x80 0x7F] 65535: [0x82 0xFD 0x7F]
* 2^32: [0x8E 0xFE 0xFE 0xFF 0x00]
*/
template<typename I> template<typename I>
inline unsigned int GetSizeOfVarInt(I n) inline unsigned int GetSizeOfVarInt(I n)
@ -317,7 +326,8 @@ I ReadVarInt(Stream& is)
#define VARINT(obj) REF(WrapVarInt(REF(obj))) #define VARINT(obj) REF(WrapVarInt(REF(obj)))
#define LIMITED_STRING(obj,n) REF(LimitedString< n >(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 class CFlatData
{ {
@ -415,17 +425,21 @@ public:
template<typename I> template<typename I>
CVarInt<I> WrapVarInt(I& n) { return CVarInt<I>(n); } 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 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 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); 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> 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, 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); 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, 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); 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); 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 Serialize(Stream& os, const CScript& v, int nType, int nVersion);
template<typename Stream> void Unserialize(Stream& is, 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 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 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); 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 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 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); 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 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 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); 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. * 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. * "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. * The compiler will only cast int to long if none of the other templates matched.
// Thanks to Boost serialization for this idea. * Thanks to Boost serialization for this idea.
// */
template<typename T> template<typename T>
inline unsigned int GetSerializeSize(const T& a, long nType, int nVersion) 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> template<typename C>
unsigned int GetSerializeSize(const std::basic_string<C>& str, int, int) 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> template<typename T, typename A>
unsigned int GetSerializeSize_impl(const std::vector<T, A>& v, int nType, int nVersion, const unsigned char&) 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) inline unsigned int GetSerializeSize(const CScript& v, int nType, int nVersion)
{ {
return GetSerializeSize((const std::vector<unsigned char>&)v, nType, 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> template<typename K, typename T>
unsigned int GetSerializeSize(const std::pair<K, T>& item, int nType, int nVersion) 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> template<typename K, typename T, typename Pred, typename A>
unsigned int GetSerializeSize(const std::map<K, T, Pred, A>& m, int nType, int nVersion) 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> template<typename K, typename Pred, typename A>
unsigned int GetSerializeSize(const std::set<K, Pred, A>& m, int nType, int nVersion) 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 struct CSerActionSerialize
{ {
bool ForRead() const { return false; } bool ForRead() const { return false; }

Loading…
Cancel
Save