You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

serialize.h 32KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963
  1. // Copyright (c) 2009-2010 Satoshi Nakamoto
  2. // Copyright (c) 2009-2015 The Bitcoin Core developers
  3. // Distributed under the MIT software license, see the accompanying
  4. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
  5. #ifndef BITCOIN_SERIALIZE_H
  6. #define BITCOIN_SERIALIZE_H
  7. #include "compat/endian.h"
  8. #include <algorithm>
  9. #include <assert.h>
  10. #include <ios>
  11. #include <limits>
  12. #include <map>
  13. #include <set>
  14. #include <stdint.h>
  15. #include <string>
  16. #include <string.h>
  17. #include <utility>
  18. #include <vector>
  19. #include "prevector.h"
  20. static const unsigned int MAX_SIZE = 0x02000000;
  21. /**
  22. * Used to bypass the rule against non-const reference to temporary
  23. * where it makes sense with wrappers such as CFlatData or CTxDB
  24. */
  25. template<typename T>
  26. inline T& REF(const T& val)
  27. {
  28. return const_cast<T&>(val);
  29. }
  30. /**
  31. * Used to acquire a non-const pointer "this" to generate bodies
  32. * of const serialization operations from a template
  33. */
  34. template<typename T>
  35. inline T* NCONST_PTR(const T* val)
  36. {
  37. return const_cast<T*>(val);
  38. }
  39. /**
  40. * Important: Do not use the following functions in new code, but use v.data()
  41. * and v.data() + v.size() respectively directly. They were once introduced to
  42. * have a compatible, safe way to get the begin and end pointer of a vector.
  43. * However with C++11 the language has built-in functionality for this and it's
  44. * more readable to just use that.
  45. */
  46. template <typename V>
  47. inline typename V::value_type* begin_ptr(V& v)
  48. {
  49. return v.data();
  50. }
  51. template <typename V>
  52. inline const typename V::value_type* begin_ptr(const V& v)
  53. {
  54. return v.data();
  55. }
  56. template <typename V>
  57. inline typename V::value_type* end_ptr(V& v)
  58. {
  59. return v.data() + v.size();
  60. }
  61. template <typename V>
  62. inline const typename V::value_type* end_ptr(const V& v)
  63. {
  64. return v.data() + v.size();
  65. }
  66. /*
  67. * Lowest-level serialization and conversion.
  68. * @note Sizes of these types are verified in the tests
  69. */
  70. template<typename Stream> inline void ser_writedata8(Stream &s, uint8_t obj)
  71. {
  72. s.write((char*)&obj, 1);
  73. }
  74. template<typename Stream> inline void ser_writedata16(Stream &s, uint16_t obj)
  75. {
  76. obj = htole16(obj);
  77. s.write((char*)&obj, 2);
  78. }
  79. template<typename Stream> inline void ser_writedata32(Stream &s, uint32_t obj)
  80. {
  81. obj = htole32(obj);
  82. s.write((char*)&obj, 4);
  83. }
  84. template<typename Stream> inline void ser_writedata64(Stream &s, uint64_t obj)
  85. {
  86. obj = htole64(obj);
  87. s.write((char*)&obj, 8);
  88. }
  89. template<typename Stream> inline uint8_t ser_readdata8(Stream &s)
  90. {
  91. uint8_t obj;
  92. s.read((char*)&obj, 1);
  93. return obj;
  94. }
  95. template<typename Stream> inline uint16_t ser_readdata16(Stream &s)
  96. {
  97. uint16_t obj;
  98. s.read((char*)&obj, 2);
  99. return le16toh(obj);
  100. }
  101. template<typename Stream> inline uint32_t ser_readdata32(Stream &s)
  102. {
  103. uint32_t obj;
  104. s.read((char*)&obj, 4);
  105. return le32toh(obj);
  106. }
  107. template<typename Stream> inline uint64_t ser_readdata64(Stream &s)
  108. {
  109. uint64_t obj;
  110. s.read((char*)&obj, 8);
  111. return le64toh(obj);
  112. }
  113. inline uint64_t ser_double_to_uint64(double x)
  114. {
  115. union { double x; uint64_t y; } tmp;
  116. tmp.x = x;
  117. return tmp.y;
  118. }
  119. inline uint32_t ser_float_to_uint32(float x)
  120. {
  121. union { float x; uint32_t y; } tmp;
  122. tmp.x = x;
  123. return tmp.y;
  124. }
  125. inline double ser_uint64_to_double(uint64_t y)
  126. {
  127. union { double x; uint64_t y; } tmp;
  128. tmp.y = y;
  129. return tmp.x;
  130. }
  131. inline float ser_uint32_to_float(uint32_t y)
  132. {
  133. union { float x; uint32_t y; } tmp;
  134. tmp.y = y;
  135. return tmp.x;
  136. }
  137. /////////////////////////////////////////////////////////////////
  138. //
  139. // Templates for serializing to anything that looks like a stream,
  140. // i.e. anything that supports .read(char*, size_t) and .write(char*, size_t)
  141. //
  142. enum
  143. {
  144. // primary actions
  145. SER_NETWORK = (1 << 0),
  146. SER_DISK = (1 << 1),
  147. SER_GETHASH = (1 << 2),
  148. };
  149. #define READWRITE(obj) (::SerReadWrite(s, (obj), nType, nVersion, ser_action))
  150. /**
  151. * Implement three methods for serializable objects. These are actually wrappers over
  152. * "SerializationOp" template, which implements the body of each class' serialization
  153. * code. Adding "ADD_SERIALIZE_METHODS" in the body of the class causes these wrappers to be
  154. * added as members.
  155. */
  156. #define ADD_SERIALIZE_METHODS \
  157. size_t GetSerializeSize(int nType, int nVersion) const { \
  158. CSizeComputer s(nType, nVersion); \
  159. NCONST_PTR(this)->SerializationOp(s, CSerActionSerialize(), nType, nVersion);\
  160. return s.size(); \
  161. } \
  162. template<typename Stream> \
  163. void Serialize(Stream& s, int nType, int nVersion) const { \
  164. NCONST_PTR(this)->SerializationOp(s, CSerActionSerialize(), nType, nVersion);\
  165. } \
  166. template<typename Stream> \
  167. void Unserialize(Stream& s, int nType, int nVersion) { \
  168. SerializationOp(s, CSerActionUnserialize(), nType, nVersion); \
  169. }
  170. /*
  171. * Basic Types
  172. */
  173. inline unsigned int GetSerializeSize(char a, int, int=0) { return 1; }
  174. inline unsigned int GetSerializeSize(int8_t a, int, int=0) { return 1; }
  175. inline unsigned int GetSerializeSize(uint8_t a, int, int=0) { return 1; }
  176. inline unsigned int GetSerializeSize(int16_t a, int, int=0) { return 2; }
  177. inline unsigned int GetSerializeSize(uint16_t a, int, int=0) { return 2; }
  178. inline unsigned int GetSerializeSize(int32_t a, int, int=0) { return 4; }
  179. inline unsigned int GetSerializeSize(uint32_t a, int, int=0) { return 4; }
  180. inline unsigned int GetSerializeSize(int64_t a, int, int=0) { return 8; }
  181. inline unsigned int GetSerializeSize(uint64_t a, int, int=0) { return 8; }
  182. inline unsigned int GetSerializeSize(float a, int, int=0) { return 4; }
  183. inline unsigned int GetSerializeSize(double a, int, int=0) { return 8; }
  184. template<typename Stream> inline void Serialize(Stream& s, char a, int, int=0) { ser_writedata8(s, a); } // TODO Get rid of bare char
  185. template<typename Stream> inline void Serialize(Stream& s, int8_t a, int, int=0) { ser_writedata8(s, a); }
  186. template<typename Stream> inline void Serialize(Stream& s, uint8_t a, int, int=0) { ser_writedata8(s, a); }
  187. template<typename Stream> inline void Serialize(Stream& s, int16_t a, int, int=0) { ser_writedata16(s, a); }
  188. template<typename Stream> inline void Serialize(Stream& s, uint16_t a, int, int=0) { ser_writedata16(s, a); }
  189. template<typename Stream> inline void Serialize(Stream& s, int32_t a, int, int=0) { ser_writedata32(s, a); }
  190. template<typename Stream> inline void Serialize(Stream& s, uint32_t a, int, int=0) { ser_writedata32(s, a); }
  191. template<typename Stream> inline void Serialize(Stream& s, int64_t a, int, int=0) { ser_writedata64(s, a); }
  192. template<typename Stream> inline void Serialize(Stream& s, uint64_t a, int, int=0) { ser_writedata64(s, a); }
  193. template<typename Stream> inline void Serialize(Stream& s, float a, int, int=0) { ser_writedata32(s, ser_float_to_uint32(a)); }
  194. template<typename Stream> inline void Serialize(Stream& s, double a, int, int=0) { ser_writedata64(s, ser_double_to_uint64(a)); }
  195. template<typename Stream> inline void Unserialize(Stream& s, char& a, int, int=0) { a = ser_readdata8(s); } // TODO Get rid of bare char
  196. template<typename Stream> inline void Unserialize(Stream& s, int8_t& a, int, int=0) { a = ser_readdata8(s); }
  197. template<typename Stream> inline void Unserialize(Stream& s, uint8_t& a, int, int=0) { a = ser_readdata8(s); }
  198. template<typename Stream> inline void Unserialize(Stream& s, int16_t& a, int, int=0) { a = ser_readdata16(s); }
  199. template<typename Stream> inline void Unserialize(Stream& s, uint16_t& a, int, int=0) { a = ser_readdata16(s); }
  200. template<typename Stream> inline void Unserialize(Stream& s, int32_t& a, int, int=0) { a = ser_readdata32(s); }
  201. template<typename Stream> inline void Unserialize(Stream& s, uint32_t& a, int, int=0) { a = ser_readdata32(s); }
  202. template<typename Stream> inline void Unserialize(Stream& s, int64_t& a, int, int=0) { a = ser_readdata64(s); }
  203. template<typename Stream> inline void Unserialize(Stream& s, uint64_t& a, int, int=0) { a = ser_readdata64(s); }
  204. template<typename Stream> inline void Unserialize(Stream& s, float& a, int, int=0) { a = ser_uint32_to_float(ser_readdata32(s)); }
  205. template<typename Stream> inline void Unserialize(Stream& s, double& a, int, int=0) { a = ser_uint64_to_double(ser_readdata64(s)); }
  206. inline unsigned int GetSerializeSize(bool a, int, int=0) { return sizeof(char); }
  207. template<typename Stream> inline void Serialize(Stream& s, bool a, int, int=0) { char f=a; ser_writedata8(s, f); }
  208. template<typename Stream> inline void Unserialize(Stream& s, bool& a, int, int=0) { char f=ser_readdata8(s); a=f; }
  209. /**
  210. * Compact Size
  211. * size < 253 -- 1 byte
  212. * size <= USHRT_MAX -- 3 bytes (253 + 2 bytes)
  213. * size <= UINT_MAX -- 5 bytes (254 + 4 bytes)
  214. * size > UINT_MAX -- 9 bytes (255 + 8 bytes)
  215. */
  216. inline unsigned int GetSizeOfCompactSize(uint64_t nSize)
  217. {
  218. if (nSize < 253) return sizeof(unsigned char);
  219. else if (nSize <= std::numeric_limits<unsigned short>::max()) return sizeof(unsigned char) + sizeof(unsigned short);
  220. else if (nSize <= std::numeric_limits<unsigned int>::max()) return sizeof(unsigned char) + sizeof(unsigned int);
  221. else return sizeof(unsigned char) + sizeof(uint64_t);
  222. }
  223. template<typename Stream>
  224. void WriteCompactSize(Stream& os, uint64_t nSize)
  225. {
  226. if (nSize < 253)
  227. {
  228. ser_writedata8(os, nSize);
  229. }
  230. else if (nSize <= std::numeric_limits<unsigned short>::max())
  231. {
  232. ser_writedata8(os, 253);
  233. ser_writedata16(os, nSize);
  234. }
  235. else if (nSize <= std::numeric_limits<unsigned int>::max())
  236. {
  237. ser_writedata8(os, 254);
  238. ser_writedata32(os, nSize);
  239. }
  240. else
  241. {
  242. ser_writedata8(os, 255);
  243. ser_writedata64(os, nSize);
  244. }
  245. return;
  246. }
  247. template<typename Stream>
  248. uint64_t ReadCompactSize(Stream& is)
  249. {
  250. uint8_t chSize = ser_readdata8(is);
  251. uint64_t nSizeRet = 0;
  252. if (chSize < 253)
  253. {
  254. nSizeRet = chSize;
  255. }
  256. else if (chSize == 253)
  257. {
  258. nSizeRet = ser_readdata16(is);
  259. if (nSizeRet < 253)
  260. throw std::ios_base::failure("non-canonical ReadCompactSize()");
  261. }
  262. else if (chSize == 254)
  263. {
  264. nSizeRet = ser_readdata32(is);
  265. if (nSizeRet < 0x10000u)
  266. throw std::ios_base::failure("non-canonical ReadCompactSize()");
  267. }
  268. else
  269. {
  270. nSizeRet = ser_readdata64(is);
  271. if (nSizeRet < 0x100000000ULL)
  272. throw std::ios_base::failure("non-canonical ReadCompactSize()");
  273. }
  274. if (nSizeRet > (uint64_t)MAX_SIZE)
  275. throw std::ios_base::failure("ReadCompactSize(): size too large");
  276. return nSizeRet;
  277. }
  278. /**
  279. * Variable-length integers: bytes are a MSB base-128 encoding of the number.
  280. * The high bit in each byte signifies whether another digit follows. To make
  281. * sure the encoding is one-to-one, one is subtracted from all but the last digit.
  282. * Thus, the byte sequence a[] with length len, where all but the last byte
  283. * has bit 128 set, encodes the number:
  284. *
  285. * (a[len-1] & 0x7F) + sum(i=1..len-1, 128^i*((a[len-i-1] & 0x7F)+1))
  286. *
  287. * Properties:
  288. * * Very small (0-127: 1 byte, 128-16511: 2 bytes, 16512-2113663: 3 bytes)
  289. * * Every integer has exactly one encoding
  290. * * Encoding does not depend on size of original integer type
  291. * * No redundancy: every (infinite) byte sequence corresponds to a list
  292. * of encoded integers.
  293. *
  294. * 0: [0x00] 256: [0x81 0x00]
  295. * 1: [0x01] 16383: [0xFE 0x7F]
  296. * 127: [0x7F] 16384: [0xFF 0x00]
  297. * 128: [0x80 0x00] 16511: [0xFF 0x7F]
  298. * 255: [0x80 0x7F] 65535: [0x82 0xFE 0x7F]
  299. * 2^32: [0x8E 0xFE 0xFE 0xFF 0x00]
  300. */
  301. template<typename I>
  302. inline unsigned int GetSizeOfVarInt(I n)
  303. {
  304. int nRet = 0;
  305. while(true) {
  306. nRet++;
  307. if (n <= 0x7F)
  308. break;
  309. n = (n >> 7) - 1;
  310. }
  311. return nRet;
  312. }
  313. template<typename Stream, typename I>
  314. void WriteVarInt(Stream& os, I n)
  315. {
  316. unsigned char tmp[(sizeof(n)*8+6)/7];
  317. int len=0;
  318. while(true) {
  319. tmp[len] = (n & 0x7F) | (len ? 0x80 : 0x00);
  320. if (n <= 0x7F)
  321. break;
  322. n = (n >> 7) - 1;
  323. len++;
  324. }
  325. do {
  326. ser_writedata8(os, tmp[len]);
  327. } while(len--);
  328. }
  329. template<typename Stream, typename I>
  330. I ReadVarInt(Stream& is)
  331. {
  332. I n = 0;
  333. while(true) {
  334. unsigned char chData = ser_readdata8(is);
  335. n = (n << 7) | (chData & 0x7F);
  336. if (chData & 0x80)
  337. n++;
  338. else
  339. return n;
  340. }
  341. }
  342. #define FLATDATA(obj) REF(CFlatData((char*)&(obj), (char*)&(obj) + sizeof(obj)))
  343. #define VARINT(obj) REF(WrapVarInt(REF(obj)))
  344. #define COMPACTSIZE(obj) REF(CCompactSize(REF(obj)))
  345. #define LIMITED_STRING(obj,n) REF(LimitedString< n >(REF(obj)))
  346. /**
  347. * Wrapper for serializing arrays and POD.
  348. */
  349. class CFlatData
  350. {
  351. protected:
  352. char* pbegin;
  353. char* pend;
  354. public:
  355. CFlatData(void* pbeginIn, void* pendIn) : pbegin((char*)pbeginIn), pend((char*)pendIn) { }
  356. template <class T, class TAl>
  357. explicit CFlatData(std::vector<T,TAl> &v)
  358. {
  359. pbegin = (char*)begin_ptr(v);
  360. pend = (char*)end_ptr(v);
  361. }
  362. template <unsigned int N, typename T, typename S, typename D>
  363. explicit CFlatData(prevector<N, T, S, D> &v)
  364. {
  365. pbegin = (char*)begin_ptr(v);
  366. pend = (char*)end_ptr(v);
  367. }
  368. char* begin() { return pbegin; }
  369. const char* begin() const { return pbegin; }
  370. char* end() { return pend; }
  371. const char* end() const { return pend; }
  372. unsigned int GetSerializeSize(int, int=0) const
  373. {
  374. return pend - pbegin;
  375. }
  376. template<typename Stream>
  377. void Serialize(Stream& s, int, int=0) const
  378. {
  379. s.write(pbegin, pend - pbegin);
  380. }
  381. template<typename Stream>
  382. void Unserialize(Stream& s, int, int=0)
  383. {
  384. s.read(pbegin, pend - pbegin);
  385. }
  386. };
  387. template<typename I>
  388. class CVarInt
  389. {
  390. protected:
  391. I &n;
  392. public:
  393. CVarInt(I& nIn) : n(nIn) { }
  394. unsigned int GetSerializeSize(int, int) const {
  395. return GetSizeOfVarInt<I>(n);
  396. }
  397. template<typename Stream>
  398. void Serialize(Stream &s, int, int) const {
  399. WriteVarInt<Stream,I>(s, n);
  400. }
  401. template<typename Stream>
  402. void Unserialize(Stream& s, int, int) {
  403. n = ReadVarInt<Stream,I>(s);
  404. }
  405. };
  406. class CCompactSize
  407. {
  408. protected:
  409. uint64_t &n;
  410. public:
  411. CCompactSize(uint64_t& nIn) : n(nIn) { }
  412. unsigned int GetSerializeSize(int, int) const {
  413. return GetSizeOfCompactSize(n);
  414. }
  415. template<typename Stream>
  416. void Serialize(Stream &s, int, int) const {
  417. WriteCompactSize<Stream>(s, n);
  418. }
  419. template<typename Stream>
  420. void Unserialize(Stream& s, int, int) {
  421. n = ReadCompactSize<Stream>(s);
  422. }
  423. };
  424. template<size_t Limit>
  425. class LimitedString
  426. {
  427. protected:
  428. std::string& string;
  429. public:
  430. LimitedString(std::string& string) : string(string) {}
  431. template<typename Stream>
  432. void Unserialize(Stream& s, int, int=0)
  433. {
  434. size_t size = ReadCompactSize(s);
  435. if (size > Limit) {
  436. throw std::ios_base::failure("String length limit exceeded");
  437. }
  438. string.resize(size);
  439. if (size != 0)
  440. s.read((char*)&string[0], size);
  441. }
  442. template<typename Stream>
  443. void Serialize(Stream& s, int, int=0) const
  444. {
  445. WriteCompactSize(s, string.size());
  446. if (!string.empty())
  447. s.write((char*)&string[0], string.size());
  448. }
  449. unsigned int GetSerializeSize(int, int=0) const
  450. {
  451. return GetSizeOfCompactSize(string.size()) + string.size();
  452. }
  453. };
  454. template<typename I>
  455. CVarInt<I> WrapVarInt(I& n) { return CVarInt<I>(n); }
  456. /**
  457. * Forward declarations
  458. */
  459. /**
  460. * string
  461. */
  462. template<typename C> unsigned int GetSerializeSize(const std::basic_string<C>& str, int, int=0);
  463. template<typename Stream, typename C> void Serialize(Stream& os, const std::basic_string<C>& str, int, int=0);
  464. template<typename Stream, typename C> void Unserialize(Stream& is, std::basic_string<C>& str, int, int=0);
  465. /**
  466. * prevector
  467. * prevectors of unsigned char are a special case and are intended to be serialized as a single opaque blob.
  468. */
  469. template<unsigned int N, typename T> unsigned int GetSerializeSize_impl(const prevector<N, T>& v, int nType, int nVersion, const unsigned char&);
  470. template<unsigned int N, typename T, typename V> unsigned int GetSerializeSize_impl(const prevector<N, T>& v, int nType, int nVersion, const V&);
  471. template<unsigned int N, typename T> inline unsigned int GetSerializeSize(const prevector<N, T>& v, int nType, int nVersion);
  472. template<typename Stream, unsigned int N, typename T> void Serialize_impl(Stream& os, const prevector<N, T>& v, int nType, int nVersion, const unsigned char&);
  473. template<typename Stream, unsigned int N, typename T, typename V> void Serialize_impl(Stream& os, const prevector<N, T>& v, int nType, int nVersion, const V&);
  474. template<typename Stream, unsigned int N, typename T> inline void Serialize(Stream& os, const prevector<N, T>& v, int nType, int nVersion);
  475. template<typename Stream, unsigned int N, typename T> void Unserialize_impl(Stream& is, prevector<N, T>& v, int nType, int nVersion, const unsigned char&);
  476. template<typename Stream, unsigned int N, typename T, typename V> void Unserialize_impl(Stream& is, prevector<N, T>& v, int nType, int nVersion, const V&);
  477. template<typename Stream, unsigned int N, typename T> inline void Unserialize(Stream& is, prevector<N, T>& v, int nType, int nVersion);
  478. /**
  479. * vector
  480. * vectors of unsigned char are a special case and are intended to be serialized as a single opaque blob.
  481. */
  482. template<typename T, typename A> unsigned int GetSerializeSize_impl(const std::vector<T, A>& v, int nType, int nVersion, const unsigned char&);
  483. template<typename T, typename A, typename V> unsigned int GetSerializeSize_impl(const std::vector<T, A>& v, int nType, int nVersion, const V&);
  484. template<typename T, typename A> inline unsigned int GetSerializeSize(const std::vector<T, A>& v, int nType, int nVersion);
  485. template<typename Stream, typename T, typename A> void Serialize_impl(Stream& os, const std::vector<T, A>& v, int nType, int nVersion, const unsigned char&);
  486. template<typename Stream, typename T, typename A, typename V> void Serialize_impl(Stream& os, const std::vector<T, A>& v, int nType, int nVersion, const V&);
  487. template<typename Stream, typename T, typename A> inline void Serialize(Stream& os, const std::vector<T, A>& v, int nType, int nVersion);
  488. template<typename Stream, typename T, typename A> void Unserialize_impl(Stream& is, std::vector<T, A>& v, int nType, int nVersion, const unsigned char&);
  489. 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&);
  490. template<typename Stream, typename T, typename A> inline void Unserialize(Stream& is, std::vector<T, A>& v, int nType, int nVersion);
  491. /**
  492. * pair
  493. */
  494. template<typename K, typename T> unsigned int GetSerializeSize(const std::pair<K, T>& item, int nType, int nVersion);
  495. template<typename Stream, typename K, typename T> void Serialize(Stream& os, const std::pair<K, T>& item, int nType, int nVersion);
  496. template<typename Stream, typename K, typename T> void Unserialize(Stream& is, std::pair<K, T>& item, int nType, int nVersion);
  497. /**
  498. * map
  499. */
  500. template<typename K, typename T, typename Pred, typename A> unsigned int GetSerializeSize(const std::map<K, T, Pred, A>& m, int nType, int nVersion);
  501. 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);
  502. 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);
  503. /**
  504. * set
  505. */
  506. template<typename K, typename Pred, typename A> unsigned int GetSerializeSize(const std::set<K, Pred, A>& m, int nType, int nVersion);
  507. template<typename Stream, typename K, typename Pred, typename A> void Serialize(Stream& os, const std::set<K, Pred, A>& m, int nType, int nVersion);
  508. template<typename Stream, typename K, typename Pred, typename A> void Unserialize(Stream& is, std::set<K, Pred, A>& m, int nType, int nVersion);
  509. /**
  510. * If none of the specialized versions above matched, default to calling member function.
  511. * "int nType" is changed to "long nType" to keep from getting an ambiguous overload error.
  512. * The compiler will only cast int to long if none of the other templates matched.
  513. * Thanks to Boost serialization for this idea.
  514. */
  515. template<typename T>
  516. inline unsigned int GetSerializeSize(const T& a, long nType, int nVersion)
  517. {
  518. return a.GetSerializeSize((int)nType, nVersion);
  519. }
  520. template<typename Stream, typename T>
  521. inline void Serialize(Stream& os, const T& a, long nType, int nVersion)
  522. {
  523. a.Serialize(os, (int)nType, nVersion);
  524. }
  525. template<typename Stream, typename T>
  526. inline void Unserialize(Stream& is, T& a, long nType, int nVersion)
  527. {
  528. a.Unserialize(is, (int)nType, nVersion);
  529. }
  530. /**
  531. * string
  532. */
  533. template<typename C>
  534. unsigned int GetSerializeSize(const std::basic_string<C>& str, int, int)
  535. {
  536. return GetSizeOfCompactSize(str.size()) + str.size() * sizeof(str[0]);
  537. }
  538. template<typename Stream, typename C>
  539. void Serialize(Stream& os, const std::basic_string<C>& str, int, int)
  540. {
  541. WriteCompactSize(os, str.size());
  542. if (!str.empty())
  543. os.write((char*)&str[0], str.size() * sizeof(str[0]));
  544. }
  545. template<typename Stream, typename C>
  546. void Unserialize(Stream& is, std::basic_string<C>& str, int, int)
  547. {
  548. unsigned int nSize = ReadCompactSize(is);
  549. str.resize(nSize);
  550. if (nSize != 0)
  551. is.read((char*)&str[0], nSize * sizeof(str[0]));
  552. }
  553. /**
  554. * prevector
  555. */
  556. template<unsigned int N, typename T>
  557. unsigned int GetSerializeSize_impl(const prevector<N, T>& v, int nType, int nVersion, const unsigned char&)
  558. {
  559. return (GetSizeOfCompactSize(v.size()) + v.size() * sizeof(T));
  560. }
  561. template<unsigned int N, typename T, typename V>
  562. unsigned int GetSerializeSize_impl(const prevector<N, T>& v, int nType, int nVersion, const V&)
  563. {
  564. unsigned int nSize = GetSizeOfCompactSize(v.size());
  565. for (typename prevector<N, T>::const_iterator vi = v.begin(); vi != v.end(); ++vi)
  566. nSize += GetSerializeSize((*vi), nType, nVersion);
  567. return nSize;
  568. }
  569. template<unsigned int N, typename T>
  570. inline unsigned int GetSerializeSize(const prevector<N, T>& v, int nType, int nVersion)
  571. {
  572. return GetSerializeSize_impl(v, nType, nVersion, T());
  573. }
  574. template<typename Stream, unsigned int N, typename T>
  575. void Serialize_impl(Stream& os, const prevector<N, T>& v, int nType, int nVersion, const unsigned char&)
  576. {
  577. WriteCompactSize(os, v.size());
  578. if (!v.empty())
  579. os.write((char*)&v[0], v.size() * sizeof(T));
  580. }
  581. template<typename Stream, unsigned int N, typename T, typename V>
  582. void Serialize_impl(Stream& os, const prevector<N, T>& v, int nType, int nVersion, const V&)
  583. {
  584. WriteCompactSize(os, v.size());
  585. for (typename prevector<N, T>::const_iterator vi = v.begin(); vi != v.end(); ++vi)
  586. ::Serialize(os, (*vi), nType, nVersion);
  587. }
  588. template<typename Stream, unsigned int N, typename T>
  589. inline void Serialize(Stream& os, const prevector<N, T>& v, int nType, int nVersion)
  590. {
  591. Serialize_impl(os, v, nType, nVersion, T());
  592. }
  593. template<typename Stream, unsigned int N, typename T>
  594. void Unserialize_impl(Stream& is, prevector<N, T>& v, int nType, int nVersion, const unsigned char&)
  595. {
  596. // Limit size per read so bogus size value won't cause out of memory
  597. v.clear();
  598. unsigned int nSize = ReadCompactSize(is);
  599. unsigned int i = 0;
  600. while (i < nSize)
  601. {
  602. unsigned int blk = std::min(nSize - i, (unsigned int)(1 + 4999999 / sizeof(T)));
  603. v.resize(i + blk);
  604. is.read((char*)&v[i], blk * sizeof(T));
  605. i += blk;
  606. }
  607. }
  608. template<typename Stream, unsigned int N, typename T, typename V>
  609. void Unserialize_impl(Stream& is, prevector<N, T>& v, int nType, int nVersion, const V&)
  610. {
  611. v.clear();
  612. unsigned int nSize = ReadCompactSize(is);
  613. unsigned int i = 0;
  614. unsigned int nMid = 0;
  615. while (nMid < nSize)
  616. {
  617. nMid += 5000000 / sizeof(T);
  618. if (nMid > nSize)
  619. nMid = nSize;
  620. v.resize(nMid);
  621. for (; i < nMid; i++)
  622. Unserialize(is, v[i], nType, nVersion);
  623. }
  624. }
  625. template<typename Stream, unsigned int N, typename T>
  626. inline void Unserialize(Stream& is, prevector<N, T>& v, int nType, int nVersion)
  627. {
  628. Unserialize_impl(is, v, nType, nVersion, T());
  629. }
  630. /**
  631. * vector
  632. */
  633. template<typename T, typename A>
  634. unsigned int GetSerializeSize_impl(const std::vector<T, A>& v, int nType, int nVersion, const unsigned char&)
  635. {
  636. return (GetSizeOfCompactSize(v.size()) + v.size() * sizeof(T));
  637. }
  638. template<typename T, typename A, typename V>
  639. unsigned int GetSerializeSize_impl(const std::vector<T, A>& v, int nType, int nVersion, const V&)
  640. {
  641. unsigned int nSize = GetSizeOfCompactSize(v.size());
  642. for (typename std::vector<T, A>::const_iterator vi = v.begin(); vi != v.end(); ++vi)
  643. nSize += GetSerializeSize((*vi), nType, nVersion);
  644. return nSize;
  645. }
  646. template<typename T, typename A>
  647. inline unsigned int GetSerializeSize(const std::vector<T, A>& v, int nType, int nVersion)
  648. {
  649. return GetSerializeSize_impl(v, nType, nVersion, T());
  650. }
  651. template<typename Stream, typename T, typename A>
  652. void Serialize_impl(Stream& os, const std::vector<T, A>& v, int nType, int nVersion, const unsigned char&)
  653. {
  654. WriteCompactSize(os, v.size());
  655. if (!v.empty())
  656. os.write((char*)&v[0], v.size() * sizeof(T));
  657. }
  658. template<typename Stream, typename T, typename A, typename V>
  659. void Serialize_impl(Stream& os, const std::vector<T, A>& v, int nType, int nVersion, const V&)
  660. {
  661. WriteCompactSize(os, v.size());
  662. for (typename std::vector<T, A>::const_iterator vi = v.begin(); vi != v.end(); ++vi)
  663. ::Serialize(os, (*vi), nType, nVersion);
  664. }
  665. template<typename Stream, typename T, typename A>
  666. inline void Serialize(Stream& os, const std::vector<T, A>& v, int nType, int nVersion)
  667. {
  668. Serialize_impl(os, v, nType, nVersion, T());
  669. }
  670. template<typename Stream, typename T, typename A>
  671. void Unserialize_impl(Stream& is, std::vector<T, A>& v, int nType, int nVersion, const unsigned char&)
  672. {
  673. // Limit size per read so bogus size value won't cause out of memory
  674. v.clear();
  675. unsigned int nSize = ReadCompactSize(is);
  676. unsigned int i = 0;
  677. while (i < nSize)
  678. {
  679. unsigned int blk = std::min(nSize - i, (unsigned int)(1 + 4999999 / sizeof(T)));
  680. v.resize(i + blk);
  681. is.read((char*)&v[i], blk * sizeof(T));
  682. i += blk;
  683. }
  684. }
  685. template<typename Stream, typename T, typename A, typename V>
  686. void Unserialize_impl(Stream& is, std::vector<T, A>& v, int nType, int nVersion, const V&)
  687. {
  688. v.clear();
  689. unsigned int nSize = ReadCompactSize(is);
  690. unsigned int i = 0;
  691. unsigned int nMid = 0;
  692. while (nMid < nSize)
  693. {
  694. nMid += 5000000 / sizeof(T);
  695. if (nMid > nSize)
  696. nMid = nSize;
  697. v.resize(nMid);
  698. for (; i < nMid; i++)
  699. Unserialize(is, v[i], nType, nVersion);
  700. }
  701. }
  702. template<typename Stream, typename T, typename A>
  703. inline void Unserialize(Stream& is, std::vector<T, A>& v, int nType, int nVersion)
  704. {
  705. Unserialize_impl(is, v, nType, nVersion, T());
  706. }
  707. /**
  708. * pair
  709. */
  710. template<typename K, typename T>
  711. unsigned int GetSerializeSize(const std::pair<K, T>& item, int nType, int nVersion)
  712. {
  713. return GetSerializeSize(item.first, nType, nVersion) + GetSerializeSize(item.second, nType, nVersion);
  714. }
  715. template<typename Stream, typename K, typename T>
  716. void Serialize(Stream& os, const std::pair<K, T>& item, int nType, int nVersion)
  717. {
  718. Serialize(os, item.first, nType, nVersion);
  719. Serialize(os, item.second, nType, nVersion);
  720. }
  721. template<typename Stream, typename K, typename T>
  722. void Unserialize(Stream& is, std::pair<K, T>& item, int nType, int nVersion)
  723. {
  724. Unserialize(is, item.first, nType, nVersion);
  725. Unserialize(is, item.second, nType, nVersion);
  726. }
  727. /**
  728. * map
  729. */
  730. template<typename K, typename T, typename Pred, typename A>
  731. unsigned int GetSerializeSize(const std::map<K, T, Pred, A>& m, int nType, int nVersion)
  732. {
  733. unsigned int nSize = GetSizeOfCompactSize(m.size());
  734. for (typename std::map<K, T, Pred, A>::const_iterator mi = m.begin(); mi != m.end(); ++mi)
  735. nSize += GetSerializeSize((*mi), nType, nVersion);
  736. return nSize;
  737. }
  738. template<typename Stream, typename K, typename T, typename Pred, typename A>
  739. void Serialize(Stream& os, const std::map<K, T, Pred, A>& m, int nType, int nVersion)
  740. {
  741. WriteCompactSize(os, m.size());
  742. for (typename std::map<K, T, Pred, A>::const_iterator mi = m.begin(); mi != m.end(); ++mi)
  743. Serialize(os, (*mi), nType, nVersion);
  744. }
  745. template<typename Stream, typename K, typename T, typename Pred, typename A>
  746. void Unserialize(Stream& is, std::map<K, T, Pred, A>& m, int nType, int nVersion)
  747. {
  748. m.clear();
  749. unsigned int nSize = ReadCompactSize(is);
  750. typename std::map<K, T, Pred, A>::iterator mi = m.begin();
  751. for (unsigned int i = 0; i < nSize; i++)
  752. {
  753. std::pair<K, T> item;
  754. Unserialize(is, item, nType, nVersion);
  755. mi = m.insert(mi, item);
  756. }
  757. }
  758. /**
  759. * set
  760. */
  761. template<typename K, typename Pred, typename A>
  762. unsigned int GetSerializeSize(const std::set<K, Pred, A>& m, int nType, int nVersion)
  763. {
  764. unsigned int nSize = GetSizeOfCompactSize(m.size());
  765. for (typename std::set<K, Pred, A>::const_iterator it = m.begin(); it != m.end(); ++it)
  766. nSize += GetSerializeSize((*it), nType, nVersion);
  767. return nSize;
  768. }
  769. template<typename Stream, typename K, typename Pred, typename A>
  770. void Serialize(Stream& os, const std::set<K, Pred, A>& m, int nType, int nVersion)
  771. {
  772. WriteCompactSize(os, m.size());
  773. for (typename std::set<K, Pred, A>::const_iterator it = m.begin(); it != m.end(); ++it)
  774. Serialize(os, (*it), nType, nVersion);
  775. }
  776. template<typename Stream, typename K, typename Pred, typename A>
  777. void Unserialize(Stream& is, std::set<K, Pred, A>& m, int nType, int nVersion)
  778. {
  779. m.clear();
  780. unsigned int nSize = ReadCompactSize(is);
  781. typename std::set<K, Pred, A>::iterator it = m.begin();
  782. for (unsigned int i = 0; i < nSize; i++)
  783. {
  784. K key;
  785. Unserialize(is, key, nType, nVersion);
  786. it = m.insert(it, key);
  787. }
  788. }
  789. /**
  790. * Support for ADD_SERIALIZE_METHODS and READWRITE macro
  791. */
  792. struct CSerActionSerialize
  793. {
  794. bool ForRead() const { return false; }
  795. };
  796. struct CSerActionUnserialize
  797. {
  798. bool ForRead() const { return true; }
  799. };
  800. template<typename Stream, typename T>
  801. inline void SerReadWrite(Stream& s, const T& obj, int nType, int nVersion, CSerActionSerialize ser_action)
  802. {
  803. ::Serialize(s, obj, nType, nVersion);
  804. }
  805. template<typename Stream, typename T>
  806. inline void SerReadWrite(Stream& s, T& obj, int nType, int nVersion, CSerActionUnserialize ser_action)
  807. {
  808. ::Unserialize(s, obj, nType, nVersion);
  809. }
  810. class CSizeComputer
  811. {
  812. protected:
  813. size_t nSize;
  814. public:
  815. int nType;
  816. int nVersion;
  817. CSizeComputer(int nTypeIn, int nVersionIn) : nSize(0), nType(nTypeIn), nVersion(nVersionIn) {}
  818. CSizeComputer& write(const char *psz, size_t nSize)
  819. {
  820. this->nSize += nSize;
  821. return *this;
  822. }
  823. template<typename T>
  824. CSizeComputer& operator<<(const T& obj)
  825. {
  826. ::Serialize(*this, obj, nType, nVersion);
  827. return (*this);
  828. }
  829. size_t size() const {
  830. return nSize;
  831. }
  832. };
  833. #endif // BITCOIN_SERIALIZE_H