PageRenderTime 53ms CodeModel.GetById 17ms RepoModel.GetById 1ms app.codeStats 0ms

/src/serialize.h

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