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 46KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383
  1. // Copyright (c) 2009-2010 Satoshi Nakamoto
  2. // Copyright (c) 2009-2013 The Bitcoin developers
  3. // Distributed under the MIT/X11 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 "allocators.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 <boost/tuple/tuple.hpp>
  20. #include <boost/type_traits/is_fundamental.hpp>
  21. class CAutoFile;
  22. class CDataStream;
  23. class CScript;
  24. static const unsigned int MAX_SIZE = 0x02000000;
  25. // Used to bypass the rule against non-const reference to temporary
  26. // where it makes sense with wrappers such as CFlatData or CTxDB
  27. template<typename T>
  28. inline T& REF(const T& val)
  29. {
  30. return const_cast<T&>(val);
  31. }
  32. // Used to acquire a non-const pointer "this" to generate bodies
  33. // of const serialization operations from a template
  34. template<typename T>
  35. inline T* NCONST_PTR(const T* val)
  36. {
  37. return const_cast<T*>(val);
  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. /* Implement three methods for serializable objects. These are actually wrappers over
  80. * "SerializationOp" template, which implements the body of each class' serialization
  81. * code. Adding "ADD_SERIALIZE_METHODS" in the body of the class causes these wrappers to be
  82. * added as members. */
  83. #define ADD_SERIALIZE_METHODS \
  84. size_t GetSerializeSize(int nType, int nVersion) const { \
  85. CSizeComputer s(nType, nVersion); \
  86. NCONST_PTR(this)->SerializationOp(s, CSerActionSerialize(), nType, nVersion);\
  87. return s.size(); \
  88. } \
  89. template<typename Stream> \
  90. void Serialize(Stream& s, int nType, int nVersion) const { \
  91. NCONST_PTR(this)->SerializationOp(s, CSerActionSerialize(), nType, nVersion);\
  92. } \
  93. template<typename Stream> \
  94. void Unserialize(Stream& s, int nType, int nVersion) { \
  95. SerializationOp(s, CSerActionUnserialize(), nType, nVersion); \
  96. }
  97. //
  98. // Basic types
  99. //
  100. #define WRITEDATA(s, obj) s.write((char*)&(obj), sizeof(obj))
  101. #define READDATA(s, obj) s.read((char*)&(obj), sizeof(obj))
  102. inline unsigned int GetSerializeSize(char a, int, int=0) { return sizeof(a); }
  103. inline unsigned int GetSerializeSize(signed char a, int, int=0) { return sizeof(a); }
  104. inline unsigned int GetSerializeSize(unsigned char a, int, int=0) { return sizeof(a); }
  105. inline unsigned int GetSerializeSize(signed short a, int, int=0) { return sizeof(a); }
  106. inline unsigned int GetSerializeSize(unsigned short a, int, int=0) { return sizeof(a); }
  107. inline unsigned int GetSerializeSize(signed int a, int, int=0) { return sizeof(a); }
  108. inline unsigned int GetSerializeSize(unsigned int a, int, int=0) { return sizeof(a); }
  109. inline unsigned int GetSerializeSize(signed long a, int, int=0) { return sizeof(a); }
  110. inline unsigned int GetSerializeSize(unsigned long a, int, int=0) { return sizeof(a); }
  111. inline unsigned int GetSerializeSize(signed long long a, int, int=0) { return sizeof(a); }
  112. inline unsigned int GetSerializeSize(unsigned long long a, int, int=0) { return sizeof(a); }
  113. inline unsigned int GetSerializeSize(float a, int, int=0) { return sizeof(a); }
  114. inline unsigned int GetSerializeSize(double a, int, int=0) { return sizeof(a); }
  115. template<typename Stream> inline void Serialize(Stream& s, char a, int, int=0) { WRITEDATA(s, a); }
  116. template<typename Stream> inline void Serialize(Stream& s, signed char a, int, int=0) { WRITEDATA(s, a); }
  117. template<typename Stream> inline void Serialize(Stream& s, unsigned char a, int, int=0) { WRITEDATA(s, a); }
  118. template<typename Stream> inline void Serialize(Stream& s, signed short a, int, int=0) { WRITEDATA(s, a); }
  119. template<typename Stream> inline void Serialize(Stream& s, unsigned short a, int, int=0) { WRITEDATA(s, a); }
  120. template<typename Stream> inline void Serialize(Stream& s, signed int a, int, int=0) { WRITEDATA(s, a); }
  121. template<typename Stream> inline void Serialize(Stream& s, unsigned int a, int, int=0) { WRITEDATA(s, a); }
  122. template<typename Stream> inline void Serialize(Stream& s, signed long a, int, int=0) { WRITEDATA(s, a); }
  123. template<typename Stream> inline void Serialize(Stream& s, unsigned long a, int, int=0) { WRITEDATA(s, a); }
  124. template<typename Stream> inline void Serialize(Stream& s, signed long long a, int, int=0) { WRITEDATA(s, a); }
  125. template<typename Stream> inline void Serialize(Stream& s, unsigned long long a, int, int=0) { WRITEDATA(s, a); }
  126. template<typename Stream> inline void Serialize(Stream& s, float a, int, int=0) { WRITEDATA(s, a); }
  127. template<typename Stream> inline void Serialize(Stream& s, double a, int, int=0) { WRITEDATA(s, a); }
  128. template<typename Stream> inline void Unserialize(Stream& s, char& a, int, int=0) { READDATA(s, a); }
  129. template<typename Stream> inline void Unserialize(Stream& s, signed char& a, int, int=0) { READDATA(s, a); }
  130. template<typename Stream> inline void Unserialize(Stream& s, unsigned char& a, int, int=0) { READDATA(s, a); }
  131. template<typename Stream> inline void Unserialize(Stream& s, signed short& a, int, int=0) { READDATA(s, a); }
  132. template<typename Stream> inline void Unserialize(Stream& s, unsigned short& a, int, int=0) { READDATA(s, a); }
  133. template<typename Stream> inline void Unserialize(Stream& s, signed int& a, int, int=0) { READDATA(s, a); }
  134. template<typename Stream> inline void Unserialize(Stream& s, unsigned int& a, int, int=0) { READDATA(s, a); }
  135. template<typename Stream> inline void Unserialize(Stream& s, signed long& a, int, int=0) { READDATA(s, a); }
  136. template<typename Stream> inline void Unserialize(Stream& s, unsigned long& a, int, int=0) { READDATA(s, a); }
  137. template<typename Stream> inline void Unserialize(Stream& s, signed long long& a, int, int=0) { READDATA(s, a); }
  138. template<typename Stream> inline void Unserialize(Stream& s, unsigned long long& a, int, int=0) { READDATA(s, a); }
  139. template<typename Stream> inline void Unserialize(Stream& s, float& a, int, int=0) { READDATA(s, a); }
  140. template<typename Stream> inline void Unserialize(Stream& s, double& a, int, int=0) { READDATA(s, a); }
  141. inline unsigned int GetSerializeSize(bool a, int, int=0) { return sizeof(char); }
  142. template<typename Stream> inline void Serialize(Stream& s, bool a, int, int=0) { char f=a; WRITEDATA(s, f); }
  143. template<typename Stream> inline void Unserialize(Stream& s, bool& a, int, int=0) { char f; READDATA(s, f); a=f; }
  144. //
  145. // Compact size
  146. // size < 253 -- 1 byte
  147. // size <= USHRT_MAX -- 3 bytes (253 + 2 bytes)
  148. // size <= UINT_MAX -- 5 bytes (254 + 4 bytes)
  149. // size > UINT_MAX -- 9 bytes (255 + 8 bytes)
  150. //
  151. inline unsigned int GetSizeOfCompactSize(uint64_t nSize)
  152. {
  153. if (nSize < 253) return sizeof(unsigned char);
  154. else if (nSize <= std::numeric_limits<unsigned short>::max()) return sizeof(unsigned char) + sizeof(unsigned short);
  155. else if (nSize <= std::numeric_limits<unsigned int>::max()) return sizeof(unsigned char) + sizeof(unsigned int);
  156. else return sizeof(unsigned char) + sizeof(uint64_t);
  157. }
  158. template<typename Stream>
  159. void WriteCompactSize(Stream& os, uint64_t nSize)
  160. {
  161. if (nSize < 253)
  162. {
  163. unsigned char chSize = nSize;
  164. WRITEDATA(os, chSize);
  165. }
  166. else if (nSize <= std::numeric_limits<unsigned short>::max())
  167. {
  168. unsigned char chSize = 253;
  169. unsigned short xSize = nSize;
  170. WRITEDATA(os, chSize);
  171. WRITEDATA(os, xSize);
  172. }
  173. else if (nSize <= std::numeric_limits<unsigned int>::max())
  174. {
  175. unsigned char chSize = 254;
  176. unsigned int xSize = nSize;
  177. WRITEDATA(os, chSize);
  178. WRITEDATA(os, xSize);
  179. }
  180. else
  181. {
  182. unsigned char chSize = 255;
  183. uint64_t xSize = nSize;
  184. WRITEDATA(os, chSize);
  185. WRITEDATA(os, xSize);
  186. }
  187. return;
  188. }
  189. template<typename Stream>
  190. uint64_t ReadCompactSize(Stream& is)
  191. {
  192. unsigned char chSize;
  193. READDATA(is, chSize);
  194. uint64_t nSizeRet = 0;
  195. if (chSize < 253)
  196. {
  197. nSizeRet = chSize;
  198. }
  199. else if (chSize == 253)
  200. {
  201. unsigned short xSize;
  202. READDATA(is, xSize);
  203. nSizeRet = xSize;
  204. if (nSizeRet < 253)
  205. throw std::ios_base::failure("non-canonical ReadCompactSize()");
  206. }
  207. else if (chSize == 254)
  208. {
  209. unsigned int xSize;
  210. READDATA(is, xSize);
  211. nSizeRet = xSize;
  212. if (nSizeRet < 0x10000u)
  213. throw std::ios_base::failure("non-canonical ReadCompactSize()");
  214. }
  215. else
  216. {
  217. uint64_t xSize;
  218. READDATA(is, xSize);
  219. nSizeRet = xSize;
  220. if (nSizeRet < 0x100000000LLu)
  221. throw std::ios_base::failure("non-canonical ReadCompactSize()");
  222. }
  223. if (nSizeRet > (uint64_t)MAX_SIZE)
  224. throw std::ios_base::failure("ReadCompactSize() : size too large");
  225. return nSizeRet;
  226. }
  227. // Variable-length integers: bytes are a MSB base-128 encoding of the number.
  228. // The high bit in each byte signifies whether another digit follows. To make
  229. // the encoding is one-to-one, one is subtracted from all but the last digit.
  230. // Thus, the byte sequence a[] with length len, where all but the last byte
  231. // has bit 128 set, encodes the number:
  232. //
  233. // (a[len-1] & 0x7F) + sum(i=1..len-1, 128^i*((a[len-i-1] & 0x7F)+1))
  234. //
  235. // Properties:
  236. // * Very small (0-127: 1 byte, 128-16511: 2 bytes, 16512-2113663: 3 bytes)
  237. // * Every integer has exactly one encoding
  238. // * Encoding does not depend on size of original integer type
  239. // * No redundancy: every (infinite) byte sequence corresponds to a list
  240. // of encoded integers.
  241. //
  242. // 0: [0x00] 256: [0x81 0x00]
  243. // 1: [0x01] 16383: [0xFE 0x7F]
  244. // 127: [0x7F] 16384: [0xFF 0x00]
  245. // 128: [0x80 0x00] 16511: [0x80 0xFF 0x7F]
  246. // 255: [0x80 0x7F] 65535: [0x82 0xFD 0x7F]
  247. // 2^32: [0x8E 0xFE 0xFE 0xFF 0x00]
  248. template<typename I>
  249. inline unsigned int GetSizeOfVarInt(I n)
  250. {
  251. int nRet = 0;
  252. while(true) {
  253. nRet++;
  254. if (n <= 0x7F)
  255. break;
  256. n = (n >> 7) - 1;
  257. }
  258. return nRet;
  259. }
  260. template<typename Stream, typename I>
  261. void WriteVarInt(Stream& os, I n)
  262. {
  263. unsigned char tmp[(sizeof(n)*8+6)/7];
  264. int len=0;
  265. while(true) {
  266. tmp[len] = (n & 0x7F) | (len ? 0x80 : 0x00);
  267. if (n <= 0x7F)
  268. break;
  269. n = (n >> 7) - 1;
  270. len++;
  271. }
  272. do {
  273. WRITEDATA(os, tmp[len]);
  274. } while(len--);
  275. }
  276. template<typename Stream, typename I>
  277. I ReadVarInt(Stream& is)
  278. {
  279. I n = 0;
  280. while(true) {
  281. unsigned char chData;
  282. READDATA(is, chData);
  283. n = (n << 7) | (chData & 0x7F);
  284. if (chData & 0x80)
  285. n++;
  286. else
  287. return n;
  288. }
  289. }
  290. #define FLATDATA(obj) REF(CFlatData((char*)&(obj), (char*)&(obj) + sizeof(obj)))
  291. #define VARINT(obj) REF(WrapVarInt(REF(obj)))
  292. #define LIMITED_STRING(obj,n) REF(LimitedString< n >(REF(obj)))
  293. /** Wrapper for serializing arrays and POD.
  294. */
  295. class CFlatData
  296. {
  297. protected:
  298. char* pbegin;
  299. char* pend;
  300. public:
  301. CFlatData(void* pbeginIn, void* pendIn) : pbegin((char*)pbeginIn), pend((char*)pendIn) { }
  302. template <class T, class TAl>
  303. explicit CFlatData(std::vector<T,TAl> &v)
  304. {
  305. pbegin = (char*)begin_ptr(v);
  306. pend = (char*)end_ptr(v);
  307. }
  308. char* begin() { return pbegin; }
  309. const char* begin() const { return pbegin; }
  310. char* end() { return pend; }
  311. const char* end() const { return pend; }
  312. unsigned int GetSerializeSize(int, int=0) const
  313. {
  314. return pend - pbegin;
  315. }
  316. template<typename Stream>
  317. void Serialize(Stream& s, int, int=0) const
  318. {
  319. s.write(pbegin, pend - pbegin);
  320. }
  321. template<typename Stream>
  322. void Unserialize(Stream& s, int, int=0)
  323. {
  324. s.read(pbegin, pend - pbegin);
  325. }
  326. };
  327. template<typename I>
  328. class CVarInt
  329. {
  330. protected:
  331. I &n;
  332. public:
  333. CVarInt(I& nIn) : n(nIn) { }
  334. unsigned int GetSerializeSize(int, int) const {
  335. return GetSizeOfVarInt<I>(n);
  336. }
  337. template<typename Stream>
  338. void Serialize(Stream &s, int, int) const {
  339. WriteVarInt<Stream,I>(s, n);
  340. }
  341. template<typename Stream>
  342. void Unserialize(Stream& s, int, int) {
  343. n = ReadVarInt<Stream,I>(s);
  344. }
  345. };
  346. template<size_t Limit>
  347. class LimitedString
  348. {
  349. protected:
  350. std::string& string;
  351. public:
  352. LimitedString(std::string& string) : string(string) {}
  353. template<typename Stream>
  354. void Unserialize(Stream& s, int, int=0)
  355. {
  356. size_t size = ReadCompactSize(s);
  357. if (size > Limit) {
  358. throw std::ios_base::failure("String length limit exceeded");
  359. }
  360. string.resize(size);
  361. if (size != 0)
  362. s.read((char*)&string[0], size);
  363. }
  364. template<typename Stream>
  365. void Serialize(Stream& s, int, int=0) const
  366. {
  367. WriteCompactSize(s, string.size());
  368. if (!string.empty())
  369. s.write((char*)&string[0], string.size());
  370. }
  371. unsigned int GetSerializeSize(int, int=0) const
  372. {
  373. return GetSizeOfCompactSize(string.size()) + string.size();
  374. }
  375. };
  376. template<typename I>
  377. CVarInt<I> WrapVarInt(I& n) { return CVarInt<I>(n); }
  378. //
  379. // Forward declarations
  380. //
  381. // string
  382. template<typename C> unsigned int GetSerializeSize(const std::basic_string<C>& str, int, int=0);
  383. template<typename Stream, typename C> void Serialize(Stream& os, const std::basic_string<C>& str, int, int=0);
  384. template<typename Stream, typename C> void Unserialize(Stream& is, std::basic_string<C>& str, int, int=0);
  385. // vector
  386. template<typename T, typename A> unsigned int GetSerializeSize_impl(const std::vector<T, A>& v, int nType, int nVersion, const boost::true_type&);
  387. template<typename T, typename A> unsigned int GetSerializeSize_impl(const std::vector<T, A>& v, int nType, int nVersion, const boost::false_type&);
  388. template<typename T, typename A> inline unsigned int GetSerializeSize(const std::vector<T, A>& v, int nType, int nVersion);
  389. template<typename Stream, typename T, typename A> void Serialize_impl(Stream& os, const std::vector<T, A>& v, int nType, int nVersion, const boost::true_type&);
  390. template<typename Stream, typename T, typename A> void Serialize_impl(Stream& os, const std::vector<T, A>& v, int nType, int nVersion, const boost::false_type&);
  391. template<typename Stream, typename T, typename A> inline void Serialize(Stream& os, const std::vector<T, A>& v, int nType, int nVersion);
  392. template<typename Stream, typename T, typename A> void Unserialize_impl(Stream& is, std::vector<T, A>& v, int nType, int nVersion, const boost::true_type&);
  393. template<typename Stream, typename T, typename A> void Unserialize_impl(Stream& is, std::vector<T, A>& v, int nType, int nVersion, const boost::false_type&);
  394. template<typename Stream, typename T, typename A> inline void Unserialize(Stream& is, std::vector<T, A>& v, int nType, int nVersion);
  395. // others derived from vector
  396. extern inline unsigned int GetSerializeSize(const CScript& v, int nType, int nVersion);
  397. template<typename Stream> void Serialize(Stream& os, const CScript& v, int nType, int nVersion);
  398. template<typename Stream> void Unserialize(Stream& is, CScript& v, int nType, int nVersion);
  399. // pair
  400. template<typename K, typename T> unsigned int GetSerializeSize(const std::pair<K, T>& item, int nType, int nVersion);
  401. template<typename Stream, typename K, typename T> void Serialize(Stream& os, const std::pair<K, T>& item, int nType, int nVersion);
  402. template<typename Stream, typename K, typename T> void Unserialize(Stream& is, std::pair<K, T>& item, int nType, int nVersion);
  403. // 3 tuple
  404. template<typename T0, typename T1, typename T2> unsigned int GetSerializeSize(const boost::tuple<T0, T1, T2>& item, int nType, int nVersion);
  405. template<typename Stream, typename T0, typename T1, typename T2> void Serialize(Stream& os, const boost::tuple<T0, T1, T2>& item, int nType, int nVersion);
  406. template<typename Stream, typename T0, typename T1, typename T2> void Unserialize(Stream& is, boost::tuple<T0, T1, T2>& item, int nType, int nVersion);
  407. // 4 tuple
  408. template<typename T0, typename T1, typename T2, typename T3> unsigned int GetSerializeSize(const boost::tuple<T0, T1, T2, T3>& item, int nType, int nVersion);
  409. template<typename Stream, typename T0, typename T1, typename T2, typename T3> void Serialize(Stream& os, const boost::tuple<T0, T1, T2, T3>& item, int nType, int nVersion);
  410. template<typename Stream, typename T0, typename T1, typename T2, typename T3> void Unserialize(Stream& is, boost::tuple<T0, T1, T2, T3>& item, int nType, int nVersion);
  411. // map
  412. template<typename K, typename T, typename Pred, typename A> unsigned int GetSerializeSize(const std::map<K, T, Pred, A>& m, int nType, int nVersion);
  413. 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);
  414. 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);
  415. // set
  416. template<typename K, typename Pred, typename A> unsigned int GetSerializeSize(const std::set<K, Pred, A>& m, int nType, int nVersion);
  417. template<typename Stream, typename K, typename Pred, typename A> void Serialize(Stream& os, const std::set<K, Pred, A>& m, int nType, int nVersion);
  418. template<typename Stream, typename K, typename Pred, typename A> void Unserialize(Stream& is, std::set<K, Pred, A>& m, int nType, int nVersion);
  419. //
  420. // If none of the specialized versions above matched, default to calling member function.
  421. // "int nType" is changed to "long nType" to keep from getting an ambiguous overload error.
  422. // The compiler will only cast int to long if none of the other templates matched.
  423. // Thanks to Boost serialization for this idea.
  424. //
  425. template<typename T>
  426. inline unsigned int GetSerializeSize(const T& a, long nType, int nVersion)
  427. {
  428. return a.GetSerializeSize((int)nType, nVersion);
  429. }
  430. template<typename Stream, typename T>
  431. inline void Serialize(Stream& os, const T& a, long nType, int nVersion)
  432. {
  433. a.Serialize(os, (int)nType, nVersion);
  434. }
  435. template<typename Stream, typename T>
  436. inline void Unserialize(Stream& is, T& a, long nType, int nVersion)
  437. {
  438. a.Unserialize(is, (int)nType, nVersion);
  439. }
  440. //
  441. // string
  442. //
  443. template<typename C>
  444. unsigned int GetSerializeSize(const std::basic_string<C>& str, int, int)
  445. {
  446. return GetSizeOfCompactSize(str.size()) + str.size() * sizeof(str[0]);
  447. }
  448. template<typename Stream, typename C>
  449. void Serialize(Stream& os, const std::basic_string<C>& str, int, int)
  450. {
  451. WriteCompactSize(os, str.size());
  452. if (!str.empty())
  453. os.write((char*)&str[0], str.size() * sizeof(str[0]));
  454. }
  455. template<typename Stream, typename C>
  456. void Unserialize(Stream& is, std::basic_string<C>& str, int, int)
  457. {
  458. unsigned int nSize = ReadCompactSize(is);
  459. str.resize(nSize);
  460. if (nSize != 0)
  461. is.read((char*)&str[0], nSize * sizeof(str[0]));
  462. }
  463. //
  464. // vector
  465. //
  466. template<typename T, typename A>
  467. unsigned int GetSerializeSize_impl(const std::vector<T, A>& v, int nType, int nVersion, const boost::true_type&)
  468. {
  469. return (GetSizeOfCompactSize(v.size()) + v.size() * sizeof(T));
  470. }
  471. template<typename T, typename A>
  472. unsigned int GetSerializeSize_impl(const std::vector<T, A>& v, int nType, int nVersion, const boost::false_type&)
  473. {
  474. unsigned int nSize = GetSizeOfCompactSize(v.size());
  475. for (typename std::vector<T, A>::const_iterator vi = v.begin(); vi != v.end(); ++vi)
  476. nSize += GetSerializeSize((*vi), nType, nVersion);
  477. return nSize;
  478. }
  479. template<typename T, typename A>
  480. inline unsigned int GetSerializeSize(const std::vector<T, A>& v, int nType, int nVersion)
  481. {
  482. return GetSerializeSize_impl(v, nType, nVersion, boost::is_fundamental<T>());
  483. }
  484. template<typename Stream, typename T, typename A>
  485. void Serialize_impl(Stream& os, const std::vector<T, A>& v, int nType, int nVersion, const boost::true_type&)
  486. {
  487. WriteCompactSize(os, v.size());
  488. if (!v.empty())
  489. os.write((char*)&v[0], v.size() * sizeof(T));
  490. }
  491. template<typename Stream, typename T, typename A>
  492. void Serialize_impl(Stream& os, const std::vector<T, A>& v, int nType, int nVersion, const boost::false_type&)
  493. {
  494. WriteCompactSize(os, v.size());
  495. for (typename std::vector<T, A>::const_iterator vi = v.begin(); vi != v.end(); ++vi)
  496. ::Serialize(os, (*vi), nType, nVersion);
  497. }
  498. template<typename Stream, typename T, typename A>
  499. inline void Serialize(Stream& os, const std::vector<T, A>& v, int nType, int nVersion)
  500. {
  501. Serialize_impl(os, v, nType, nVersion, boost::is_fundamental<T>());
  502. }
  503. template<typename Stream, typename T, typename A>
  504. void Unserialize_impl(Stream& is, std::vector<T, A>& v, int nType, int nVersion, const boost::true_type&)
  505. {
  506. // Limit size per read so bogus size value won't cause out of memory
  507. v.clear();
  508. unsigned int nSize = ReadCompactSize(is);
  509. unsigned int i = 0;
  510. while (i < nSize)
  511. {
  512. unsigned int blk = std::min(nSize - i, (unsigned int)(1 + 4999999 / sizeof(T)));
  513. v.resize(i + blk);
  514. is.read((char*)&v[i], blk * sizeof(T));
  515. i += blk;
  516. }
  517. }
  518. template<typename Stream, typename T, typename A>
  519. void Unserialize_impl(Stream& is, std::vector<T, A>& v, int nType, int nVersion, const boost::false_type&)
  520. {
  521. v.clear();
  522. unsigned int nSize = ReadCompactSize(is);
  523. unsigned int i = 0;
  524. unsigned int nMid = 0;
  525. while (nMid < nSize)
  526. {
  527. nMid += 5000000 / sizeof(T);
  528. if (nMid > nSize)
  529. nMid = nSize;
  530. v.resize(nMid);
  531. for (; i < nMid; i++)
  532. Unserialize(is, v[i], nType, nVersion);
  533. }
  534. }
  535. template<typename Stream, typename T, typename A>
  536. inline void Unserialize(Stream& is, std::vector<T, A>& v, int nType, int nVersion)
  537. {
  538. Unserialize_impl(is, v, nType, nVersion, boost::is_fundamental<T>());
  539. }
  540. //
  541. // others derived from vector
  542. //
  543. inline unsigned int GetSerializeSize(const CScript& v, int nType, int nVersion)
  544. {
  545. return GetSerializeSize((const std::vector<unsigned char>&)v, nType, nVersion);
  546. }
  547. template<typename Stream>
  548. void Serialize(Stream& os, const CScript& v, int nType, int nVersion)
  549. {
  550. Serialize(os, (const std::vector<unsigned char>&)v, nType, nVersion);
  551. }
  552. template<typename Stream>
  553. void Unserialize(Stream& is, CScript& v, int nType, int nVersion)
  554. {
  555. Unserialize(is, (std::vector<unsigned char>&)v, nType, nVersion);
  556. }
  557. //
  558. // pair
  559. //
  560. template<typename K, typename T>
  561. unsigned int GetSerializeSize(const std::pair<K, T>& item, int nType, int nVersion)
  562. {
  563. return GetSerializeSize(item.first, nType, nVersion) + GetSerializeSize(item.second, nType, nVersion);
  564. }
  565. template<typename Stream, typename K, typename T>
  566. void Serialize(Stream& os, const std::pair<K, T>& item, int nType, int nVersion)
  567. {
  568. Serialize(os, item.first, nType, nVersion);
  569. Serialize(os, item.second, nType, nVersion);
  570. }
  571. template<typename Stream, typename K, typename T>
  572. void Unserialize(Stream& is, std::pair<K, T>& item, int nType, int nVersion)
  573. {
  574. Unserialize(is, item.first, nType, nVersion);
  575. Unserialize(is, item.second, nType, nVersion);
  576. }
  577. //
  578. // 3 tuple
  579. //
  580. template<typename T0, typename T1, typename T2>
  581. unsigned int GetSerializeSize(const boost::tuple<T0, T1, T2>& item, int nType, int nVersion)
  582. {
  583. unsigned int nSize = 0;
  584. nSize += GetSerializeSize(boost::get<0>(item), nType, nVersion);
  585. nSize += GetSerializeSize(boost::get<1>(item), nType, nVersion);
  586. nSize += GetSerializeSize(boost::get<2>(item), nType, nVersion);
  587. return nSize;
  588. }
  589. template<typename Stream, typename T0, typename T1, typename T2>
  590. void Serialize(Stream& os, const boost::tuple<T0, T1, T2>& item, int nType, int nVersion)
  591. {
  592. Serialize(os, boost::get<0>(item), nType, nVersion);
  593. Serialize(os, boost::get<1>(item), nType, nVersion);
  594. Serialize(os, boost::get<2>(item), nType, nVersion);
  595. }
  596. template<typename Stream, typename T0, typename T1, typename T2>
  597. void Unserialize(Stream& is, boost::tuple<T0, T1, T2>& item, int nType, int nVersion)
  598. {
  599. Unserialize(is, boost::get<0>(item), nType, nVersion);
  600. Unserialize(is, boost::get<1>(item), nType, nVersion);
  601. Unserialize(is, boost::get<2>(item), nType, nVersion);
  602. }
  603. //
  604. // 4 tuple
  605. //
  606. template<typename T0, typename T1, typename T2, typename T3>
  607. unsigned int GetSerializeSize(const boost::tuple<T0, T1, T2, T3>& item, int nType, int nVersion)
  608. {
  609. unsigned int nSize = 0;
  610. nSize += GetSerializeSize(boost::get<0>(item), nType, nVersion);
  611. nSize += GetSerializeSize(boost::get<1>(item), nType, nVersion);
  612. nSize += GetSerializeSize(boost::get<2>(item), nType, nVersion);
  613. nSize += GetSerializeSize(boost::get<3>(item), nType, nVersion);
  614. return nSize;
  615. }
  616. template<typename Stream, typename T0, typename T1, typename T2, typename T3>
  617. void Serialize(Stream& os, const boost::tuple<T0, T1, T2, T3>& item, int nType, int nVersion)
  618. {
  619. Serialize(os, boost::get<0>(item), nType, nVersion);
  620. Serialize(os, boost::get<1>(item), nType, nVersion);
  621. Serialize(os, boost::get<2>(item), nType, nVersion);
  622. Serialize(os, boost::get<3>(item), nType, nVersion);
  623. }
  624. template<typename Stream, typename T0, typename T1, typename T2, typename T3>
  625. void Unserialize(Stream& is, boost::tuple<T0, T1, T2, T3>& item, int nType, int nVersion)
  626. {
  627. Unserialize(is, boost::get<0>(item), nType, nVersion);
  628. Unserialize(is, boost::get<1>(item), nType, nVersion);
  629. Unserialize(is, boost::get<2>(item), nType, nVersion);
  630. Unserialize(is, boost::get<3>(item), nType, nVersion);
  631. }
  632. //
  633. // map
  634. //
  635. template<typename K, typename T, typename Pred, typename A>
  636. unsigned int GetSerializeSize(const std::map<K, T, Pred, A>& m, int nType, int nVersion)
  637. {
  638. unsigned int nSize = GetSizeOfCompactSize(m.size());
  639. for (typename std::map<K, T, Pred, A>::const_iterator mi = m.begin(); mi != m.end(); ++mi)
  640. nSize += GetSerializeSize((*mi), nType, nVersion);
  641. return nSize;
  642. }
  643. template<typename Stream, typename K, typename T, typename Pred, typename A>
  644. void Serialize(Stream& os, const std::map<K, T, Pred, A>& m, int nType, int nVersion)
  645. {
  646. WriteCompactSize(os, m.size());
  647. for (typename std::map<K, T, Pred, A>::const_iterator mi = m.begin(); mi != m.end(); ++mi)
  648. Serialize(os, (*mi), nType, nVersion);
  649. }
  650. template<typename Stream, typename K, typename T, typename Pred, typename A>
  651. void Unserialize(Stream& is, std::map<K, T, Pred, A>& m, int nType, int nVersion)
  652. {
  653. m.clear();
  654. unsigned int nSize = ReadCompactSize(is);
  655. typename std::map<K, T, Pred, A>::iterator mi = m.begin();
  656. for (unsigned int i = 0; i < nSize; i++)
  657. {
  658. std::pair<K, T> item;
  659. Unserialize(is, item, nType, nVersion);
  660. mi = m.insert(mi, item);
  661. }
  662. }
  663. //
  664. // set
  665. //
  666. template<typename K, typename Pred, typename A>
  667. unsigned int GetSerializeSize(const std::set<K, Pred, A>& m, int nType, int nVersion)
  668. {
  669. unsigned int nSize = GetSizeOfCompactSize(m.size());
  670. for (typename std::set<K, Pred, A>::const_iterator it = m.begin(); it != m.end(); ++it)
  671. nSize += GetSerializeSize((*it), nType, nVersion);
  672. return nSize;
  673. }
  674. template<typename Stream, typename K, typename Pred, typename A>
  675. void Serialize(Stream& os, const std::set<K, Pred, A>& m, int nType, int nVersion)
  676. {
  677. WriteCompactSize(os, m.size());
  678. for (typename std::set<K, Pred, A>::const_iterator it = m.begin(); it != m.end(); ++it)
  679. Serialize(os, (*it), nType, nVersion);
  680. }
  681. template<typename Stream, typename K, typename Pred, typename A>
  682. void Unserialize(Stream& is, std::set<K, Pred, A>& m, int nType, int nVersion)
  683. {
  684. m.clear();
  685. unsigned int nSize = ReadCompactSize(is);
  686. typename std::set<K, Pred, A>::iterator it = m.begin();
  687. for (unsigned int i = 0; i < nSize; i++)
  688. {
  689. K key;
  690. Unserialize(is, key, nType, nVersion);
  691. it = m.insert(it, key);
  692. }
  693. }
  694. //
  695. // Support for ADD_SERIALIZE_METHODS and READWRITE macro
  696. //
  697. struct CSerActionSerialize
  698. {
  699. bool ForRead() const { return false; }
  700. };
  701. struct CSerActionUnserialize
  702. {
  703. bool ForRead() const { return true; }
  704. };
  705. template<typename Stream, typename T>
  706. inline void SerReadWrite(Stream& s, const T& obj, int nType, int nVersion, CSerActionSerialize ser_action)
  707. {
  708. ::Serialize(s, obj, nType, nVersion);
  709. }
  710. template<typename Stream, typename T>
  711. inline void SerReadWrite(Stream& s, T& obj, int nType, int nVersion, CSerActionUnserialize ser_action)
  712. {
  713. ::Unserialize(s, obj, nType, nVersion);
  714. }
  715. typedef std::vector<char, zero_after_free_allocator<char> > CSerializeData;
  716. class CSizeComputer
  717. {
  718. protected:
  719. size_t nSize;
  720. public:
  721. int nType;
  722. int nVersion;
  723. CSizeComputer(int nTypeIn, int nVersionIn) : nSize(0), nType(nTypeIn), nVersion(nVersionIn) {}
  724. CSizeComputer& write(const char *psz, size_t nSize)
  725. {
  726. this->nSize += nSize;
  727. return *this;
  728. }
  729. template<typename T>
  730. CSizeComputer& operator<<(const T& obj)
  731. {
  732. ::Serialize(*this, obj, nType, nVersion);
  733. return (*this);
  734. }
  735. size_t size() const {
  736. return nSize;
  737. }
  738. };
  739. /** Double ended buffer combining vector and stream-like interfaces.
  740. *
  741. * >> and << read and write unformatted data using the above serialization templates.
  742. * Fills with data in linear time; some stringstream implementations take N^2 time.
  743. */
  744. class CDataStream
  745. {
  746. protected:
  747. typedef CSerializeData vector_type;
  748. vector_type vch;
  749. unsigned int nReadPos;
  750. public:
  751. int nType;
  752. int nVersion;
  753. typedef vector_type::allocator_type allocator_type;
  754. typedef vector_type::size_type size_type;
  755. typedef vector_type::difference_type difference_type;
  756. typedef vector_type::reference reference;
  757. typedef vector_type::const_reference const_reference;
  758. typedef vector_type::value_type value_type;
  759. typedef vector_type::iterator iterator;
  760. typedef vector_type::const_iterator const_iterator;
  761. typedef vector_type::reverse_iterator reverse_iterator;
  762. explicit CDataStream(int nTypeIn, int nVersionIn)
  763. {
  764. Init(nTypeIn, nVersionIn);
  765. }
  766. CDataStream(const_iterator pbegin, const_iterator pend, int nTypeIn, int nVersionIn) : vch(pbegin, pend)
  767. {
  768. Init(nTypeIn, nVersionIn);
  769. }
  770. #if !defined(_MSC_VER) || _MSC_VER >= 1300
  771. CDataStream(const char* pbegin, const char* pend, int nTypeIn, int nVersionIn) : vch(pbegin, pend)
  772. {
  773. Init(nTypeIn, nVersionIn);
  774. }
  775. #endif
  776. CDataStream(const vector_type& vchIn, int nTypeIn, int nVersionIn) : vch(vchIn.begin(), vchIn.end())
  777. {
  778. Init(nTypeIn, nVersionIn);
  779. }
  780. CDataStream(const std::vector<char>& vchIn, int nTypeIn, int nVersionIn) : vch(vchIn.begin(), vchIn.end())
  781. {
  782. Init(nTypeIn, nVersionIn);
  783. }
  784. CDataStream(const std::vector<unsigned char>& vchIn, int nTypeIn, int nVersionIn) : vch(vchIn.begin(), vchIn.end())
  785. {
  786. Init(nTypeIn, nVersionIn);
  787. }
  788. void Init(int nTypeIn, int nVersionIn)
  789. {
  790. nReadPos = 0;
  791. nType = nTypeIn;
  792. nVersion = nVersionIn;
  793. }
  794. CDataStream& operator+=(const CDataStream& b)
  795. {
  796. vch.insert(vch.end(), b.begin(), b.end());
  797. return *this;
  798. }
  799. friend CDataStream operator+(const CDataStream& a, const CDataStream& b)
  800. {
  801. CDataStream ret = a;
  802. ret += b;
  803. return (ret);
  804. }
  805. std::string str() const
  806. {
  807. return (std::string(begin(), end()));
  808. }
  809. //
  810. // Vector subset
  811. //
  812. const_iterator begin() const { return vch.begin() + nReadPos; }
  813. iterator begin() { return vch.begin() + nReadPos; }
  814. const_iterator end() const { return vch.end(); }
  815. iterator end() { return vch.end(); }
  816. size_type size() const { return vch.size() - nReadPos; }
  817. bool empty() const { return vch.size() == nReadPos; }
  818. void resize(size_type n, value_type c=0) { vch.resize(n + nReadPos, c); }
  819. void reserve(size_type n) { vch.reserve(n + nReadPos); }
  820. const_reference operator[](size_type pos) const { return vch[pos + nReadPos]; }
  821. reference operator[](size_type pos) { return vch[pos + nReadPos]; }
  822. void clear() { vch.clear(); nReadPos = 0; }
  823. iterator insert(iterator it, const char& x=char()) { return vch.insert(it, x); }
  824. void insert(iterator it, size_type n, const char& x) { vch.insert(it, n, x); }
  825. void insert(iterator it, std::vector<char>::const_iterator first, std::vector<char>::const_iterator last)
  826. {
  827. assert(last - first >= 0);
  828. if (it == vch.begin() + nReadPos && (unsigned int)(last - first) <= nReadPos)
  829. {
  830. // special case for inserting at the front when there's room
  831. nReadPos -= (last - first);
  832. memcpy(&vch[nReadPos], &first[0], last - first);
  833. }
  834. else
  835. vch.insert(it, first, last);
  836. }
  837. #if !defined(_MSC_VER) || _MSC_VER >= 1300
  838. void insert(iterator it, const char* first, const char* last)
  839. {
  840. assert(last - first >= 0);
  841. if (it == vch.begin() + nReadPos && (unsigned int)(last - first) <= nReadPos)
  842. {
  843. // special case for inserting at the front when there's room
  844. nReadPos -= (last - first);
  845. memcpy(&vch[nReadPos], &first[0], last - first);
  846. }
  847. else
  848. vch.insert(it, first, last);
  849. }
  850. #endif
  851. iterator erase(iterator it)
  852. {
  853. if (it == vch.begin() + nReadPos)
  854. {
  855. // special case for erasing from the front
  856. if (++nReadPos >= vch.size())
  857. {
  858. // whenever we reach the end, we take the opportunity to clear the buffer
  859. nReadPos = 0;
  860. return vch.erase(vch.begin(), vch.end());
  861. }
  862. return vch.begin() + nReadPos;
  863. }
  864. else
  865. return vch.erase(it);
  866. }
  867. iterator erase(iterator first, iterator last)
  868. {
  869. if (first == vch.begin() + nReadPos)
  870. {
  871. // special case for erasing from the front
  872. if (last == vch.end())
  873. {
  874. nReadPos = 0;
  875. return vch.erase(vch.begin(), vch.end());
  876. }
  877. else
  878. {
  879. nReadPos = (last - vch.begin());
  880. return last;
  881. }
  882. }
  883. else
  884. return vch.erase(first, last);
  885. }
  886. inline void Compact()
  887. {
  888. vch.erase(vch.begin(), vch.begin() + nReadPos);
  889. nReadPos = 0;
  890. }
  891. bool Rewind(size_type n)
  892. {
  893. // Rewind by n characters if the buffer hasn't been compacted yet
  894. if (n > nReadPos)
  895. return false;
  896. nReadPos -= n;
  897. return true;
  898. }
  899. //
  900. // Stream subset
  901. //
  902. bool eof() const { return size() == 0; }
  903. CDataStream* rdbuf() { return this; }
  904. int in_avail() { return size(); }
  905. void SetType(int n) { nType = n; }
  906. int GetType() { return nType; }
  907. void SetVersion(int n) { nVersion = n; }
  908. int GetVersion() { return nVersion; }
  909. void ReadVersion() { *this >> nVersion; }
  910. void WriteVersion() { *this << nVersion; }
  911. CDataStream& read(char* pch, size_t nSize)
  912. {
  913. // Read from the beginning of the buffer
  914. unsigned int nReadPosNext = nReadPos + nSize;
  915. if (nReadPosNext >= vch.size())
  916. {
  917. if (nReadPosNext > vch.size())
  918. {
  919. throw std::ios_base::failure("CDataStream::read() : end of data");
  920. }
  921. memcpy(pch, &vch[nReadPos], nSize);
  922. nReadPos = 0;
  923. vch.clear();
  924. return (*this);
  925. }
  926. memcpy(pch, &vch[nReadPos], nSize);
  927. nReadPos = nReadPosNext;
  928. return (*this);
  929. }
  930. CDataStream& ignore(int nSize)
  931. {
  932. // Ignore from the beginning of the buffer
  933. assert(nSize >= 0);
  934. unsigned int nReadPosNext = nReadPos + nSize;
  935. if (nReadPosNext >= vch.size())
  936. {
  937. if (nReadPosNext > vch.size())
  938. throw std::ios_base::failure("CDataStream::ignore() : end of data");
  939. nReadPos = 0;
  940. vch.clear();
  941. return (*this);
  942. }
  943. nReadPos = nReadPosNext;
  944. return (*this);
  945. }
  946. CDataStream& write(const char* pch, size_t nSize)
  947. {
  948. // Write to the end of the buffer
  949. vch.insert(vch.end(), pch, pch + nSize);
  950. return (*this);
  951. }
  952. template<typename Stream>
  953. void Serialize(Stream& s, int nType, int nVersion) const
  954. {
  955. // Special case: stream << stream concatenates like stream += stream
  956. if (!vch.empty())
  957. s.write((char*)&vch[0], vch.size() * sizeof(vch[0]));
  958. }
  959. template<typename T>
  960. unsigned int GetSerializeSize(const T& obj)
  961. {
  962. // Tells the size of the object if serialized to this stream
  963. return ::GetSerializeSize(obj, nType, nVersion);
  964. }
  965. template<typename T>
  966. CDataStream& operator<<(const T& obj)
  967. {
  968. // Serialize to this stream
  969. ::Serialize(*this, obj, nType, nVersion);
  970. return (*this);
  971. }
  972. template<typename T>
  973. CDataStream& operator>>(T& obj)
  974. {
  975. // Unserialize from this stream
  976. ::Unserialize(*this, obj, nType, nVersion);
  977. return (*this);
  978. }
  979. void GetAndClear(CSerializeData &data) {
  980. data.insert(data.end(), begin(), end());
  981. clear();
  982. }
  983. };
  984. /** RAII wrapper for FILE*.
  985. *
  986. * Will automatically close the file when it goes out of scope if not null.
  987. * If you're returning the file pointer, return file.release().
  988. * If you need to close the file early, use file.fclose() instead of fclose(file).
  989. */
  990. class CAutoFile
  991. {
  992. protected:
  993. FILE* file;
  994. public:
  995. int nType;
  996. int nVersion;
  997. CAutoFile(FILE* filenew, int nTypeIn, int nVersionIn)
  998. {
  999. file = filenew;
  1000. nType = nTypeIn;
  1001. nVersion = nVersionIn;
  1002. }
  1003. ~CAutoFile()
  1004. {
  1005. fclose();
  1006. }
  1007. void fclose()
  1008. {
  1009. if (file != NULL && file != stdin && file != stdout && file != stderr)
  1010. ::fclose(file);
  1011. file = NULL;
  1012. }
  1013. FILE* release() { FILE* ret = file; file = NULL; return ret; }
  1014. operator FILE*() { return file; }
  1015. FILE* operator->() { return file; }
  1016. FILE& operator*() { return *file; }
  1017. FILE** operator&() { return &file; }
  1018. FILE* operator=(FILE* pnew) { return file = pnew; }
  1019. bool operator!() { return (file == NULL); }
  1020. //
  1021. // Stream subset
  1022. //
  1023. void SetType(int n) { nType = n; }
  1024. int GetType() { return nType; }
  1025. void SetVersion(int n) { nVersion = n; }
  1026. int GetVersion() { return nVersion; }
  1027. void ReadVersion() { *this >> nVersion; }
  1028. void WriteVersion() { *this << nVersion; }
  1029. CAutoFile& read(char* pch, size_t nSize)
  1030. {
  1031. if (!file)
  1032. throw std::ios_base::failure("CAutoFile::read : file handle is NULL");
  1033. if (fread(pch, 1, nSize, file) != nSize)
  1034. throw std::ios_base::failure(feof(file) ? "CAutoFile::read : end of file" : "CAutoFile::read : fread failed");
  1035. return (*this);
  1036. }
  1037. CAutoFile& write(const char* pch, size_t nSize)
  1038. {
  1039. if (!file)
  1040. throw std::ios_base::failure("CAutoFile::write : file handle is NULL");
  1041. if (fwrite(pch, 1, nSize, file) != nSize)
  1042. throw std::ios_base::failure("CAutoFile::write : write failed");
  1043. return (*this);
  1044. }
  1045. template<typename T>
  1046. unsigned int GetSerializeSize(const T& obj)
  1047. {
  1048. // Tells the size of the object if serialized to this stream
  1049. return ::GetSerializeSize(obj, nType, nVersion);
  1050. }
  1051. template<typename T>
  1052. CAutoFile& operator<<(const T& obj)
  1053. {
  1054. // Serialize to this stream
  1055. if (!file)
  1056. throw std::ios_base::failure("CAutoFile::operator<< : file handle is NULL");
  1057. ::Serialize(*this, obj, nType, nVersion);
  1058. return (*this);
  1059. }
  1060. template<typename T>
  1061. CAutoFile& operator>>(T& obj)
  1062. {
  1063. // Unserialize from this stream
  1064. if (!file)
  1065. throw std::ios_base::failure("CAutoFile::operator>> : file handle is NULL");
  1066. ::Unserialize(*this, obj, nType, nVersion);
  1067. return (*this);
  1068. }
  1069. };
  1070. /** Wrapper around a FILE* that implements a ring buffer to
  1071. * deserialize from. It guarantees the ability to rewind
  1072. * a given number of bytes. */
  1073. class CBufferedFile
  1074. {
  1075. private:
  1076. FILE *src; // source file
  1077. uint64_t nSrcPos; // how many bytes have been read from source
  1078. uint64_t nReadPos; // how many bytes have been read from this
  1079. uint64_t nReadLimit; // up to which position we're allowed to read
  1080. uint64_t nRewind; // how many bytes we guarantee to rewind
  1081. std::vector<char> vchBuf; // the buffer
  1082. protected:
  1083. // read data from the source to fill the buffer
  1084. bool Fill() {
  1085. unsigned int pos = nSrcPos % vchBuf.size();
  1086. unsigned int readNow = vchBuf.size() - pos;
  1087. unsigned int nAvail = vchBuf.size() - (nSrcPos - nReadPos) - nRewind;
  1088. if (nAvail < readNow)
  1089. readNow = nAvail;
  1090. if (readNow == 0)
  1091. return false;
  1092. size_t read = fread((void*)&vchBuf[pos], 1, readNow, src);
  1093. if (read == 0) {
  1094. throw std::ios_base::failure(feof(src) ? "CBufferedFile::Fill : end of file" : "CBufferedFile::Fill : fread failed");
  1095. } else {
  1096. nSrcPos += read;
  1097. return true;
  1098. }
  1099. }
  1100. public:
  1101. int nType;
  1102. int nVersion;
  1103. CBufferedFile(FILE *fileIn, uint64_t nBufSize, uint64_t nRewindIn, int nTypeIn, int nVersionIn) :
  1104. src(fileIn), nSrcPos(0), nReadPos(0), nReadLimit((uint64_t)(-1)), nRewind(nRewindIn), vchBuf(nBufSize, 0),
  1105. nType(nTypeIn), nVersion(nVersionIn) {
  1106. }
  1107. // check whether we're at the end of the source file
  1108. bool eof() const {
  1109. return nReadPos == nSrcPos && feof(src);
  1110. }
  1111. // read a number of bytes
  1112. CBufferedFile& read(char *pch, size_t nSize) {
  1113. if (nSize + nReadPos > nReadLimit)
  1114. throw std::ios_base::failure("Read attempted past buffer limit");
  1115. if (nSize + nRewind > vchBuf.size())
  1116. throw std::ios_base::failure("Read larger than buffer size");
  1117. while (nSize > 0) {
  1118. if (nReadPos == nSrcPos)
  1119. Fill();
  1120. unsigned int pos = nReadPos % vchBuf.size();
  1121. size_t nNow = nSize;
  1122. if (nNow + pos > vchBuf.size())
  1123. nNow = vchBuf.size() - pos;
  1124. if (nNow + nReadPos > nSrcPos)
  1125. nNow = nSrcPos - nReadPos;
  1126. memcpy(pch, &vchBuf[pos], nNow);
  1127. nReadPos += nNow;
  1128. pch += nNow;
  1129. nSize -= nNow;
  1130. }
  1131. return (*this);
  1132. }
  1133. // return the current reading position
  1134. uint64_t GetPos() {
  1135. return nReadPos;
  1136. }
  1137. // rewind to a given reading position
  1138. bool SetPos(uint64_t nPos) {
  1139. nReadPos = nPos;
  1140. if (nReadPos + nRewind < nSrcPos) {
  1141. nReadPos = nSrcPos - nRewind;
  1142. return false;
  1143. } else if (nReadPos > nSrcPos) {
  1144. nReadPos = nSrcPos;
  1145. return false;
  1146. } else {
  1147. return true;
  1148. }
  1149. }
  1150. bool Seek(uint64_t nPos) {
  1151. long nLongPos = nPos;
  1152. if (nPos != (uint64_t)nLongPos)
  1153. return false;
  1154. if (fseek(src, nLongPos, SEEK_SET))
  1155. return false;
  1156. nLongPos = ftell(src);
  1157. nSrcPos = nLongPos;
  1158. nReadPos = nLongPos;
  1159. return true;
  1160. }
  1161. // prevent reading beyond a certain position
  1162. // no argument removes the limit
  1163. bool SetLimit(uint64_t nPos = (uint64_t)(-1)) {
  1164. if (nPos < nReadPos)
  1165. return false;
  1166. nReadLimit = nPos;
  1167. return true;
  1168. }
  1169. template<typename T>
  1170. CBufferedFile& operator>>(T& obj) {
  1171. // Unserialize from this stream
  1172. ::Unserialize(*this, obj, nType, nVersion);
  1173. return (*this);
  1174. }
  1175. // search for a given byte in the stream, and remain positioned on it
  1176. void FindByte(char ch) {
  1177. while (true) {
  1178. if (nReadPos == nSrcPos)
  1179. Fill();
  1180. if (vchBuf[nReadPos % vchBuf.size()] == ch)
  1181. break;
  1182. nReadPos++;
  1183. }
  1184. }
  1185. };
  1186. #endif // BITCOIN_SERIALIZE_H