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