Dash Core  0.12.2.1
P2P Digital Currency
serialize.h
Go to the documentation of this file.
1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2015 The Bitcoin Core developers
3 // Distributed under the MIT software license, see the accompanying
4 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
5 
6 #ifndef BITCOIN_SERIALIZE_H
7 #define BITCOIN_SERIALIZE_H
8 
9 #include "compat/endian.h"
10 
11 #include <algorithm>
12 #include <assert.h>
13 #include <ios>
14 #include <limits>
15 #include <list>
16 #include <map>
17 #include <set>
18 #include <stdint.h>
19 #include <string>
20 #include <string.h>
21 #include <utility>
22 #include <vector>
23 
24 #include "prevector.h"
25 
26 static const unsigned int MAX_SIZE = 0x02000000;
27 
32 template<typename T>
33 inline T& REF(const T& val)
34 {
35  return const_cast<T&>(val);
36 }
37 
42 template<typename T>
43 inline T* NCONST_PTR(const T* val)
44 {
45  return const_cast<T*>(val);
46 }
47 
53 template <typename V>
54 inline typename V::value_type* begin_ptr(V& v)
55 {
56  return v.empty() ? NULL : &v[0];
57 }
59 template <typename V>
60 inline const typename V::value_type* begin_ptr(const V& v)
61 {
62  return v.empty() ? NULL : &v[0];
63 }
65 template <typename V>
66 inline typename V::value_type* end_ptr(V& v)
67 {
68  return v.empty() ? NULL : (&v[0] + v.size());
69 }
71 template <typename V>
72 inline const typename V::value_type* end_ptr(const V& v)
73 {
74  return v.empty() ? NULL : (&v[0] + v.size());
75 }
76 
77 /*
78  * Lowest-level serialization and conversion.
79  * @note Sizes of these types are verified in the tests
80  */
81 template<typename Stream> inline void ser_writedata8(Stream &s, uint8_t obj)
82 {
83  s.write((char*)&obj, 1);
84 }
85 template<typename Stream> inline void ser_writedata16(Stream &s, uint16_t obj)
86 {
87  obj = htole16(obj);
88  s.write((char*)&obj, 2);
89 }
90 template<typename Stream> inline void ser_writedata32(Stream &s, uint32_t obj)
91 {
92  obj = htole32(obj);
93  s.write((char*)&obj, 4);
94 }
95 template<typename Stream> inline void ser_writedata32be(Stream &s, uint32_t obj)
96 {
97  obj = htobe32(obj);
98  s.write((char*)&obj, 4);
99 }
100 template<typename Stream> inline void ser_writedata64(Stream &s, uint64_t obj)
101 {
102  obj = htole64(obj);
103  s.write((char*)&obj, 8);
104 }
105 template<typename Stream> inline uint8_t ser_readdata8(Stream &s)
106 {
107  uint8_t obj;
108  s.read((char*)&obj, 1);
109  return obj;
110 }
111 template<typename Stream> inline uint16_t ser_readdata16(Stream &s)
112 {
113  uint16_t obj;
114  s.read((char*)&obj, 2);
115  return le16toh(obj);
116 }
117 template<typename Stream> inline uint32_t ser_readdata32(Stream &s)
118 {
119  uint32_t obj;
120  s.read((char*)&obj, 4);
121  return le32toh(obj);
122 }
123 template<typename Stream> inline uint32_t ser_readdata32be(Stream &s)
124 {
125  uint32_t obj;
126  s.read((char*)&obj, 4);
127  return be32toh(obj);
128 }
129 template<typename Stream> inline uint64_t ser_readdata64(Stream &s)
130 {
131  uint64_t obj;
132  s.read((char*)&obj, 8);
133  return le64toh(obj);
134 }
135 inline uint64_t ser_double_to_uint64(double x)
136 {
137  union { double x; uint64_t y; } tmp;
138  tmp.x = x;
139  return tmp.y;
140 }
141 inline uint32_t ser_float_to_uint32(float x)
142 {
143  union { float x; uint32_t y; } tmp;
144  tmp.x = x;
145  return tmp.y;
146 }
147 inline double ser_uint64_to_double(uint64_t y)
148 {
149  union { double x; uint64_t y; } tmp;
150  tmp.y = y;
151  return tmp.x;
152 }
153 inline float ser_uint32_to_float(uint32_t y)
154 {
155  union { float x; uint32_t y; } tmp;
156  tmp.y = y;
157  return tmp.x;
158 }
159 
160 
162 //
163 // Templates for serializing to anything that looks like a stream,
164 // i.e. anything that supports .read(char*, size_t) and .write(char*, size_t)
165 //
166 
167 enum
168 {
169  // primary actions
170  SER_NETWORK = (1 << 0),
171  SER_DISK = (1 << 1),
172  SER_GETHASH = (1 << 2),
173 };
174 
175 #define READWRITE(obj) (::SerReadWrite(s, (obj), nType, nVersion, ser_action))
176 #define READWRITEMANY(...) (::SerReadWriteMany(s, nType, nVersion, ser_action, __VA_ARGS__))
177 
184 #define ADD_SERIALIZE_METHODS \
185  size_t GetSerializeSize(int nType, int nVersion) const { \
186  CSizeComputer s(nType, nVersion); \
187  NCONST_PTR(this)->SerializationOp(s, CSerActionSerialize(), nType, nVersion);\
188  return s.size(); \
189  } \
190  template<typename Stream> \
191  void Serialize(Stream& s, int nType, int nVersion) const { \
192  NCONST_PTR(this)->SerializationOp(s, CSerActionSerialize(), nType, nVersion);\
193  } \
194  template<typename Stream> \
195  void Unserialize(Stream& s, int nType, int nVersion) { \
196  SerializationOp(s, CSerActionUnserialize(), nType, nVersion); \
197  }
198 
199 /*
200  * Basic Types
201  */
202 inline unsigned int GetSerializeSize(char a, int, int=0) { return 1; }
203 inline unsigned int GetSerializeSize(int8_t a, int, int=0) { return 1; }
204 inline unsigned int GetSerializeSize(uint8_t a, int, int=0) { return 1; }
205 inline unsigned int GetSerializeSize(int16_t a, int, int=0) { return 2; }
206 inline unsigned int GetSerializeSize(uint16_t a, int, int=0) { return 2; }
207 inline unsigned int GetSerializeSize(int32_t a, int, int=0) { return 4; }
208 inline unsigned int GetSerializeSize(uint32_t a, int, int=0) { return 4; }
209 inline unsigned int GetSerializeSize(int64_t a, int, int=0) { return 8; }
210 inline unsigned int GetSerializeSize(uint64_t a, int, int=0) { return 8; }
211 inline unsigned int GetSerializeSize(float a, int, int=0) { return 4; }
212 inline unsigned int GetSerializeSize(double a, int, int=0) { return 8; }
213 
214 template<typename Stream> inline void Serialize(Stream& s, char a, int, int=0) { ser_writedata8(s, a); } // TODO Get rid of bare char
215 template<typename Stream> inline void Serialize(Stream& s, int8_t a, int, int=0) { ser_writedata8(s, a); }
216 template<typename Stream> inline void Serialize(Stream& s, uint8_t a, int, int=0) { ser_writedata8(s, a); }
217 template<typename Stream> inline void Serialize(Stream& s, int16_t a, int, int=0) { ser_writedata16(s, a); }
218 template<typename Stream> inline void Serialize(Stream& s, uint16_t a, int, int=0) { ser_writedata16(s, a); }
219 template<typename Stream> inline void Serialize(Stream& s, int32_t a, int, int=0) { ser_writedata32(s, a); }
220 template<typename Stream> inline void Serialize(Stream& s, uint32_t a, int, int=0) { ser_writedata32(s, a); }
221 template<typename Stream> inline void Serialize(Stream& s, int64_t a, int, int=0) { ser_writedata64(s, a); }
222 template<typename Stream> inline void Serialize(Stream& s, uint64_t a, int, int=0) { ser_writedata64(s, a); }
223 template<typename Stream> inline void Serialize(Stream& s, float a, int, int=0) { ser_writedata32(s, ser_float_to_uint32(a)); }
224 template<typename Stream> inline void Serialize(Stream& s, double a, int, int=0) { ser_writedata64(s, ser_double_to_uint64(a)); }
225 
226 template<typename Stream> inline void Unserialize(Stream& s, char& a, int, int=0) { a = ser_readdata8(s); } // TODO Get rid of bare char
227 template<typename Stream> inline void Unserialize(Stream& s, int8_t& a, int, int=0) { a = ser_readdata8(s); }
228 template<typename Stream> inline void Unserialize(Stream& s, uint8_t& a, int, int=0) { a = ser_readdata8(s); }
229 template<typename Stream> inline void Unserialize(Stream& s, int16_t& a, int, int=0) { a = ser_readdata16(s); }
230 template<typename Stream> inline void Unserialize(Stream& s, uint16_t& a, int, int=0) { a = ser_readdata16(s); }
231 template<typename Stream> inline void Unserialize(Stream& s, int32_t& a, int, int=0) { a = ser_readdata32(s); }
232 template<typename Stream> inline void Unserialize(Stream& s, uint32_t& a, int, int=0) { a = ser_readdata32(s); }
233 template<typename Stream> inline void Unserialize(Stream& s, int64_t& a, int, int=0) { a = ser_readdata64(s); }
234 template<typename Stream> inline void Unserialize(Stream& s, uint64_t& a, int, int=0) { a = ser_readdata64(s); }
235 template<typename Stream> inline void Unserialize(Stream& s, float& a, int, int=0) { a = ser_uint32_to_float(ser_readdata32(s)); }
236 template<typename Stream> inline void Unserialize(Stream& s, double& a, int, int=0) { a = ser_uint64_to_double(ser_readdata64(s)); }
237 
238 inline unsigned int GetSerializeSize(bool a, int, int=0) { return sizeof(char); }
239 template<typename Stream> inline void Serialize(Stream& s, bool a, int, int=0) { char f=a; ser_writedata8(s, f); }
240 template<typename Stream> inline void Unserialize(Stream& s, bool& a, int, int=0) { char f=ser_readdata8(s); a=f; }
241 
242 
243 
244 
245 
246 
254 inline unsigned int GetSizeOfCompactSize(uint64_t nSize)
255 {
256  if (nSize < 253) return sizeof(unsigned char);
257  else if (nSize <= std::numeric_limits<unsigned short>::max()) return sizeof(unsigned char) + sizeof(unsigned short);
258  else if (nSize <= std::numeric_limits<unsigned int>::max()) return sizeof(unsigned char) + sizeof(unsigned int);
259  else return sizeof(unsigned char) + sizeof(uint64_t);
260 }
261 
262 template<typename Stream>
263 void WriteCompactSize(Stream& os, uint64_t nSize)
264 {
265  if (nSize < 253)
266  {
267  ser_writedata8(os, nSize);
268  }
269  else if (nSize <= std::numeric_limits<unsigned short>::max())
270  {
271  ser_writedata8(os, 253);
272  ser_writedata16(os, nSize);
273  }
274  else if (nSize <= std::numeric_limits<unsigned int>::max())
275  {
276  ser_writedata8(os, 254);
277  ser_writedata32(os, nSize);
278  }
279  else
280  {
281  ser_writedata8(os, 255);
282  ser_writedata64(os, nSize);
283  }
284  return;
285 }
286 
287 template<typename Stream>
288 uint64_t ReadCompactSize(Stream& is)
289 {
290  uint8_t chSize = ser_readdata8(is);
291  uint64_t nSizeRet = 0;
292  if (chSize < 253)
293  {
294  nSizeRet = chSize;
295  }
296  else if (chSize == 253)
297  {
298  nSizeRet = ser_readdata16(is);
299  if (nSizeRet < 253)
300  throw std::ios_base::failure("non-canonical ReadCompactSize()");
301  }
302  else if (chSize == 254)
303  {
304  nSizeRet = ser_readdata32(is);
305  if (nSizeRet < 0x10000u)
306  throw std::ios_base::failure("non-canonical ReadCompactSize()");
307  }
308  else
309  {
310  nSizeRet = ser_readdata64(is);
311  if (nSizeRet < 0x100000000ULL)
312  throw std::ios_base::failure("non-canonical ReadCompactSize()");
313  }
314  if (nSizeRet > (uint64_t)MAX_SIZE)
315  throw std::ios_base::failure("ReadCompactSize(): size too large");
316  return nSizeRet;
317 }
318 
343 template<typename I>
344 inline unsigned int GetSizeOfVarInt(I n)
345 {
346  int nRet = 0;
347  while(true) {
348  nRet++;
349  if (n <= 0x7F)
350  break;
351  n = (n >> 7) - 1;
352  }
353  return nRet;
354 }
355 
356 template<typename Stream, typename I>
357 void WriteVarInt(Stream& os, I n)
358 {
359  unsigned char tmp[(sizeof(n)*8+6)/7];
360  int len=0;
361  while(true) {
362  tmp[len] = (n & 0x7F) | (len ? 0x80 : 0x00);
363  if (n <= 0x7F)
364  break;
365  n = (n >> 7) - 1;
366  len++;
367  }
368  do {
369  ser_writedata8(os, tmp[len]);
370  } while(len--);
371 }
372 
373 template<typename Stream, typename I>
374 I ReadVarInt(Stream& is)
375 {
376  I n = 0;
377  while(true) {
378  unsigned char chData = ser_readdata8(is);
379  n = (n << 7) | (chData & 0x7F);
380  if (chData & 0x80)
381  n++;
382  else
383  return n;
384  }
385 }
386 
387 #define FLATDATA(obj) REF(CFlatData((char*)&(obj), (char*)&(obj) + sizeof(obj)))
388 #define VARINT(obj) REF(WrapVarInt(REF(obj)))
389 #define LIMITED_STRING(obj,n) REF(LimitedString< n >(REF(obj)))
390 
395 {
396 protected:
397  char* pbegin;
398  char* pend;
399 public:
400  CFlatData(void* pbeginIn, void* pendIn) : pbegin((char*)pbeginIn), pend((char*)pendIn) { }
401  template <class T, class TAl>
402  explicit CFlatData(std::vector<T,TAl> &v)
403  {
404  pbegin = (char*)begin_ptr(v);
405  pend = (char*)end_ptr(v);
406  }
407  template <unsigned int N, typename T, typename S, typename D>
409  {
410  pbegin = (char*)begin_ptr(v);
411  pend = (char*)end_ptr(v);
412  }
413  char* begin() { return pbegin; }
414  const char* begin() const { return pbegin; }
415  char* end() { return pend; }
416  const char* end() const { return pend; }
417 
418  unsigned int GetSerializeSize(int, int=0) const
419  {
420  return pend - pbegin;
421  }
422 
423  template<typename Stream>
424  void Serialize(Stream& s, int, int=0) const
425  {
426  s.write(pbegin, pend - pbegin);
427  }
428 
429  template<typename Stream>
430  void Unserialize(Stream& s, int, int=0)
431  {
432  s.read(pbegin, pend - pbegin);
433  }
434 };
435 
436 template<typename I>
437 class CVarInt
438 {
439 protected:
440  I &n;
441 public:
442  CVarInt(I& nIn) : n(nIn) { }
443 
444  unsigned int GetSerializeSize(int, int) const {
445  return GetSizeOfVarInt<I>(n);
446  }
447 
448  template<typename Stream>
449  void Serialize(Stream &s, int, int) const {
450  WriteVarInt<Stream,I>(s, n);
451  }
452 
453  template<typename Stream>
454  void Unserialize(Stream& s, int, int) {
455  n = ReadVarInt<Stream,I>(s);
456  }
457 };
458 
459 template<size_t Limit>
461 {
462 protected:
463  std::string& string;
464 public:
465  LimitedString(std::string& string) : string(string) {}
466 
467  template<typename Stream>
468  void Unserialize(Stream& s, int, int=0)
469  {
470  size_t size = ReadCompactSize(s);
471  if (size > Limit) {
472  throw std::ios_base::failure("String length limit exceeded");
473  }
474  string.resize(size);
475  if (size != 0)
476  s.read((char*)&string[0], size);
477  }
478 
479  template<typename Stream>
480  void Serialize(Stream& s, int, int=0) const
481  {
482  WriteCompactSize(s, string.size());
483  if (!string.empty())
484  s.write((char*)&string[0], string.size());
485  }
486 
487  unsigned int GetSerializeSize(int, int=0) const
488  {
489  return GetSizeOfCompactSize(string.size()) + string.size();
490  }
491 };
492 
493 template<typename I>
495 
503 template<typename C> unsigned int GetSerializeSize(const std::basic_string<C>& str, int, int=0);
504 template<typename Stream, typename C> void Serialize(Stream& os, const std::basic_string<C>& str, int, int=0);
505 template<typename Stream, typename C> void Unserialize(Stream& is, std::basic_string<C>& str, int, int=0);
506 
511 template<unsigned int N, typename T> unsigned int GetSerializeSize_impl(const prevector<N, T>& v, int nType, int nVersion, const unsigned char&);
512 template<unsigned int N, typename T, typename V> unsigned int GetSerializeSize_impl(const prevector<N, T>& v, int nType, int nVersion, const V&);
513 template<unsigned int N, typename T> inline unsigned int GetSerializeSize(const prevector<N, T>& v, int nType, int nVersion);
514 template<typename Stream, unsigned int N, typename T> void Serialize_impl(Stream& os, const prevector<N, T>& v, int nType, int nVersion, const unsigned char&);
515 template<typename Stream, unsigned int N, typename T, typename V> void Serialize_impl(Stream& os, const prevector<N, T>& v, int nType, int nVersion, const V&);
516 template<typename Stream, unsigned int N, typename T> inline void Serialize(Stream& os, const prevector<N, T>& v, int nType, int nVersion);
517 template<typename Stream, unsigned int N, typename T> void Unserialize_impl(Stream& is, prevector<N, T>& v, int nType, int nVersion, const unsigned char&);
518 template<typename Stream, unsigned int N, typename T, typename V> void Unserialize_impl(Stream& is, prevector<N, T>& v, int nType, int nVersion, const V&);
519 template<typename Stream, unsigned int N, typename T> inline void Unserialize(Stream& is, prevector<N, T>& v, int nType, int nVersion);
520 
525 template<typename T, typename A> unsigned int GetSerializeSize_impl(const std::vector<T, A>& v, int nType, int nVersion, const unsigned char&);
526 template<typename T, typename A, typename V> unsigned int GetSerializeSize_impl(const std::vector<T, A>& v, int nType, int nVersion, const V&);
527 template<typename T, typename A> inline unsigned int GetSerializeSize(const std::vector<T, A>& v, int nType, int nVersion);
528 template<typename Stream, typename T, typename A> void Serialize_impl(Stream& os, const std::vector<T, A>& v, int nType, int nVersion, const unsigned char&);
529 template<typename Stream, typename T, typename A, typename V> void Serialize_impl(Stream& os, const std::vector<T, A>& v, int nType, int nVersion, const V&);
530 template<typename Stream, typename T, typename A> inline void Serialize(Stream& os, const std::vector<T, A>& v, int nType, int nVersion);
531 template<typename Stream, typename T, typename A> void Unserialize_impl(Stream& is, std::vector<T, A>& v, int nType, int nVersion, const unsigned char&);
532 template<typename Stream, typename T, typename A, typename V> void Unserialize_impl(Stream& is, std::vector<T, A>& v, int nType, int nVersion, const V&);
533 template<typename Stream, typename T, typename A> inline void Unserialize(Stream& is, std::vector<T, A>& v, int nType, int nVersion);
534 
538 template<typename K, typename T> unsigned int GetSerializeSize(const std::pair<K, T>& item, int nType, int nVersion);
539 template<typename Stream, typename K, typename T> void Serialize(Stream& os, const std::pair<K, T>& item, int nType, int nVersion);
540 template<typename Stream, typename K, typename T> void Unserialize(Stream& is, std::pair<K, T>& item, int nType, int nVersion);
541 
545 template<typename K, typename T, typename Pred, typename A> unsigned int GetSerializeSize(const std::map<K, T, Pred, A>& m, int nType, int nVersion);
546 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);
547 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);
548 
552 template<typename K, typename Pred, typename A> unsigned int GetSerializeSize(const std::set<K, Pred, A>& m, int nType, int nVersion);
553 template<typename Stream, typename K, typename Pred, typename A> void Serialize(Stream& os, const std::set<K, Pred, A>& m, int nType, int nVersion);
554 template<typename Stream, typename K, typename Pred, typename A> void Unserialize(Stream& is, std::set<K, Pred, A>& m, int nType, int nVersion);
555 
556 
557 
558 
559 
566 template<typename T>
567 inline unsigned int GetSerializeSize(const T& a, long nType, int nVersion)
568 {
569  return a.GetSerializeSize((int)nType, nVersion);
570 }
571 
572 template<typename Stream, typename T>
573 inline void Serialize(Stream& os, const T& a, long nType, int nVersion)
574 {
575  a.Serialize(os, (int)nType, nVersion);
576 }
577 
578 template<typename Stream, typename T>
579 inline void Unserialize(Stream& is, T& a, long nType, int nVersion)
580 {
581  a.Unserialize(is, (int)nType, nVersion);
582 }
583 
584 
585 
586 
587 
591 template<typename C>
592 unsigned int GetSerializeSize(const std::basic_string<C>& str, int, int)
593 {
594  return GetSizeOfCompactSize(str.size()) + str.size() * sizeof(str[0]);
595 }
596 
597 template<typename Stream, typename C>
598 void Serialize(Stream& os, const std::basic_string<C>& str, int, int)
599 {
600  WriteCompactSize(os, str.size());
601  if (!str.empty())
602  os.write((char*)&str[0], str.size() * sizeof(str[0]));
603 }
604 
605 template<typename Stream, typename C>
606 void Unserialize(Stream& is, std::basic_string<C>& str, int, int)
607 {
608  unsigned int nSize = ReadCompactSize(is);
609  str.resize(nSize);
610  if (nSize != 0)
611  is.read((char*)&str[0], nSize * sizeof(str[0]));
612 }
613 
614 
615 
619 template<unsigned int N, typename T>
620 unsigned int GetSerializeSize_impl(const prevector<N, T>& v, int nType, int nVersion, const unsigned char&)
621 {
622  return (GetSizeOfCompactSize(v.size()) + v.size() * sizeof(T));
623 }
624 
625 template<unsigned int N, typename T, typename V>
626 unsigned int GetSerializeSize_impl(const prevector<N, T>& v, int nType, int nVersion, const V&)
627 {
628  unsigned int nSize = GetSizeOfCompactSize(v.size());
629  for (typename prevector<N, T>::const_iterator vi = v.begin(); vi != v.end(); ++vi)
630  nSize += GetSerializeSize((*vi), nType, nVersion);
631  return nSize;
632 }
633 
634 template<unsigned int N, typename T>
635 inline unsigned int GetSerializeSize(const prevector<N, T>& v, int nType, int nVersion)
636 {
637  return GetSerializeSize_impl(v, nType, nVersion, T());
638 }
639 
640 
641 template<typename Stream, unsigned int N, typename T>
642 void Serialize_impl(Stream& os, const prevector<N, T>& v, int nType, int nVersion, const unsigned char&)
643 {
644  WriteCompactSize(os, v.size());
645  if (!v.empty())
646  os.write((char*)&v[0], v.size() * sizeof(T));
647 }
648 
649 template<typename Stream, unsigned int N, typename T, typename V>
650 void Serialize_impl(Stream& os, const prevector<N, T>& v, int nType, int nVersion, const V&)
651 {
652  WriteCompactSize(os, v.size());
653  for (typename prevector<N, T>::const_iterator vi = v.begin(); vi != v.end(); ++vi)
654  ::Serialize(os, (*vi), nType, nVersion);
655 }
656 
657 template<typename Stream, unsigned int N, typename T>
658 inline void Serialize(Stream& os, const prevector<N, T>& v, int nType, int nVersion)
659 {
660  Serialize_impl(os, v, nType, nVersion, T());
661 }
662 
663 
664 template<typename Stream, unsigned int N, typename T>
665 void Unserialize_impl(Stream& is, prevector<N, T>& v, int nType, int nVersion, const unsigned char&)
666 {
667  // Limit size per read so bogus size value won't cause out of memory
668  v.clear();
669  unsigned int nSize = ReadCompactSize(is);
670  unsigned int i = 0;
671  while (i < nSize)
672  {
673  unsigned int blk = std::min(nSize - i, (unsigned int)(1 + 4999999 / sizeof(T)));
674  v.resize(i + blk);
675  is.read((char*)&v[i], blk * sizeof(T));
676  i += blk;
677  }
678 }
679 
680 template<typename Stream, unsigned int N, typename T, typename V>
681 void Unserialize_impl(Stream& is, prevector<N, T>& v, int nType, int nVersion, const V&)
682 {
683  v.clear();
684  unsigned int nSize = ReadCompactSize(is);
685  unsigned int i = 0;
686  unsigned int nMid = 0;
687  while (nMid < nSize)
688  {
689  nMid += 5000000 / sizeof(T);
690  if (nMid > nSize)
691  nMid = nSize;
692  v.resize(nMid);
693  for (; i < nMid; i++)
694  Unserialize(is, v[i], nType, nVersion);
695  }
696 }
697 
698 template<typename Stream, unsigned int N, typename T>
699 inline void Unserialize(Stream& is, prevector<N, T>& v, int nType, int nVersion)
700 {
701  Unserialize_impl(is, v, nType, nVersion, T());
702 }
703 
704 
705 
709 template<typename T, typename A>
710 unsigned int GetSerializeSize_impl(const std::vector<T, A>& v, int nType, int nVersion, const unsigned char&)
711 {
712  return (GetSizeOfCompactSize(v.size()) + v.size() * sizeof(T));
713 }
714 
715 template<typename T, typename A, typename V>
716 unsigned int GetSerializeSize_impl(const std::vector<T, A>& v, int nType, int nVersion, const V&)
717 {
718  unsigned int nSize = GetSizeOfCompactSize(v.size());
719  for (typename std::vector<T, A>::const_iterator vi = v.begin(); vi != v.end(); ++vi)
720  nSize += GetSerializeSize((*vi), nType, nVersion);
721  return nSize;
722 }
723 
724 template<typename T, typename A>
725 inline unsigned int GetSerializeSize(const std::vector<T, A>& v, int nType, int nVersion)
726 {
727  return GetSerializeSize_impl(v, nType, nVersion, T());
728 }
729 
730 
731 template<typename Stream, typename T, typename A>
732 void Serialize_impl(Stream& os, const std::vector<T, A>& v, int nType, int nVersion, const unsigned char&)
733 {
734  WriteCompactSize(os, v.size());
735  if (!v.empty())
736  os.write((char*)&v[0], v.size() * sizeof(T));
737 }
738 
739 template<typename Stream, typename T, typename A, typename V>
740 void Serialize_impl(Stream& os, const std::vector<T, A>& v, int nType, int nVersion, const V&)
741 {
742  WriteCompactSize(os, v.size());
743  for (typename std::vector<T, A>::const_iterator vi = v.begin(); vi != v.end(); ++vi)
744  ::Serialize(os, (*vi), nType, nVersion);
745 }
746 
747 template<typename Stream, typename T, typename A>
748 inline void Serialize(Stream& os, const std::vector<T, A>& v, int nType, int nVersion)
749 {
750  Serialize_impl(os, v, nType, nVersion, T());
751 }
752 
753 
754 template<typename Stream, typename T, typename A>
755 void Unserialize_impl(Stream& is, std::vector<T, A>& v, int nType, int nVersion, const unsigned char&)
756 {
757  // Limit size per read so bogus size value won't cause out of memory
758  v.clear();
759  unsigned int nSize = ReadCompactSize(is);
760  unsigned int i = 0;
761  while (i < nSize)
762  {
763  unsigned int blk = std::min(nSize - i, (unsigned int)(1 + 4999999 / sizeof(T)));
764  v.resize(i + blk);
765  is.read((char*)&v[i], blk * sizeof(T));
766  i += blk;
767  }
768 }
769 
770 template<typename Stream, typename T, typename A, typename V>
771 void Unserialize_impl(Stream& is, std::vector<T, A>& v, int nType, int nVersion, const V&)
772 {
773  v.clear();
774  unsigned int nSize = ReadCompactSize(is);
775  unsigned int i = 0;
776  unsigned int nMid = 0;
777  while (nMid < nSize)
778  {
779  nMid += 5000000 / sizeof(T);
780  if (nMid > nSize)
781  nMid = nSize;
782  v.resize(nMid);
783  for (; i < nMid; i++)
784  Unserialize(is, v[i], nType, nVersion);
785  }
786 }
787 
788 template<typename Stream, typename T, typename A>
789 inline void Unserialize(Stream& is, std::vector<T, A>& v, int nType, int nVersion)
790 {
791  Unserialize_impl(is, v, nType, nVersion, T());
792 }
793 
794 
795 
799 template<typename K, typename T>
800 unsigned int GetSerializeSize(const std::pair<K, T>& item, int nType, int nVersion)
801 {
802  return GetSerializeSize(item.first, nType, nVersion) + GetSerializeSize(item.second, nType, nVersion);
803 }
804 
805 template<typename Stream, typename K, typename T>
806 void Serialize(Stream& os, const std::pair<K, T>& item, int nType, int nVersion)
807 {
808  Serialize(os, item.first, nType, nVersion);
809  Serialize(os, item.second, nType, nVersion);
810 }
811 
812 template<typename Stream, typename K, typename T>
813 void Unserialize(Stream& is, std::pair<K, T>& item, int nType, int nVersion)
814 {
815  Unserialize(is, item.first, nType, nVersion);
816  Unserialize(is, item.second, nType, nVersion);
817 }
818 
819 
820 
824 template<typename K, typename T, typename Pred, typename A>
825 unsigned int GetSerializeSize(const std::map<K, T, Pred, A>& m, int nType, int nVersion)
826 {
827  unsigned int nSize = GetSizeOfCompactSize(m.size());
828  for (typename std::map<K, T, Pred, A>::const_iterator mi = m.begin(); mi != m.end(); ++mi)
829  nSize += GetSerializeSize((*mi), nType, nVersion);
830  return nSize;
831 }
832 
833 template<typename Stream, typename K, typename T, typename Pred, typename A>
834 void Serialize(Stream& os, const std::map<K, T, Pred, A>& m, int nType, int nVersion)
835 {
836  WriteCompactSize(os, m.size());
837  for (typename std::map<K, T, Pred, A>::const_iterator mi = m.begin(); mi != m.end(); ++mi)
838  Serialize(os, (*mi), nType, nVersion);
839 }
840 
841 template<typename Stream, typename K, typename T, typename Pred, typename A>
842 void Unserialize(Stream& is, std::map<K, T, Pred, A>& m, int nType, int nVersion)
843 {
844  m.clear();
845  unsigned int nSize = ReadCompactSize(is);
846  typename std::map<K, T, Pred, A>::iterator mi = m.begin();
847  for (unsigned int i = 0; i < nSize; i++)
848  {
849  std::pair<K, T> item;
850  Unserialize(is, item, nType, nVersion);
851  mi = m.insert(mi, item);
852  }
853 }
854 
855 
856 
860 template<typename K, typename Pred, typename A>
861 unsigned int GetSerializeSize(const std::set<K, Pred, A>& m, int nType, int nVersion)
862 {
863  unsigned int nSize = GetSizeOfCompactSize(m.size());
864  for (typename std::set<K, Pred, A>::const_iterator it = m.begin(); it != m.end(); ++it)
865  nSize += GetSerializeSize((*it), nType, nVersion);
866  return nSize;
867 }
868 
869 template<typename Stream, typename K, typename Pred, typename A>
870 void Serialize(Stream& os, const std::set<K, Pred, A>& m, int nType, int nVersion)
871 {
872  WriteCompactSize(os, m.size());
873  for (typename std::set<K, Pred, A>::const_iterator it = m.begin(); it != m.end(); ++it)
874  Serialize(os, (*it), nType, nVersion);
875 }
876 
877 template<typename Stream, typename K, typename Pred, typename A>
878 void Unserialize(Stream& is, std::set<K, Pred, A>& m, int nType, int nVersion)
879 {
880  m.clear();
881  unsigned int nSize = ReadCompactSize(is);
882  typename std::set<K, Pred, A>::iterator it = m.begin();
883  for (unsigned int i = 0; i < nSize; i++)
884  {
885  K key;
886  Unserialize(is, key, nType, nVersion);
887  it = m.insert(it, key);
888  }
889 }
890 
894 template<typename T, typename A>
895 unsigned int GetSerializeSize(const std::list<T, A>& l, int nType, int nVersion)
896 {
897  unsigned int nSize = GetSizeOfCompactSize(l.size());
898  for (typename std::list<T, A>::const_iterator it = l.begin(); it != l.end(); ++it)
899  nSize += GetSerializeSize((*it), nType, nVersion);
900  return nSize;
901 }
902 
903 template<typename Stream, typename T, typename A>
904 void Serialize(Stream& os, const std::list<T, A>& l, int nType, int nVersion)
905 {
906  WriteCompactSize(os, l.size());
907  for (typename std::list<T, A>::const_iterator it = l.begin(); it != l.end(); ++it)
908  Serialize(os, (*it), nType, nVersion);
909 }
910 
911 template<typename Stream, typename T, typename A>
912 void Unserialize(Stream& is, std::list<T, A>& l, int nType, int nVersion)
913 {
914  l.clear();
915  unsigned int nSize = ReadCompactSize(is);
916  for (unsigned int i = 0; i < nSize; i++)
917  {
918  T val;
919  Unserialize(is, val, nType, nVersion);
920  l.push_back(val);
921  }
922 }
923 
924 
925 
930 {
931  bool ForRead() const { return false; }
932 };
934 {
935  bool ForRead() const { return true; }
936 };
937 
938 template<typename Stream, typename T>
939 inline void SerReadWrite(Stream& s, const T& obj, int nType, int nVersion, CSerActionSerialize ser_action)
940 {
941  ::Serialize(s, obj, nType, nVersion);
942 }
943 
944 template<typename Stream, typename T>
945 inline void SerReadWrite(Stream& s, T& obj, int nType, int nVersion, CSerActionUnserialize ser_action)
946 {
947  ::Unserialize(s, obj, nType, nVersion);
948 }
949 
950 
951 
952 
953 
954 
955 
956 
957 
959 {
960 protected:
961  size_t nSize;
962 
963 public:
964  int nType;
965  int nVersion;
966 
967  CSizeComputer(int nTypeIn, int nVersionIn) : nSize(0), nType(nTypeIn), nVersion(nVersionIn) {}
968 
969  CSizeComputer& write(const char *psz, size_t nSize)
970  {
971  this->nSize += nSize;
972  return *this;
973  }
974 
975  template<typename T>
976  CSizeComputer& operator<<(const T& obj)
977  {
978  ::Serialize(*this, obj, nType, nVersion);
979  return (*this);
980  }
981 
982  size_t size() const {
983  return nSize;
984  }
985 };
986 
987 template<typename Stream>
988 void SerializeMany(Stream& s, int nType, int nVersion)
989 {
990 }
991 
992 template<typename Stream, typename Arg>
993 void SerializeMany(Stream& s, int nType, int nVersion, Arg&& arg)
994 {
995  ::Serialize(s, std::forward<Arg>(arg), nType, nVersion);
996 }
997 
998 template<typename Stream, typename Arg, typename... Args>
999 void SerializeMany(Stream& s, int nType, int nVersion, Arg&& arg, Args&&... args)
1000 {
1001  ::Serialize(s, std::forward<Arg>(arg), nType, nVersion);
1002  ::SerializeMany(s, nType, nVersion, std::forward<Args>(args)...);
1003 }
1004 
1005 template<typename Stream>
1006 inline void UnserializeMany(Stream& s, int nType, int nVersion)
1007 {
1008 }
1009 
1010 template<typename Stream, typename Arg>
1011 inline void UnserializeMany(Stream& s, int nType, int nVersion, Arg& arg)
1012 {
1013  ::Unserialize(s, arg, nType, nVersion);
1014 }
1015 
1016 template<typename Stream, typename Arg, typename... Args>
1017 inline void UnserializeMany(Stream& s, int nType, int nVersion, Arg& arg, Args&... args)
1018 {
1019  ::Unserialize(s, arg, nType, nVersion);
1020  ::UnserializeMany(s, nType, nVersion, args...);
1021 }
1022 
1023 template<typename Stream, typename... Args>
1024 inline void SerReadWriteMany(Stream& s, int nType, int nVersion, CSerActionSerialize ser_action, Args&&... args)
1025 {
1026  ::SerializeMany(s, nType, nVersion, std::forward<Args>(args)...);
1027 }
1028 
1029 template<typename Stream, typename... Args>
1030 inline void SerReadWriteMany(Stream& s, int nType, int nVersion, CSerActionUnserialize ser_action, Args&... args)
1031 {
1032  ::UnserializeMany(s, nType, nVersion, args...);
1033 }
1034 
1035 #endif // BITCOIN_SERIALIZE_H
size_t nSize
Definition: serialize.h:961
uint64_t ser_double_to_uint64(double x)
Definition: serialize.h:135
void Serialize(Stream &s, int, int=0) const
Definition: serialize.h:424
void UnserializeMany(Stream &s, int nType, int nVersion)
Definition: serialize.h:1006
void resize(size_type new_size)
Definition: prevector.h:296
uint32_t ser_float_to_uint32(float x)
Definition: serialize.h:141
bool ForRead() const
Definition: serialize.h:931
uint8_t ser_readdata8(Stream &s)
Definition: serialize.h:105
void clear()
Definition: prevector.h:319
void ser_writedata64(Stream &s, uint64_t obj)
Definition: serialize.h:100
uint64_t ReadCompactSize(Stream &is)
Definition: serialize.h:288
CFlatData(void *pbeginIn, void *pendIn)
Definition: serialize.h:400
void Serialize(Stream &s, char a, int, int=0)
Definition: serialize.h:214
void ser_writedata32(Stream &s, uint32_t obj)
Definition: serialize.h:90
unsigned int GetSizeOfCompactSize(uint64_t nSize)
Definition: serialize.h:254
void Unserialize_impl(Stream &is, prevector< N, T > &v, int nType, int nVersion, const unsigned char &)
Definition: serialize.h:665
void Serialize_impl(Stream &os, const prevector< N, T > &v, int nType, int nVersion, const unsigned char &)
Definition: serialize.h:642
unsigned int GetSerializeSize(int, int) const
Definition: serialize.h:444
void Unserialize(Stream &s, int, int)
Definition: serialize.h:454
uint32_t be32toh(uint32_t big_endian_32bits)
Definition: endian.h:153
char * end()
Definition: serialize.h:415
CFlatData(prevector< N, T, S, D > &v)
Definition: serialize.h:408
uint32_t htole32(uint32_t host_32bits)
Definition: endian.h:146
void WriteVarInt(Stream &os, I n)
Definition: serialize.h:357
void SerReadWriteMany(Stream &s, int nType, int nVersion, CSerActionSerialize ser_action, Args &&... args)
Definition: serialize.h:1024
const char * end() const
Definition: serialize.h:416
const char * begin() const
Definition: serialize.h:414
void SerializeMany(Stream &s, int nType, int nVersion)
Definition: serialize.h:988
uint32_t htobe32(uint32_t host_32bits)
Definition: endian.h:139
I ReadVarInt(Stream &is)
Definition: serialize.h:374
CSizeComputer(int nTypeIn, int nVersionIn)
Definition: serialize.h:967
CVarInt(I &nIn)
Definition: serialize.h:442
iterator end()
Definition: prevector.h:272
uint16_t ser_readdata16(Stream &s)
Definition: serialize.h:111
CSizeComputer & operator<<(const T &obj)
Definition: serialize.h:976
unsigned int GetSerializeSize_impl(const prevector< N, T > &v, int nType, int nVersion, const unsigned char &)
Definition: serialize.h:620
uint32_t ser_readdata32(Stream &s)
Definition: serialize.h:117
unsigned int GetSerializeSize(char a, int, int=0)
Definition: serialize.h:202
void Unserialize(Stream &s, int, int=0)
Definition: serialize.h:430
void Serialize(Stream &s, int, int) const
Definition: serialize.h:449
void ser_writedata16(Stream &s, uint16_t obj)
Definition: serialize.h:85
void Unserialize(Stream &s, char &a, int, int=0)
Definition: serialize.h:226
V::value_type * end_ptr(V &v)
Definition: serialize.h:66
char * pbegin
Definition: serialize.h:397
void SerReadWrite(Stream &s, const T &obj, int nType, int nVersion, CSerActionSerialize ser_action)
Definition: serialize.h:939
CFlatData(std::vector< T, TAl > &v)
Definition: serialize.h:402
LimitedString(std::string &string)
Definition: serialize.h:465
uint16_t le16toh(uint16_t little_endian_16bits)
Definition: endian.h:132
void ser_writedata32be(Stream &s, uint32_t obj)
Definition: serialize.h:95
std::string & string
Definition: serialize.h:463
double ser_uint64_to_double(uint64_t y)
Definition: serialize.h:147
char * begin()
Definition: serialize.h:413
unsigned int GetSizeOfVarInt(I n)
Definition: serialize.h:344
uint64_t ser_readdata64(Stream &s)
Definition: serialize.h:129
V::value_type * begin_ptr(V &v)
Definition: serialize.h:54
uint16_t htole16(uint16_t host_16bits)
Definition: endian.h:118
size_t size() const
Definition: serialize.h:982
static const unsigned int MAX_SIZE
Definition: serialize.h:26
uint64_t le64toh(uint64_t little_endian_64bits)
Definition: endian.h:188
char * pend
Definition: serialize.h:398
bool empty() const
Definition: prevector.h:266
CSizeComputer & write(const char *psz, size_t nSize)
Definition: serialize.h:969
uint64_t htole64(uint64_t host_64bits)
Definition: endian.h:174
uint32_t ser_readdata32be(Stream &s)
Definition: serialize.h:123
I & n
Definition: serialize.h:440
iterator begin()
Definition: prevector.h:270
size_type size() const
Definition: prevector.h:262
unsigned int GetSerializeSize(int, int=0) const
Definition: serialize.h:418
T * NCONST_PTR(const T *val)
Definition: serialize.h:43
bool ForRead() const
Definition: serialize.h:935
void Serialize(Stream &s, int, int=0) const
Definition: serialize.h:480
void WriteCompactSize(Stream &os, uint64_t nSize)
Definition: serialize.h:263
uint32_t le32toh(uint32_t little_endian_32bits)
Definition: endian.h:160
void Unserialize(Stream &s, int, int=0)
Definition: serialize.h:468
T & REF(const T &val)
Definition: serialize.h:33
unsigned int GetSerializeSize(int, int=0) const
Definition: serialize.h:487
CVarInt< I > WrapVarInt(I &n)
Definition: serialize.h:494
void ser_writedata8(Stream &s, uint8_t obj)
Definition: serialize.h:81
float ser_uint32_to_float(uint32_t y)
Definition: serialize.h:153