PRCYCoin  2.0.0.7rc1
P2P Digital Currency
serialize.h
Go to the documentation of this file.
1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2014 The Bitcoin developers
3 // Copyright (c) 2015-2018 The PIVX developers
4 // Copyright (c) 2018-2020 The DAPS Project developers
5 // Distributed under the MIT software license, see the accompanying
6 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
7 
8 #ifndef BITCOIN_SERIALIZE_H
9 #define BITCOIN_SERIALIZE_H
10 
11 #include <algorithm>
12 #include <assert.h>
13 #include <ios>
14 #include <limits>
15 #include <map>
16 #include <set>
17 #include <stdint.h>
18 #include <string.h>
19 #include <string>
20 #include <utility>
21 #include <vector>
22 
23 #include "compat/endian.h"
24 #include "prevector.h"
25 
26 
27 static const unsigned int MAX_SIZE = 0x02000000;
28 
33 template <typename T>
34 inline T& REF(const T& val)
35 {
36  return const_cast<T&>(val);
37 }
38 
43 template <typename T>
44 inline T* NCONST_PTR(const T* val)
45 {
46  return const_cast<T*>(val);
47 }
48 
56 template <typename V>
57 inline typename V::value_type* begin_ptr(V& v)
58 {
59  return v.data();
60 }
61 template <typename V>
62 inline const typename V::value_type* begin_ptr(const V& v)
63 {
64  return v.data();
65 }
66 template <typename V>
67 inline typename V::value_type* end_ptr(V& v)
68 {
69  return v.data() + v.size();
70 }
71 template <typename V>
72 inline const typename V::value_type* end_ptr(const V& v)
73 {
74  return v.data() + v.size();
75 }
76 
77 
78 /*
79  * Lowest-level serialization and conversion.
80  * @note Sizes of these types are verified in the tests
81  */
82 template<typename Stream> inline void ser_writedata8(Stream &s, uint8_t obj)
83 {
84  s.write((char*)&obj, 1);
85 }
86 template<typename Stream> inline void ser_writedata16(Stream &s, uint16_t obj)
87 {
88  obj = htole16(obj);
89  s.write((char*)&obj, 2);
90 }
91 template<typename Stream> inline void ser_writedata32(Stream &s, uint32_t obj)
92 {
93  obj = htole32(obj);
94  s.write((char*)&obj, 4);
95 }
96 template<typename Stream> inline void ser_writedata64(Stream &s, uint64_t obj)
97 {
98  obj = htole64(obj);
99  s.write((char*)&obj, 8);
100 }
101 template<typename Stream> inline uint8_t ser_readdata8(Stream &s)
102 {
103  uint8_t obj;
104  s.read((char*)&obj, 1);
105  return obj;
106 }
107 template<typename Stream> inline uint16_t ser_readdata16(Stream &s)
108 {
109  uint16_t obj;
110  s.read((char*)&obj, 2);
111  return le16toh(obj);
112 }
113 template<typename Stream> inline uint32_t ser_readdata32(Stream &s)
114 {
115  uint32_t obj;
116  s.read((char*)&obj, 4);
117  return le32toh(obj);
118 }
119 template<typename Stream> inline uint64_t ser_readdata64(Stream &s)
120 {
121  uint64_t obj;
122  s.read((char*)&obj, 8);
123  return le64toh(obj);
124 }
125 inline uint64_t ser_double_to_uint64(double x)
126 {
127  union { double x; uint64_t y; } tmp;
128  tmp.x = x;
129  return tmp.y;
130 }
131 inline uint32_t ser_float_to_uint32(float x)
132 {
133  union { float x; uint32_t y; } tmp;
134  tmp.x = x;
135  return tmp.y;
136 }
137 inline double ser_uint64_to_double(uint64_t y)
138 {
139  union { double x; uint64_t y; } tmp;
140  tmp.y = y;
141  return tmp.x;
142 }
143 inline float ser_uint32_to_float(uint32_t y)
144 {
145  union { float x; uint32_t y; } tmp;
146  tmp.y = y;
147  return tmp.x;
148 }
149 
150 
152 //
153 // Templates for serializing to anything that looks like a stream,
154 // i.e. anything that supports .read(char*, size_t) and .write(char*, size_t)
155 //
156 
157 enum {
158  // primary actions
159  SER_NETWORK = (1 << 0),
160  SER_DISK = (1 << 1),
161  SER_GETHASH = (1 << 2),
162 };
163 
164 #define READWRITE(obj) (::SerReadWrite(s, (obj), nType, nVersion, ser_action))
165 
172 #define ADD_SERIALIZE_METHODS \
173  size_t GetSerializeSize(int nType, int nVersion) const \
174  { \
175  CSizeComputer s(nType, nVersion); \
176  NCONST_PTR(this)->SerializationOp(s, CSerActionSerialize(), nType, nVersion); \
177  return s.size(); \
178  } \
179  template <typename Stream> \
180  void Serialize(Stream& s, int nType, int nVersion) const \
181  { \
182  NCONST_PTR(this)->SerializationOp(s, CSerActionSerialize(), nType, nVersion); \
183  } \
184  template <typename Stream> \
185  void Unserialize(Stream& s, int nType, int nVersion) \
186  { \
187  SerializationOp(s, CSerActionUnserialize(), nType, nVersion); \
188  }
189 
190 
191 /*
192  * Basic Types
193  */
194 inline unsigned int GetSerializeSize(char a, int, int=0) { return 1; }
195 inline unsigned int GetSerializeSize(int8_t a, int, int=0) { return 1; }
196 inline unsigned int GetSerializeSize(uint8_t a, int, int=0) { return 1; }
197 inline unsigned int GetSerializeSize(int16_t a, int, int=0) { return 2; }
198 inline unsigned int GetSerializeSize(uint16_t a, int, int=0) { return 2; }
199 inline unsigned int GetSerializeSize(int32_t a, int, int=0) { return 4; }
200 inline unsigned int GetSerializeSize(uint32_t a, int, int=0) { return 4; }
201 inline unsigned int GetSerializeSize(int64_t a, int, int=0) { return 8; }
202 inline unsigned int GetSerializeSize(uint64_t a, int, int=0) { return 8; }
203 inline unsigned int GetSerializeSize(float a, int, int=0) { return 4; }
204 inline unsigned int GetSerializeSize(double a, int, int=0) { return 8; }
205 
206 template<typename Stream> inline void Serialize(Stream& s, char a, int, int=0) { ser_writedata8(s, a); } // TODO Get rid of bare char
207 template<typename Stream> inline void Serialize(Stream& s, int8_t a, int, int=0) { ser_writedata8(s, a); }
208 template<typename Stream> inline void Serialize(Stream& s, uint8_t a, int, int=0) { ser_writedata8(s, a); }
209 template<typename Stream> inline void Serialize(Stream& s, int16_t a, int, int=0) { ser_writedata16(s, a); }
210 template<typename Stream> inline void Serialize(Stream& s, uint16_t a, int, int=0) { ser_writedata16(s, a); }
211 template<typename Stream> inline void Serialize(Stream& s, int32_t a, int, int=0) { ser_writedata32(s, a); }
212 template<typename Stream> inline void Serialize(Stream& s, uint32_t a, int, int=0) { ser_writedata32(s, a); }
213 template<typename Stream> inline void Serialize(Stream& s, int64_t a, int, int=0) { ser_writedata64(s, a); }
214 template<typename Stream> inline void Serialize(Stream& s, uint64_t a, int, int=0) { ser_writedata64(s, a); }
215 template<typename Stream> inline void Serialize(Stream& s, float a, int, int=0) { ser_writedata32(s, ser_float_to_uint32(a)); }
216 template<typename Stream> inline void Serialize(Stream& s, double a, int, int=0) { ser_writedata64(s, ser_double_to_uint64(a)); }
217 
218 template<typename Stream> inline void Unserialize(Stream& s, char& a, int, int=0) { a = ser_readdata8(s); } // TODO Get rid of bare char
219 template<typename Stream> inline void Unserialize(Stream& s, int8_t& a, int, int=0) { a = ser_readdata8(s); }
220 template<typename Stream> inline void Unserialize(Stream& s, uint8_t& a, int, int=0) { a = ser_readdata8(s); }
221 template<typename Stream> inline void Unserialize(Stream& s, int16_t& a, int, int=0) { a = ser_readdata16(s); }
222 template<typename Stream> inline void Unserialize(Stream& s, uint16_t& a, int, int=0) { a = ser_readdata16(s); }
223 template<typename Stream> inline void Unserialize(Stream& s, int32_t& a, int, int=0) { a = ser_readdata32(s); }
224 template<typename Stream> inline void Unserialize(Stream& s, uint32_t& a, int, int=0) { a = ser_readdata32(s); }
225 template<typename Stream> inline void Unserialize(Stream& s, int64_t& a, int, int=0) { a = ser_readdata64(s); }
226 template<typename Stream> inline void Unserialize(Stream& s, uint64_t& a, int, int=0) { a = ser_readdata64(s); }
227 template<typename Stream> inline void Unserialize(Stream& s, float& a, int, int=0) { a = ser_uint32_to_float(ser_readdata32(s)); }
228 template<typename Stream> inline void Unserialize(Stream& s, double& a, int, int=0) { a = ser_uint64_to_double(ser_readdata64(s)); }
229 
230 inline unsigned int GetSerializeSize(bool a, int, int = 0) { return sizeof(char); }
231 template<typename Stream> inline void Serialize(Stream& s, bool a, int, int=0) { char f=a; ser_writedata8(s, f); }
232 template<typename Stream> inline void Unserialize(Stream& s, bool& a, int, int=0) { char f=ser_readdata8(s); a=f; }
233 
234 
242 inline unsigned int GetSizeOfCompactSize(uint64_t nSize)
243 {
244  if (nSize < 253)
245  return sizeof(unsigned char);
246  else if (nSize <= std::numeric_limits<unsigned short>::max())
247  return sizeof(unsigned char) + sizeof(unsigned short);
248  else if (nSize <= std::numeric_limits<unsigned int>::max())
249  return sizeof(unsigned char) + sizeof(unsigned int);
250  else
251  return sizeof(unsigned char) + sizeof(uint64_t);
252 }
253 
254 template <typename Stream>
255 void WriteCompactSize(Stream& os, uint64_t nSize)
256 {
257  if (nSize < 253) {
258  ser_writedata8(os, nSize);
259  } else if (nSize <= std::numeric_limits<unsigned short>::max()) {
260  ser_writedata8(os, 253);
261  ser_writedata16(os, nSize);
262  } else if (nSize <= std::numeric_limits<unsigned int>::max()) {
263  ser_writedata8(os, 254);
264  ser_writedata32(os, nSize);
265  } else {
266  ser_writedata8(os, 255);
267  ser_writedata64(os, nSize);
268  }
269  return;
270 }
271 
272 template <typename Stream>
273 uint64_t ReadCompactSize(Stream& is)
274 {
275  uint8_t chSize = ser_readdata8(is);
276  uint64_t nSizeRet = 0;
277  if (chSize < 253) {
278  nSizeRet = chSize;
279  } else if (chSize == 253) {
280  nSizeRet = ser_readdata16(is);
281  if (nSizeRet < 253)
282  throw std::ios_base::failure("non-canonical ReadCompactSize()");
283  } else if (chSize == 254) {
284  nSizeRet = ser_readdata32(is);
285  if (nSizeRet < 0x10000u)
286  throw std::ios_base::failure("non-canonical ReadCompactSize()");
287  } else {
288  nSizeRet = ser_readdata64(is);
289  if (nSizeRet < 0x100000000ULL)
290  throw std::ios_base::failure("non-canonical ReadCompactSize()");
291  }
292  if (nSizeRet > (uint64_t)MAX_SIZE)
293  throw std::ios_base::failure("ReadCompactSize() : size too large");
294  return nSizeRet;
295 }
296 
321 template <typename I>
322 inline unsigned int GetSizeOfVarInt(I n)
323 {
324  int nRet = 0;
325  while (true) {
326  nRet++;
327  if (n <= 0x7F)
328  break;
329  n = (n >> 7) - 1;
330  }
331  return nRet;
332 }
333 
334 template <typename Stream, typename I>
335 void WriteVarInt(Stream& os, I n)
336 {
337  unsigned char tmp[(sizeof(n) * 8 + 6) / 7];
338  int len = 0;
339  while (true) {
340  tmp[len] = (n & 0x7F) | (len ? 0x80 : 0x00);
341  if (n <= 0x7F)
342  break;
343  n = (n >> 7) - 1;
344  len++;
345  }
346  do {
347  ser_writedata8(os, tmp[len]);
348  } while (len--);
349 }
350 
351 template <typename Stream, typename I>
352 I ReadVarInt(Stream& is)
353 {
354  I n = 0;
355  while (true) {
356  unsigned char chData = ser_readdata8(is);
357  n = (n << 7) | (chData & 0x7F);
358  if (chData & 0x80)
359  n++;
360  else
361  return n;
362  }
363 }
364 
365 #define FLATDATA(obj) REF(CFlatData((char*)&(obj), (char*)&(obj) + sizeof(obj)))
366 #define VARINT(obj) REF(WrapVarInt(REF(obj)))
367 #define LIMITED_STRING(obj, n) REF(LimitedString<n>(REF(obj)))
368 
373 {
374 protected:
375  char* pbegin;
376  char* pend;
377 
378 public:
379  CFlatData(void* pbeginIn, void* pendIn) : pbegin((char*)pbeginIn), pend((char*)pendIn) {}
380  template <class T, class TAl>
381  explicit CFlatData(std::vector<T, TAl>& v)
382  {
383  pbegin = (char*)v.data();
384  pend = (char*)(v.data() + v.size());
385  }
386  template <unsigned int N, typename T, typename S, typename D>
388  {
389  pbegin = (char*)begin_ptr(v);
390  pend = (char*)end_ptr(v);
391  }
392  char* begin() { return pbegin; }
393  const char* begin() const { return pbegin; }
394  char* end() { return pend; }
395  const char* end() const { return pend; }
396 
397  unsigned int GetSerializeSize(int, int = 0) const
398  {
399  return pend - pbegin;
400  }
401 
402  template <typename Stream>
403  void Serialize(Stream& s, int, int = 0) const
404  {
405  s.write(pbegin, pend - pbegin);
406  }
407 
408  template <typename Stream>
409  void Unserialize(Stream& s, int, int = 0)
410  {
411  s.read(pbegin, pend - pbegin);
412  }
413 };
414 
415 template <typename I>
416 class CVarInt
417 {
418 protected:
419  I& n;
420 
421 public:
422  CVarInt(I& nIn) : n(nIn) {}
423 
424  unsigned int GetSerializeSize(int, int) const
425  {
426  return GetSizeOfVarInt<I>(n);
427  }
428 
429  template <typename Stream>
430  void Serialize(Stream& s, int, int) const
431  {
432  WriteVarInt<Stream, I>(s, n);
433  }
434 
435  template <typename Stream>
436  void Unserialize(Stream& s, int, int)
437  {
438  n = ReadVarInt<Stream, I>(s);
439  }
440 };
441 
442 template <size_t Limit>
444 {
445 protected:
446  std::string& string;
447 
448 public:
449  LimitedString(std::string& string) : string(string) {}
450 
451  template <typename Stream>
452  void Unserialize(Stream& s, int, int = 0)
453  {
454  size_t size = ReadCompactSize(s);
455  if (size > Limit) {
456  throw std::ios_base::failure("String length limit exceeded");
457  }
458  string.resize(size);
459  if (size != 0)
460  s.read((char*)&string[0], size);
461  }
462 
463  template <typename Stream>
464  void Serialize(Stream& s, int, int = 0) const
465  {
466  WriteCompactSize(s, string.size());
467  if (!string.empty())
468  s.write((char*)&string[0], string.size());
469  }
470 
471  unsigned int GetSerializeSize(int, int = 0) const
472  {
473  return GetSizeOfCompactSize(string.size()) + string.size();
474  }
475 };
476 
477 template <typename I>
479 {
480  return CVarInt<I>(n);
481 }
482 
490 template <typename C>
491 unsigned int GetSerializeSize(const std::basic_string<C>& str, int, int = 0);
492 template <typename Stream, typename C>
493 void Serialize(Stream& os, const std::basic_string<C>& str, int, int = 0);
494 template <typename Stream, typename C>
495 void Unserialize(Stream& is, std::basic_string<C>& str, int, int = 0);
496 
501 template<unsigned int N, typename T> unsigned int GetSerializeSize_impl(const prevector<N, T>& v, int nType, int nVersion, const unsigned char&);
502 template<unsigned int N, typename T, typename V> unsigned int GetSerializeSize_impl(const prevector<N, T>& v, int nType, int nVersion, const V&);
503 template<unsigned int N, typename T> inline unsigned int GetSerializeSize(const prevector<N, T>& v, int nType, int nVersion);
504 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&);
505 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&);
506 template<typename Stream, unsigned int N, typename T> inline void Serialize(Stream& os, const prevector<N, T>& v, int nType, int nVersion);
507 template<typename Stream, unsigned int N, typename T> void Unserialize_impl(Stream& is, prevector<N, T>& v, int nType, int nVersion, const unsigned char&);
508 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&);
509 template<typename Stream, unsigned int N, typename T> inline void Unserialize(Stream& is, prevector<N, T>& v, int nType, int nVersion);
510 
515 template <typename T, typename A>
516 unsigned int GetSerializeSize_impl(const std::vector<T, A>& v, int nType, int nVersion, const unsigned char&);
517 template <typename T, typename A, typename V>
518 unsigned int GetSerializeSize_impl(const std::vector<T, A>& v, int nType, int nVersion, const V&);
519 template <typename T, typename A>
520 inline unsigned int GetSerializeSize(const std::vector<T, A>& v, int nType, int nVersion);
521 template <typename Stream, typename T, typename A>
522 void Serialize_impl(Stream& os, const std::vector<T, A>& v, int nType, int nVersion, const unsigned char&);
523 template <typename Stream, typename T, typename A, typename V>
524 void Serialize_impl(Stream& os, const std::vector<T, A>& v, int nType, int nVersion, const V&);
525 template <typename Stream, typename T, typename A>
526 inline void Serialize(Stream& os, const std::vector<T, A>& v, int nType, int nVersion);
527 template <typename Stream, typename T, typename A>
528 void Unserialize_impl(Stream& is, std::vector<T, A>& v, int nType, int nVersion, const unsigned char&);
529 template <typename Stream, typename T, typename A, typename V>
530 void Unserialize_impl(Stream& is, std::vector<T, A>& v, int nType, int nVersion, const V&);
531 template <typename Stream, typename T, typename A>
532 inline void Unserialize(Stream& is, std::vector<T, A>& v, int nType, int nVersion);
533 
537 template <typename K, typename T>
538 unsigned int GetSerializeSize(const std::pair<K, T>& item, int nType, int nVersion);
539 template <typename Stream, typename K, typename T>
540 void Serialize(Stream& os, const std::pair<K, T>& item, int nType, int nVersion);
541 template <typename Stream, typename K, typename T>
542 void Unserialize(Stream& is, std::pair<K, T>& item, int nType, int nVersion);
543 
547 template <typename K, typename T, typename Pred, typename A>
548 unsigned int GetSerializeSize(const std::map<K, T, Pred, A>& m, int nType, int nVersion);
549 template <typename Stream, typename K, typename T, typename Pred, typename A>
550 void Serialize(Stream& os, const std::map<K, T, Pred, A>& m, int nType, int nVersion);
551 template <typename Stream, typename K, typename T, typename Pred, typename A>
552 void Unserialize(Stream& is, std::map<K, T, Pred, A>& m, int nType, int nVersion);
553 
557 template <typename K, typename Pred, typename A>
558 unsigned int GetSerializeSize(const std::set<K, Pred, A>& m, int nType, int nVersion);
559 template <typename Stream, typename K, typename Pred, typename A>
560 void Serialize(Stream& os, const std::set<K, Pred, A>& m, int nType, int nVersion);
561 template <typename Stream, typename K, typename Pred, typename A>
562 void Unserialize(Stream& is, std::set<K, Pred, A>& m, int nType, int nVersion);
563 
564 
571 template <typename T>
572 inline unsigned int GetSerializeSize(const T& a, long nType, int nVersion)
573 {
574  return a.GetSerializeSize((int)nType, nVersion);
575 }
576 
577 template <typename Stream, typename T>
578 inline void Serialize(Stream& os, const T& a, long nType, int nVersion)
579 {
580  a.Serialize(os, (int)nType, nVersion);
581 }
582 
583 template <typename Stream, typename T>
584 inline void Unserialize(Stream& is, T& a, long nType, int nVersion)
585 {
586  a.Unserialize(is, (int)nType, nVersion);
587 }
588 
589 
593 template <typename C>
594 unsigned int GetSerializeSize(const std::basic_string<C>& str, int, int)
595 {
596  return GetSizeOfCompactSize(str.size()) + str.size() * sizeof(str[0]);
597 }
598 
599 template <typename Stream, typename C>
600 void Serialize(Stream& os, const std::basic_string<C>& str, int, int)
601 {
602  WriteCompactSize(os, str.size());
603  if (!str.empty())
604  os.write((char*)&str[0], str.size() * sizeof(str[0]));
605 }
606 
607 template <typename Stream, typename C>
608 void Unserialize(Stream& is, std::basic_string<C>& str, int, int)
609 {
610  unsigned int nSize = ReadCompactSize(is);
611  str.resize(nSize);
612  if (nSize != 0)
613  is.read((char*)&str[0], nSize * sizeof(str[0]));
614 }
615 
616 
617 
621 template<unsigned int N, typename T>
622 unsigned int GetSerializeSize_impl(const prevector<N, T>& v, int nType, int nVersion, const unsigned char&)
623 {
624  return (GetSizeOfCompactSize(v.size()) + v.size() * sizeof(T));
625 }
626 
627 template<unsigned int N, typename T, typename V>
628 unsigned int GetSerializeSize_impl(const prevector<N, T>& v, int nType, int nVersion, const V&)
629 {
630  unsigned int nSize = GetSizeOfCompactSize(v.size());
631  for (typename prevector<N, T>::const_iterator vi = v.begin(); vi != v.end(); ++vi)
632  nSize += GetSerializeSize((*vi), nType, nVersion);
633  return nSize;
634 }
635 
636 template<unsigned int N, typename T>
637 inline unsigned int GetSerializeSize(const prevector<N, T>& v, int nType, int nVersion)
638 {
639  return GetSerializeSize_impl(v, nType, nVersion, T());
640 }
641 
642 
643 template<typename Stream, unsigned int N, typename T>
644 void Serialize_impl(Stream& os, const prevector<N, T>& v, int nType, int nVersion, const unsigned char&)
645 {
646  WriteCompactSize(os, v.size());
647  if (!v.empty())
648  os.write((char*)&v[0], v.size() * sizeof(T));
649 }
650 
651 template<typename Stream, unsigned int N, typename T, typename V>
652 void Serialize_impl(Stream& os, const prevector<N, T>& v, int nType, int nVersion, const V&)
653 {
654  WriteCompactSize(os, v.size());
655  for (typename prevector<N, T>::const_iterator vi = v.begin(); vi != v.end(); ++vi)
656  ::Serialize(os, (*vi), nType, nVersion);
657 }
658 
659 template<typename Stream, unsigned int N, typename T>
660 inline void Serialize(Stream& os, const prevector<N, T>& v, int nType, int nVersion)
661 {
662  Serialize_impl(os, v, nType, nVersion, T());
663 }
664 
665 
666 template<typename Stream, unsigned int N, typename T>
667 void Unserialize_impl(Stream& is, prevector<N, T>& v, int nType, int nVersion, const unsigned char&)
668 {
669  // Limit size per read so bogus size value won't cause out of memory
670  v.clear();
671  unsigned int nSize = ReadCompactSize(is);
672  unsigned int i = 0;
673  while (i < nSize)
674  {
675  unsigned int blk = std::min(nSize - i, (unsigned int)(1 + 4999999 / sizeof(T)));
676  v.resize(i + blk);
677  is.read((char*)&v[i], blk * sizeof(T));
678  i += blk;
679  }
680 }
681 
682 template<typename Stream, unsigned int N, typename T, typename V>
683 void Unserialize_impl(Stream& is, prevector<N, T>& v, int nType, int nVersion, const V&)
684 {
685  v.clear();
686  unsigned int nSize = ReadCompactSize(is);
687  unsigned int i = 0;
688  unsigned int nMid = 0;
689  while (nMid < nSize)
690  {
691  nMid += 5000000 / sizeof(T);
692  if (nMid > nSize)
693  nMid = nSize;
694  v.resize(nMid);
695  for (; i < nMid; i++)
696  Unserialize(is, v[i], nType, nVersion);
697  }
698 }
699 
700 template<typename Stream, unsigned int N, typename T>
701 inline void Unserialize(Stream& is, prevector<N, T>& v, int nType, int nVersion)
702 {
703  Unserialize_impl(is, v, nType, nVersion, T());
704 }
705 
706 
707 
711 template <typename T, typename A>
712 unsigned int GetSerializeSize_impl(const std::vector<T, A>& v, int nType, int nVersion, const unsigned char&)
713 {
714  return (GetSizeOfCompactSize(v.size()) + v.size() * sizeof(T));
715 }
716 
717 template <typename T, typename A, typename V>
718 unsigned int GetSerializeSize_impl(const std::vector<T, A>& v, int nType, int nVersion, const V&)
719 {
720  unsigned int nSize = GetSizeOfCompactSize(v.size());
721  for (typename std::vector<T, A>::const_iterator vi = v.begin(); vi != v.end(); ++vi)
722  nSize += GetSerializeSize((*vi), nType, nVersion);
723  return nSize;
724 }
725 
726 template <typename T, typename A>
727 inline unsigned int GetSerializeSize(const std::vector<T, A>& v, int nType, int nVersion)
728 {
729  return GetSerializeSize_impl(v, nType, nVersion, T());
730 }
731 
732 
733 template <typename Stream, typename T, typename A>
734 void Serialize_impl(Stream& os, const std::vector<T, A>& v, int nType, int nVersion, const unsigned char&)
735 {
736  WriteCompactSize(os, v.size());
737  if (!v.empty())
738  os.write((char*)&v[0], v.size() * sizeof(T));
739 }
740 
741 template <typename Stream, typename T, typename A, typename V>
742 void Serialize_impl(Stream& os, const std::vector<T, A>& v, int nType, int nVersion, const V&)
743 {
744  WriteCompactSize(os, v.size());
745  for (typename std::vector<T, A>::const_iterator vi = v.begin(); vi != v.end(); ++vi)
746  ::Serialize(os, (*vi), nType, nVersion);
747 }
748 
749 template <typename Stream, typename T, typename A>
750 inline void Serialize(Stream& os, const std::vector<T, A>& v, int nType, int nVersion)
751 {
752  Serialize_impl(os, v, nType, nVersion, T());
753 }
754 
755 
756 template <typename Stream, typename T, typename A>
757 void Unserialize_impl(Stream& is, std::vector<T, A>& v, int nType, int nVersion, const unsigned char&)
758 {
759  // Limit size per read so bogus size value won't cause out of memory
760  v.clear();
761  unsigned int nSize = ReadCompactSize(is);
762  unsigned int i = 0;
763  while (i < nSize) {
764  unsigned int blk = std::min(nSize - i, (unsigned int)(1 + 4999999 / sizeof(T)));
765  v.resize(i + blk);
766  is.read((char*)&v[i], blk * sizeof(T));
767  i += blk;
768  }
769 }
770 
771 template <typename Stream, typename T, typename A, typename V>
772 void Unserialize_impl(Stream& is, std::vector<T, A>& v, int nType, int nVersion, const V&)
773 {
774  v.clear();
775  unsigned int nSize = ReadCompactSize(is);
776  unsigned int i = 0;
777  unsigned int nMid = 0;
778  while (nMid < nSize) {
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 
823 template <typename K, typename T, typename Pred, typename A>
824 unsigned int GetSerializeSize(const std::map<K, T, Pred, A>& m, int nType, int nVersion)
825 {
826  unsigned int nSize = GetSizeOfCompactSize(m.size());
827  for (typename std::map<K, T, Pred, A>::const_iterator mi = m.begin(); mi != m.end(); ++mi)
828  nSize += GetSerializeSize((*mi), nType, nVersion);
829  return nSize;
830 }
831 
832 template <typename Stream, typename K, typename T, typename Pred, typename A>
833 void Serialize(Stream& os, const std::map<K, T, Pred, A>& m, int nType, int nVersion)
834 {
835  WriteCompactSize(os, m.size());
836  for (typename std::map<K, T, Pred, A>::const_iterator mi = m.begin(); mi != m.end(); ++mi)
837  Serialize(os, (*mi), nType, nVersion);
838 }
839 
840 template <typename Stream, typename K, typename T, typename Pred, typename A>
841 void Unserialize(Stream& is, std::map<K, T, Pred, A>& m, int nType, int nVersion)
842 {
843  m.clear();
844  unsigned int nSize = ReadCompactSize(is);
845  typename std::map<K, T, Pred, A>::iterator mi = m.begin();
846  for (unsigned int i = 0; i < nSize; i++) {
847  std::pair<K, T> item;
848  Unserialize(is, item, nType, nVersion);
849  mi = m.insert(mi, item);
850  }
851 }
852 
853 
857 template <typename K, typename Pred, typename A>
858 unsigned int GetSerializeSize(const std::set<K, Pred, A>& m, int nType, int nVersion)
859 {
860  unsigned int nSize = GetSizeOfCompactSize(m.size());
861  for (typename std::set<K, Pred, A>::const_iterator it = m.begin(); it != m.end(); ++it)
862  nSize += GetSerializeSize((*it), nType, nVersion);
863  return nSize;
864 }
865 
866 template <typename Stream, typename K, typename Pred, typename A>
867 void Serialize(Stream& os, const std::set<K, Pred, A>& m, int nType, int nVersion)
868 {
869  WriteCompactSize(os, m.size());
870  for (typename std::set<K, Pred, A>::const_iterator it = m.begin(); it != m.end(); ++it)
871  Serialize(os, (*it), nType, nVersion);
872 }
873 
874 template <typename Stream, typename K, typename Pred, typename A>
875 void Unserialize(Stream& is, std::set<K, Pred, A>& m, int nType, int nVersion)
876 {
877  m.clear();
878  unsigned int nSize = ReadCompactSize(is);
879  typename std::set<K, Pred, A>::iterator it = m.begin();
880  for (unsigned int i = 0; i < nSize; i++) {
881  K key;
882  Unserialize(is, key, nType, nVersion);
883  it = m.insert(it, key);
884  }
885 }
886 
887 
892  bool ForRead() const { return false; }
893 };
895  bool ForRead() const { return true; }
896 };
897 
898 template <typename Stream, typename T>
899 inline void SerReadWrite(Stream& s, const T& obj, int nType, int nVersion, CSerActionSerialize ser_action)
900 {
901  ::Serialize(s, obj, nType, nVersion);
902 }
903 
904 template <typename Stream, typename T>
905 inline void SerReadWrite(Stream& s, T& obj, int nType, int nVersion, CSerActionUnserialize ser_action)
906 {
907  ::Unserialize(s, obj, nType, nVersion);
908 }
909 
910 
912 {
913 protected:
914  size_t nSize;
915 
916 public:
917  int nType;
918  int nVersion;
919 
920  CSizeComputer(int nTypeIn, int nVersionIn) : nSize(0), nType(nTypeIn), nVersion(nVersionIn) {}
921 
922  CSizeComputer& write(const char* psz, size_t nSize)
923  {
924  this->nSize += nSize;
925  return *this;
926  }
927 
928  template <typename T>
929  CSizeComputer& operator<<(const T& obj)
930  {
931  ::Serialize(*this, obj, nType, nVersion);
932  return (*this);
933  }
934 
935  size_t size() const
936  {
937  return nSize;
938  }
939 };
940 
941 #endif // BITCOIN_SERIALIZE_H
htole16
uint16_t htole16(uint16_t host_16bits)
Definition: endian.h:163
CFlatData::CFlatData
CFlatData(std::vector< T, TAl > &v)
Definition: serialize.h:381
GetSizeOfVarInt
unsigned int GetSizeOfVarInt(I n)
Variable-length integers: bytes are a MSB base-128 encoding of the number.
Definition: serialize.h:322
LimitedString::Serialize
void Serialize(Stream &s, int, int=0) const
Definition: serialize.h:464
LimitedString::Unserialize
void Unserialize(Stream &s, int, int=0)
Definition: serialize.h:452
ser_readdata32
uint32_t ser_readdata32(Stream &s)
Definition: serialize.h:113
CSizeComputer::nType
int nType
Definition: serialize.h:917
CFlatData::Serialize
void Serialize(Stream &s, int, int=0) const
Definition: serialize.h:403
SER_GETHASH
@ SER_GETHASH
Definition: serialize.h:161
prevector::const_iterator
Definition: prevector.h:97
ReadCompactSize
uint64_t ReadCompactSize(Stream &is)
Definition: serialize.h:273
CVarInt::CVarInt
CVarInt(I &nIn)
Definition: serialize.h:422
CFlatData::Unserialize
void Unserialize(Stream &s, int, int=0)
Definition: serialize.h:409
ser_float_to_uint32
uint32_t ser_float_to_uint32(float x)
Definition: serialize.h:131
htole64
uint64_t htole64(uint64_t host_64bits)
Definition: endian.h:219
CVarInt::Unserialize
void Unserialize(Stream &s, int, int)
Definition: serialize.h:436
SerReadWrite
void SerReadWrite(Stream &s, const T &obj, int nType, int nVersion, CSerActionSerialize ser_action)
Definition: serialize.h:899
ser_writedata64
void ser_writedata64(Stream &s, uint64_t obj)
Definition: serialize.h:96
prevector::clear
void clear()
Definition: prevector.h:339
le32toh
uint32_t le32toh(uint32_t little_endian_32bits)
Definition: endian.h:205
CVarInt
Definition: serialize.h:416
WriteCompactSize
void WriteCompactSize(Stream &os, uint64_t nSize)
Definition: serialize.h:255
GetSerializeSize
unsigned int GetSerializeSize(char a, int, int=0)
Definition: serialize.h:194
Unserialize
void Unserialize(Stream &s, char &a, int, int=0)
Definition: serialize.h:218
CSizeComputer::size
size_t size() const
Definition: serialize.h:935
CSizeComputer::operator<<
CSizeComputer & operator<<(const T &obj)
Definition: serialize.h:929
SER_NETWORK
@ SER_NETWORK
Definition: serialize.h:159
CSerActionSerialize
Support for ADD_SERIALIZE_METHODS and READWRITE macro.
Definition: serialize.h:891
CSerActionUnserialize
Definition: serialize.h:894
CFlatData::CFlatData
CFlatData(prevector< N, T, S, D > &v)
Definition: serialize.h:387
CFlatData::CFlatData
CFlatData(void *pbeginIn, void *pendIn)
Definition: serialize.h:379
ser_uint64_to_double
double ser_uint64_to_double(uint64_t y)
Definition: serialize.h:137
CFlatData::begin
const char * begin() const
Definition: serialize.h:393
prevector::end
iterator end()
Definition: prevector.h:292
WrapVarInt
CVarInt< I > WrapVarInt(I &n)
Definition: serialize.h:478
CFlatData::pbegin
char * pbegin
Definition: serialize.h:375
ser_uint32_to_float
float ser_uint32_to_float(uint32_t y)
Definition: serialize.h:143
CSizeComputer
Definition: serialize.h:911
CSizeComputer::CSizeComputer
CSizeComputer(int nTypeIn, int nVersionIn)
Definition: serialize.h:920
NCONST_PTR
T * NCONST_PTR(const T *val)
Used to acquire a non-const pointer "this" to generate bodies of const serialization operations from ...
Definition: serialize.h:44
ser_readdata16
uint16_t ser_readdata16(Stream &s)
Definition: serialize.h:107
le16toh
uint16_t le16toh(uint16_t little_endian_16bits)
Definition: endian.h:177
CVarInt::GetSerializeSize
unsigned int GetSerializeSize(int, int) const
Definition: serialize.h:424
CFlatData::pend
char * pend
Definition: serialize.h:376
CVarInt::Serialize
void Serialize(Stream &s, int, int) const
Definition: serialize.h:430
CFlatData::end
char * end()
Definition: serialize.h:394
CFlatData
Wrapper for serializing arrays and POD.
Definition: serialize.h:372
ser_readdata8
uint8_t ser_readdata8(Stream &s)
Definition: serialize.h:101
SER_DISK
@ SER_DISK
Definition: serialize.h:160
GetSizeOfCompactSize
unsigned int GetSizeOfCompactSize(uint64_t nSize)
Compact Size size < 253 – 1 byte size <= USHRT_MAX – 3 bytes (253 + 2 bytes) size <= UINT_MAX – 5 byt...
Definition: serialize.h:242
Serialize_impl
void Serialize_impl(Stream &os, const prevector< N, T > &v, int nType, int nVersion, const unsigned char &)
Definition: serialize.h:644
ser_writedata8
void ser_writedata8(Stream &s, uint8_t obj)
Definition: serialize.h:82
htole32
uint32_t htole32(uint32_t host_32bits)
Definition: endian.h:191
ser_writedata32
void ser_writedata32(Stream &s, uint32_t obj)
Definition: serialize.h:91
ser_double_to_uint64
uint64_t ser_double_to_uint64(double x)
Definition: serialize.h:125
Unserialize_impl
void Unserialize_impl(Stream &is, prevector< N, T > &v, int nType, int nVersion, const unsigned char &)
Definition: serialize.h:667
GetSerializeSize_impl
unsigned int GetSerializeSize_impl(const prevector< N, T > &v, int nType, int nVersion, const unsigned char &)
prevector prevectors of unsigned char are a special case and are intended to be serialized as a singl...
Definition: serialize.h:622
CVarInt::n
I & n
Definition: serialize.h:419
prevector::resize
void resize(size_type new_size)
Definition: prevector.h:316
CFlatData::end
const char * end() const
Definition: serialize.h:395
prevector
Implements a drop-in replacement for std::vector<T> which stores up to N elements directly (without h...
Definition: prevector.h:36
CFlatData::begin
char * begin()
Definition: serialize.h:392
le64toh
uint64_t le64toh(uint64_t little_endian_64bits)
Definition: endian.h:233
CFlatData::GetSerializeSize
unsigned int GetSerializeSize(int, int=0) const
Definition: serialize.h:397
CSerActionSerialize::ForRead
bool ForRead() const
Definition: serialize.h:892
WriteVarInt
void WriteVarInt(Stream &os, I n)
Definition: serialize.h:335
key
CKey key
Definition: bip38tooldialog.cpp:173
ser_writedata16
void ser_writedata16(Stream &s, uint16_t obj)
Definition: serialize.h:86
Serialize
void Serialize(Stream &s, char a, int, int=0)
Definition: serialize.h:206
prevector::size
size_type size() const
Definition: prevector.h:282
prevector::begin
iterator begin()
Definition: prevector.h:290
ReadVarInt
I ReadVarInt(Stream &is)
Definition: serialize.h:352
CSizeComputer::nVersion
int nVersion
Definition: serialize.h:918
LimitedString
Definition: serialize.h:443
prevector::empty
bool empty() const
Definition: prevector.h:286
prevector.h
begin_ptr
V::value_type * begin_ptr(V &v)
Important: Do not use the following functions in new code, but use v.data() and v....
Definition: serialize.h:57
end_ptr
V::value_type * end_ptr(V &v)
Definition: serialize.h:67
REF
T & REF(const T &val)
Used to bypass the rule against non-const reference to temporary where it makes sense with wrappers s...
Definition: serialize.h:34
LimitedString::LimitedString
LimitedString(std::string &string)
Definition: serialize.h:449
LimitedString::GetSerializeSize
unsigned int GetSerializeSize(int, int=0) const
Definition: serialize.h:471
CSerActionUnserialize::ForRead
bool ForRead() const
Definition: serialize.h:895
CSizeComputer::write
CSizeComputer & write(const char *psz, size_t nSize)
Definition: serialize.h:922
ser_readdata64
uint64_t ser_readdata64(Stream &s)
Definition: serialize.h:119
LimitedString::string
std::string & string
Definition: serialize.h:446
CSizeComputer::nSize
size_t nSize
Definition: serialize.h:914
endian.h