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

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