BSHA3  0.17.99
P2P Blockchain, based on Bitcoin
serialize.h
Go to the documentation of this file.
1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2018 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 <map>
16 #include <memory>
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 #include <span.h>
26 
27 static const unsigned int MAX_SIZE = 0x02000000;
28 
40 struct deserialize_type {};
42 
47 template<typename T>
48 inline T& REF(const T& val)
49 {
50  return const_cast<T&>(val);
51 }
52 
57 template<typename T>
58 inline T* NCONST_PTR(const T* val)
59 {
60  return const_cast<T*>(val);
61 }
62 
64 inline char* CharCast(char* c) { return c; }
65 inline char* CharCast(unsigned char* c) { return (char*)c; }
66 inline const char* CharCast(const char* c) { return c; }
67 inline const char* CharCast(const unsigned char* c) { return (const char*)c; }
68 
69 /*
70  * Lowest-level serialization and conversion.
71  * @note Sizes of these types are verified in the tests
72  */
73 template<typename Stream> inline void ser_writedata8(Stream &s, uint8_t obj)
74 {
75  s.write((char*)&obj, 1);
76 }
77 template<typename Stream> inline void ser_writedata16(Stream &s, uint16_t obj)
78 {
79  obj = htole16(obj);
80  s.write((char*)&obj, 2);
81 }
82 template<typename Stream> inline void ser_writedata16be(Stream &s, uint16_t obj)
83 {
84  obj = htobe16(obj);
85  s.write((char*)&obj, 2);
86 }
87 template<typename Stream> inline void ser_writedata32(Stream &s, uint32_t obj)
88 {
89  obj = htole32(obj);
90  s.write((char*)&obj, 4);
91 }
92 template<typename Stream> inline void ser_writedata64(Stream &s, uint64_t obj)
93 {
94  obj = htole64(obj);
95  s.write((char*)&obj, 8);
96 }
97 template<typename Stream> inline uint8_t ser_readdata8(Stream &s)
98 {
99  uint8_t obj;
100  s.read((char*)&obj, 1);
101  return obj;
102 }
103 template<typename Stream> inline uint16_t ser_readdata16(Stream &s)
104 {
105  uint16_t obj;
106  s.read((char*)&obj, 2);
107  return le16toh(obj);
108 }
109 template<typename Stream> inline uint16_t ser_readdata16be(Stream &s)
110 {
111  uint16_t obj;
112  s.read((char*)&obj, 2);
113  return be16toh(obj);
114 }
115 template<typename Stream> inline uint32_t ser_readdata32(Stream &s)
116 {
117  uint32_t obj;
118  s.read((char*)&obj, 4);
119  return le32toh(obj);
120 }
121 template<typename Stream> inline uint64_t ser_readdata64(Stream &s)
122 {
123  uint64_t obj;
124  s.read((char*)&obj, 8);
125  return le64toh(obj);
126 }
127 inline uint64_t ser_double_to_uint64(double x)
128 {
129  union { double x; uint64_t y; } tmp;
130  tmp.x = x;
131  return tmp.y;
132 }
133 inline uint32_t ser_float_to_uint32(float x)
134 {
135  union { float x; uint32_t y; } tmp;
136  tmp.x = x;
137  return tmp.y;
138 }
139 inline double ser_uint64_to_double(uint64_t y)
140 {
141  union { double x; uint64_t y; } tmp;
142  tmp.y = y;
143  return tmp.x;
144 }
145 inline float ser_uint32_to_float(uint32_t y)
146 {
147  union { float x; uint32_t y; } tmp;
148  tmp.y = y;
149  return tmp.x;
150 }
151 
152 
154 //
155 // Templates for serializing to anything that looks like a stream,
156 // i.e. anything that supports .read(char*, size_t) and .write(char*, size_t)
157 //
158 
159 class CSizeComputer;
160 
161 enum
162 {
163  // primary actions
164  SER_NETWORK = (1 << 0),
165  SER_DISK = (1 << 1),
166  SER_GETHASH = (1 << 2),
167 };
168 
170 template<typename X> X& ReadWriteAsHelper(X& x) { return x; }
171 template<typename X> const X& ReadWriteAsHelper(const X& x) { return x; }
172 
173 #define READWRITE(...) (::SerReadWriteMany(s, ser_action, __VA_ARGS__))
174 #define READWRITEAS(type, obj) (::SerReadWriteMany(s, ser_action, ReadWriteAsHelper<type>(obj)))
175 
182 #define ADD_SERIALIZE_METHODS \
183  template<typename Stream> \
184  void Serialize(Stream& s) const { \
185  NCONST_PTR(this)->SerializationOp(s, CSerActionSerialize()); \
186  } \
187  template<typename Stream> \
188  void Unserialize(Stream& s) { \
189  SerializationOp(s, CSerActionUnserialize()); \
190  }
191 
192 #ifndef CHAR_EQUALS_INT8
193 template<typename Stream> inline void Serialize(Stream& s, char a ) { ser_writedata8(s, a); } // TODO Get rid of bare char
194 #endif
195 template<typename Stream> inline void Serialize(Stream& s, int8_t a ) { ser_writedata8(s, a); }
196 template<typename Stream> inline void Serialize(Stream& s, uint8_t a ) { ser_writedata8(s, a); }
197 template<typename Stream> inline void Serialize(Stream& s, int16_t a ) { ser_writedata16(s, a); }
198 template<typename Stream> inline void Serialize(Stream& s, uint16_t a) { ser_writedata16(s, a); }
199 template<typename Stream> inline void Serialize(Stream& s, int32_t a ) { ser_writedata32(s, a); }
200 template<typename Stream> inline void Serialize(Stream& s, uint32_t a) { ser_writedata32(s, a); }
201 template<typename Stream> inline void Serialize(Stream& s, int64_t a ) { ser_writedata64(s, a); }
202 template<typename Stream> inline void Serialize(Stream& s, uint64_t a) { ser_writedata64(s, a); }
203 template<typename Stream> inline void Serialize(Stream& s, float a ) { ser_writedata32(s, ser_float_to_uint32(a)); }
204 template<typename Stream> inline void Serialize(Stream& s, double a ) { ser_writedata64(s, ser_double_to_uint64(a)); }
205 template<typename Stream, int N> inline void Serialize(Stream& s, const char (&a)[N]) { s.write(a, N); }
206 template<typename Stream, int N> inline void Serialize(Stream& s, const unsigned char (&a)[N]) { s.write(CharCast(a), N); }
207 template<typename Stream> inline void Serialize(Stream& s, const Span<const unsigned char>& span) { s.write(CharCast(span.data()), span.size()); }
208 template<typename Stream> inline void Serialize(Stream& s, const Span<unsigned char>& span) { s.write(CharCast(span.data()), span.size()); }
209 
210 #ifndef CHAR_EQUALS_INT8
211 template<typename Stream> inline void Unserialize(Stream& s, char& a ) { a = ser_readdata8(s); } // TODO Get rid of bare char
212 #endif
213 template<typename Stream> inline void Unserialize(Stream& s, int8_t& a ) { a = ser_readdata8(s); }
214 template<typename Stream> inline void Unserialize(Stream& s, uint8_t& a ) { a = ser_readdata8(s); }
215 template<typename Stream> inline void Unserialize(Stream& s, int16_t& a ) { a = ser_readdata16(s); }
216 template<typename Stream> inline void Unserialize(Stream& s, uint16_t& a) { a = ser_readdata16(s); }
217 template<typename Stream> inline void Unserialize(Stream& s, int32_t& a ) { a = ser_readdata32(s); }
218 template<typename Stream> inline void Unserialize(Stream& s, uint32_t& a) { a = ser_readdata32(s); }
219 template<typename Stream> inline void Unserialize(Stream& s, int64_t& a ) { a = ser_readdata64(s); }
220 template<typename Stream> inline void Unserialize(Stream& s, uint64_t& a) { a = ser_readdata64(s); }
221 template<typename Stream> inline void Unserialize(Stream& s, float& a ) { a = ser_uint32_to_float(ser_readdata32(s)); }
222 template<typename Stream> inline void Unserialize(Stream& s, double& a ) { a = ser_uint64_to_double(ser_readdata64(s)); }
223 template<typename Stream, int N> inline void Unserialize(Stream& s, char (&a)[N]) { s.read(a, N); }
224 template<typename Stream, int N> inline void Unserialize(Stream& s, unsigned char (&a)[N]) { s.read(CharCast(a), N); }
225 template<typename Stream> inline void Unserialize(Stream& s, Span<unsigned char>& span) { s.read(CharCast(span.data()), span.size()); }
226 
227 template<typename Stream> inline void Serialize(Stream& s, bool a) { char f=a; ser_writedata8(s, f); }
228 template<typename Stream> inline void Unserialize(Stream& s, bool& a) { char f=ser_readdata8(s); a=f; }
229 
230 
231 
232 
233 
234 
242 inline unsigned int GetSizeOfCompactSize(uint64_t nSize)
243 {
244  if (nSize < 253) return sizeof(unsigned char);
245  else if (nSize <= std::numeric_limits<unsigned short>::max()) return sizeof(unsigned char) + sizeof(unsigned short);
246  else if (nSize <= std::numeric_limits<unsigned int>::max()) return sizeof(unsigned char) + sizeof(unsigned int);
247  else return sizeof(unsigned char) + sizeof(uint64_t);
248 }
249 
250 inline void WriteCompactSize(CSizeComputer& os, uint64_t nSize);
251 
252 template<typename Stream>
253 void WriteCompactSize(Stream& os, uint64_t nSize)
254 {
255  if (nSize < 253)
256  {
257  ser_writedata8(os, nSize);
258  }
259  else if (nSize <= std::numeric_limits<unsigned short>::max())
260  {
261  ser_writedata8(os, 253);
262  ser_writedata16(os, nSize);
263  }
264  else if (nSize <= std::numeric_limits<unsigned int>::max())
265  {
266  ser_writedata8(os, 254);
267  ser_writedata32(os, nSize);
268  }
269  else
270  {
271  ser_writedata8(os, 255);
272  ser_writedata64(os, nSize);
273  }
274  return;
275 }
276 
277 template<typename Stream>
278 uint64_t ReadCompactSize(Stream& is)
279 {
280  uint8_t chSize = ser_readdata8(is);
281  uint64_t nSizeRet = 0;
282  if (chSize < 253)
283  {
284  nSizeRet = chSize;
285  }
286  else if (chSize == 253)
287  {
288  nSizeRet = ser_readdata16(is);
289  if (nSizeRet < 253)
290  throw std::ios_base::failure("non-canonical ReadCompactSize()");
291  }
292  else if (chSize == 254)
293  {
294  nSizeRet = ser_readdata32(is);
295  if (nSizeRet < 0x10000u)
296  throw std::ios_base::failure("non-canonical ReadCompactSize()");
297  }
298  else
299  {
300  nSizeRet = ser_readdata64(is);
301  if (nSizeRet < 0x100000000ULL)
302  throw std::ios_base::failure("non-canonical ReadCompactSize()");
303  }
304  if (nSizeRet > (uint64_t)MAX_SIZE)
305  throw std::ios_base::failure("ReadCompactSize(): size too large");
306  return nSizeRet;
307 }
308 
344 
345 template <VarIntMode Mode, typename I>
347  constexpr CheckVarIntMode()
348  {
349  static_assert(Mode != VarIntMode::DEFAULT || std::is_unsigned<I>::value, "Unsigned type required with mode DEFAULT.");
350  static_assert(Mode != VarIntMode::NONNEGATIVE_SIGNED || std::is_signed<I>::value, "Signed type required with mode NONNEGATIVE_SIGNED.");
351  }
352 };
353 
354 template<VarIntMode Mode, typename I>
355 inline unsigned int GetSizeOfVarInt(I n)
356 {
358  int nRet = 0;
359  while(true) {
360  nRet++;
361  if (n <= 0x7F)
362  break;
363  n = (n >> 7) - 1;
364  }
365  return nRet;
366 }
367 
368 template<typename I>
369 inline void WriteVarInt(CSizeComputer& os, I n);
370 
371 template<typename Stream, VarIntMode Mode, typename I>
372 void WriteVarInt(Stream& os, I n)
373 {
375  unsigned char tmp[(sizeof(n)*8+6)/7];
376  int len=0;
377  while(true) {
378  tmp[len] = (n & 0x7F) | (len ? 0x80 : 0x00);
379  if (n <= 0x7F)
380  break;
381  n = (n >> 7) - 1;
382  len++;
383  }
384  do {
385  ser_writedata8(os, tmp[len]);
386  } while(len--);
387 }
388 
389 template<typename Stream, VarIntMode Mode, typename I>
390 I ReadVarInt(Stream& is)
391 {
393  I n = 0;
394  while(true) {
395  unsigned char chData = ser_readdata8(is);
396  if (n > (std::numeric_limits<I>::max() >> 7)) {
397  throw std::ios_base::failure("ReadVarInt(): size too large");
398  }
399  n = (n << 7) | (chData & 0x7F);
400  if (chData & 0x80) {
401  if (n == std::numeric_limits<I>::max()) {
402  throw std::ios_base::failure("ReadVarInt(): size too large");
403  }
404  n++;
405  } else {
406  return n;
407  }
408  }
409 }
410 
411 #define VARINT(obj, ...) WrapVarInt<__VA_ARGS__>(REF(obj))
412 #define COMPACTSIZE(obj) CCompactSize(REF(obj))
413 #define LIMITED_STRING(obj,n) LimitedString< n >(REF(obj))
414 
415 template<VarIntMode Mode, typename I>
416 class CVarInt
417 {
418 protected:
419  I &n;
420 public:
421  explicit CVarInt(I& nIn) : n(nIn) { }
422 
423  template<typename Stream>
424  void Serialize(Stream &s) const {
425  WriteVarInt<Stream,Mode,I>(s, n);
426  }
427 
428  template<typename Stream>
429  void Unserialize(Stream& s) {
430  n = ReadVarInt<Stream,Mode,I>(s);
431  }
432 };
433 
443 template<typename I>
445 {
446 protected:
447  I& m_val;
448 public:
449  explicit BigEndian(I& val) : m_val(val)
450  {
451  static_assert(std::is_unsigned<I>::value, "BigEndian type must be unsigned integer");
452  static_assert(sizeof(I) == 2 && std::numeric_limits<I>::min() == 0 && std::numeric_limits<I>::max() == std::numeric_limits<uint16_t>::max(), "Unsupported BigEndian size");
453  }
454 
455  template<typename Stream>
456  void Serialize(Stream& s) const
457  {
459  }
460 
461  template<typename Stream>
462  void Unserialize(Stream& s)
463  {
464  m_val = ser_readdata16be(s);
465  }
466 };
467 
469 {
470 protected:
471  uint64_t &n;
472 public:
473  explicit CCompactSize(uint64_t& nIn) : n(nIn) { }
474 
475  template<typename Stream>
476  void Serialize(Stream &s) const {
477  WriteCompactSize<Stream>(s, n);
478  }
479 
480  template<typename Stream>
481  void Unserialize(Stream& s) {
482  n = ReadCompactSize<Stream>(s);
483  }
484 };
485 
486 template<size_t Limit>
488 {
489 protected:
490  std::string& string;
491 public:
492  explicit LimitedString(std::string& _string) : string(_string) {}
493 
494  template<typename Stream>
495  void Unserialize(Stream& s)
496  {
497  size_t size = ReadCompactSize(s);
498  if (size > Limit) {
499  throw std::ios_base::failure("String length limit exceeded");
500  }
501  string.resize(size);
502  if (size != 0)
503  s.read((char*)string.data(), size);
504  }
505 
506  template<typename Stream>
507  void Serialize(Stream& s) const
508  {
509  WriteCompactSize(s, string.size());
510  if (!string.empty())
511  s.write((char*)string.data(), string.size());
512  }
513 };
514 
515 template<VarIntMode Mode=VarIntMode::DEFAULT, typename I>
517 
518 template<typename I>
520 
528 template<typename Stream, typename C> void Serialize(Stream& os, const std::basic_string<C>& str);
529 template<typename Stream, typename C> void Unserialize(Stream& is, std::basic_string<C>& str);
530 
535 template<typename Stream, unsigned int N, typename T> void Serialize_impl(Stream& os, const prevector<N, T>& v, const unsigned char&);
536 template<typename Stream, unsigned int N, typename T, typename V> void Serialize_impl(Stream& os, const prevector<N, T>& v, const V&);
537 template<typename Stream, unsigned int N, typename T> inline void Serialize(Stream& os, const prevector<N, T>& v);
538 template<typename Stream, unsigned int N, typename T> void Unserialize_impl(Stream& is, prevector<N, T>& v, const unsigned char&);
539 template<typename Stream, unsigned int N, typename T, typename V> void Unserialize_impl(Stream& is, prevector<N, T>& v, const V&);
540 template<typename Stream, unsigned int N, typename T> inline void Unserialize(Stream& is, prevector<N, T>& v);
541 
546 template<typename Stream, typename T, typename A> void Serialize_impl(Stream& os, const std::vector<T, A>& v, const unsigned char&);
547 template<typename Stream, typename T, typename A, typename V> void Serialize_impl(Stream& os, const std::vector<T, A>& v, const V&);
548 template<typename Stream, typename T, typename A> inline void Serialize(Stream& os, const std::vector<T, A>& v);
549 template<typename Stream, typename T, typename A> void Unserialize_impl(Stream& is, std::vector<T, A>& v, const unsigned char&);
550 template<typename Stream, typename T, typename A, typename V> void Unserialize_impl(Stream& is, std::vector<T, A>& v, const V&);
551 template<typename Stream, typename T, typename A> inline void Unserialize(Stream& is, std::vector<T, A>& v);
552 
556 template<typename Stream, typename K, typename T> void Serialize(Stream& os, const std::pair<K, T>& item);
557 template<typename Stream, typename K, typename T> void Unserialize(Stream& is, std::pair<K, T>& item);
558 
562 template<typename Stream, typename K, typename T, typename Pred, typename A> void Serialize(Stream& os, const std::map<K, T, Pred, A>& m);
563 template<typename Stream, typename K, typename T, typename Pred, typename A> void Unserialize(Stream& is, std::map<K, T, Pred, A>& m);
564 
568 template<typename Stream, typename K, typename Pred, typename A> void Serialize(Stream& os, const std::set<K, Pred, A>& m);
569 template<typename Stream, typename K, typename Pred, typename A> void Unserialize(Stream& is, std::set<K, Pred, A>& m);
570 
574 template<typename Stream, typename T> void Serialize(Stream& os, const std::shared_ptr<const T>& p);
575 template<typename Stream, typename T> void Unserialize(Stream& os, std::shared_ptr<const T>& p);
576 
580 template<typename Stream, typename T> void Serialize(Stream& os, const std::unique_ptr<const T>& p);
581 template<typename Stream, typename T> void Unserialize(Stream& os, std::unique_ptr<const T>& p);
582 
583 
584 
588 template<typename Stream, typename T>
589 inline void Serialize(Stream& os, const T& a)
590 {
591  a.Serialize(os);
592 }
593 
594 template<typename Stream, typename T>
595 inline void Unserialize(Stream& is, T&& a)
596 {
597  a.Unserialize(is);
598 }
599 
600 
601 
602 
603 
607 template<typename Stream, typename C>
608 void Serialize(Stream& os, const std::basic_string<C>& str)
609 {
610  WriteCompactSize(os, str.size());
611  if (!str.empty())
612  os.write((char*)str.data(), str.size() * sizeof(C));
613 }
614 
615 template<typename Stream, typename C>
616 void Unserialize(Stream& is, std::basic_string<C>& str)
617 {
618  unsigned int nSize = ReadCompactSize(is);
619  str.resize(nSize);
620  if (nSize != 0)
621  is.read((char*)str.data(), nSize * sizeof(C));
622 }
623 
624 
625 
629 template<typename Stream, unsigned int N, typename T>
630 void Serialize_impl(Stream& os, const prevector<N, T>& v, const unsigned char&)
631 {
632  WriteCompactSize(os, v.size());
633  if (!v.empty())
634  os.write((char*)v.data(), v.size() * sizeof(T));
635 }
636 
637 template<typename Stream, unsigned int N, typename T, typename V>
638 void Serialize_impl(Stream& os, const prevector<N, T>& v, const V&)
639 {
640  WriteCompactSize(os, v.size());
641  for (typename prevector<N, T>::const_iterator vi = v.begin(); vi != v.end(); ++vi)
642  ::Serialize(os, (*vi));
643 }
644 
645 template<typename Stream, unsigned int N, typename T>
646 inline void Serialize(Stream& os, const prevector<N, T>& v)
647 {
648  Serialize_impl(os, v, T());
649 }
650 
651 
652 template<typename Stream, unsigned int N, typename T>
653 void Unserialize_impl(Stream& is, prevector<N, T>& v, const unsigned char&)
654 {
655  // Limit size per read so bogus size value won't cause out of memory
656  v.clear();
657  unsigned int nSize = ReadCompactSize(is);
658  unsigned int i = 0;
659  while (i < nSize)
660  {
661  unsigned int blk = std::min(nSize - i, (unsigned int)(1 + 4999999 / sizeof(T)));
662  v.resize(i + blk);
663  is.read((char*)&v[i], blk * sizeof(T));
664  i += blk;
665  }
666 }
667 
668 template<typename Stream, unsigned int N, typename T, typename V>
669 void Unserialize_impl(Stream& is, prevector<N, T>& v, const V&)
670 {
671  v.clear();
672  unsigned int nSize = ReadCompactSize(is);
673  unsigned int i = 0;
674  unsigned int nMid = 0;
675  while (nMid < nSize)
676  {
677  nMid += 5000000 / sizeof(T);
678  if (nMid > nSize)
679  nMid = nSize;
680  v.resize(nMid);
681  for (; i < nMid; i++)
682  Unserialize(is, v[i]);
683  }
684 }
685 
686 template<typename Stream, unsigned int N, typename T>
687 inline void Unserialize(Stream& is, prevector<N, T>& v)
688 {
689  Unserialize_impl(is, v, T());
690 }
691 
692 
693 
697 template<typename Stream, typename T, typename A>
698 void Serialize_impl(Stream& os, const std::vector<T, A>& v, const unsigned char&)
699 {
700  WriteCompactSize(os, v.size());
701  if (!v.empty())
702  os.write((char*)v.data(), v.size() * sizeof(T));
703 }
704 
705 template<typename Stream, typename T, typename A, typename V>
706 void Serialize_impl(Stream& os, const std::vector<T, A>& v, const V&)
707 {
708  WriteCompactSize(os, v.size());
709  for (typename std::vector<T, A>::const_iterator vi = v.begin(); vi != v.end(); ++vi)
710  ::Serialize(os, (*vi));
711 }
712 
713 template<typename Stream, typename T, typename A>
714 inline void Serialize(Stream& os, const std::vector<T, A>& v)
715 {
716  Serialize_impl(os, v, T());
717 }
718 
719 
720 template<typename Stream, typename T, typename A>
721 void Unserialize_impl(Stream& is, std::vector<T, A>& v, const unsigned char&)
722 {
723  // Limit size per read so bogus size value won't cause out of memory
724  v.clear();
725  unsigned int nSize = ReadCompactSize(is);
726  unsigned int i = 0;
727  while (i < nSize)
728  {
729  unsigned int blk = std::min(nSize - i, (unsigned int)(1 + 4999999 / sizeof(T)));
730  v.resize(i + blk);
731  is.read((char*)&v[i], blk * sizeof(T));
732  i += blk;
733  }
734 }
735 
736 template<typename Stream, typename T, typename A, typename V>
737 void Unserialize_impl(Stream& is, std::vector<T, A>& v, const V&)
738 {
739  v.clear();
740  unsigned int nSize = ReadCompactSize(is);
741  unsigned int i = 0;
742  unsigned int nMid = 0;
743  while (nMid < nSize)
744  {
745  nMid += 5000000 / sizeof(T);
746  if (nMid > nSize)
747  nMid = nSize;
748  v.resize(nMid);
749  for (; i < nMid; i++)
750  Unserialize(is, v[i]);
751  }
752 }
753 
754 template<typename Stream, typename T, typename A>
755 inline void Unserialize(Stream& is, std::vector<T, A>& v)
756 {
757  Unserialize_impl(is, v, T());
758 }
759 
760 
761 
765 template<typename Stream, typename K, typename T>
766 void Serialize(Stream& os, const std::pair<K, T>& item)
767 {
768  Serialize(os, item.first);
769  Serialize(os, item.second);
770 }
771 
772 template<typename Stream, typename K, typename T>
773 void Unserialize(Stream& is, std::pair<K, T>& item)
774 {
775  Unserialize(is, item.first);
776  Unserialize(is, item.second);
777 }
778 
779 
780 
784 template<typename Stream, typename K, typename T, typename Pred, typename A>
785 void Serialize(Stream& os, const std::map<K, T, Pred, A>& m)
786 {
787  WriteCompactSize(os, m.size());
788  for (const auto& entry : m)
789  Serialize(os, entry);
790 }
791 
792 template<typename Stream, typename K, typename T, typename Pred, typename A>
793 void Unserialize(Stream& is, std::map<K, T, Pred, A>& m)
794 {
795  m.clear();
796  unsigned int nSize = ReadCompactSize(is);
797  typename std::map<K, T, Pred, A>::iterator mi = m.begin();
798  for (unsigned int i = 0; i < nSize; i++)
799  {
800  std::pair<K, T> item;
801  Unserialize(is, item);
802  mi = m.insert(mi, item);
803  }
804 }
805 
806 
807 
811 template<typename Stream, typename K, typename Pred, typename A>
812 void Serialize(Stream& os, const std::set<K, Pred, A>& m)
813 {
814  WriteCompactSize(os, m.size());
815  for (typename std::set<K, Pred, A>::const_iterator it = m.begin(); it != m.end(); ++it)
816  Serialize(os, (*it));
817 }
818 
819 template<typename Stream, typename K, typename Pred, typename A>
820 void Unserialize(Stream& is, std::set<K, Pred, A>& m)
821 {
822  m.clear();
823  unsigned int nSize = ReadCompactSize(is);
824  typename std::set<K, Pred, A>::iterator it = m.begin();
825  for (unsigned int i = 0; i < nSize; i++)
826  {
827  K key;
828  Unserialize(is, key);
829  it = m.insert(it, key);
830  }
831 }
832 
833 
834 
838 template<typename Stream, typename T> void
839 Serialize(Stream& os, const std::unique_ptr<const T>& p)
840 {
841  Serialize(os, *p);
842 }
843 
844 template<typename Stream, typename T>
845 void Unserialize(Stream& is, std::unique_ptr<const T>& p)
846 {
847  p.reset(new T(deserialize, is));
848 }
849 
850 
851 
855 template<typename Stream, typename T> void
856 Serialize(Stream& os, const std::shared_ptr<const T>& p)
857 {
858  Serialize(os, *p);
859 }
860 
861 template<typename Stream, typename T>
862 void Unserialize(Stream& is, std::shared_ptr<const T>& p)
863 {
864  p = std::make_shared<const T>(deserialize, is);
865 }
866 
867 
868 
873 {
874  constexpr bool ForRead() const { return false; }
875 };
877 {
878  constexpr bool ForRead() const { return true; }
879 };
880 
881 
882 
883 
884 
885 
886 
887 
888 /* ::GetSerializeSize implementations
889  *
890  * Computing the serialized size of objects is done through a special stream
891  * object of type CSizeComputer, which only records the number of bytes written
892  * to it.
893  *
894  * If your Serialize or SerializationOp method has non-trivial overhead for
895  * serialization, it may be worthwhile to implement a specialized version for
896  * CSizeComputer, which uses the s.seek() method to record bytes that would
897  * be written instead.
898  */
900 {
901 protected:
902  size_t nSize;
903 
904  const int nVersion;
905 public:
906  explicit CSizeComputer(int nVersionIn) : nSize(0), nVersion(nVersionIn) {}
907 
908  void write(const char *psz, size_t _nSize)
909  {
910  this->nSize += _nSize;
911  }
912 
914  void seek(size_t _nSize)
915  {
916  this->nSize += _nSize;
917  }
918 
919  template<typename T>
920  CSizeComputer& operator<<(const T& obj)
921  {
922  ::Serialize(*this, obj);
923  return (*this);
924  }
925 
926  size_t size() const {
927  return nSize;
928  }
929 
930  int GetVersion() const { return nVersion; }
931 };
932 
933 template<typename Stream>
934 void SerializeMany(Stream& s)
935 {
936 }
937 
938 template<typename Stream, typename Arg, typename... Args>
939 void SerializeMany(Stream& s, const Arg& arg, const Args&... args)
940 {
941  ::Serialize(s, arg);
942  ::SerializeMany(s, args...);
943 }
944 
945 template<typename Stream>
946 inline void UnserializeMany(Stream& s)
947 {
948 }
949 
950 template<typename Stream, typename Arg, typename... Args>
951 inline void UnserializeMany(Stream& s, Arg&& arg, Args&&... args)
952 {
953  ::Unserialize(s, arg);
954  ::UnserializeMany(s, args...);
955 }
956 
957 template<typename Stream, typename... Args>
958 inline void SerReadWriteMany(Stream& s, CSerActionSerialize ser_action, const Args&... args)
959 {
960  ::SerializeMany(s, args...);
961 }
962 
963 template<typename Stream, typename... Args>
964 inline void SerReadWriteMany(Stream& s, CSerActionUnserialize ser_action, Args&&... args)
965 {
966  ::UnserializeMany(s, args...);
967 }
968 
969 template<typename I>
970 inline void WriteVarInt(CSizeComputer &s, I n)
971 {
972  s.seek(GetSizeOfVarInt<I>(n));
973 }
974 
975 inline void WriteCompactSize(CSizeComputer &s, uint64_t nSize)
976 {
977  s.seek(GetSizeOfCompactSize(nSize));
978 }
979 
980 template <typename T>
981 size_t GetSerializeSize(const T& t, int nVersion = 0)
982 {
983  return (CSizeComputer(nVersion) << t).size();
984 }
985 
986 template <typename... T>
987 size_t GetSerializeSizeMany(int nVersion, const T&... t)
988 {
989  CSizeComputer sc(nVersion);
990  SerializeMany(sc, t...);
991  return sc.size();
992 }
993 
994 #endif // BITCOIN_SERIALIZE_H
uint64_t ser_double_to_uint64(double x)
Definition: serialize.h:127
CSizeComputer(int nVersionIn)
Definition: serialize.h:906
std::string & string
Definition: serialize.h:490
X & ReadWriteAsHelper(X &x)
Convert the reference base type to X, without changing constness or reference type.
Definition: serialize.h:170
void Unserialize(Stream &s)
Definition: serialize.h:429
constexpr std::ptrdiff_t size() const noexcept
Definition: span.h:30
void resize(size_type new_size)
Definition: prevector.h:327
uint32_t ser_float_to_uint32(float x)
Definition: serialize.h:133
uint8_t ser_readdata8(Stream &s)
Definition: serialize.h:97
void clear()
Definition: prevector.h:354
void ser_writedata64(Stream &s, uint64_t obj)
Definition: serialize.h:92
uint64_t & n
Definition: serialize.h:471
uint64_t ReadCompactSize(Stream &is)
Definition: serialize.h:278
void WriteVarInt(CSizeComputer &os, I n)
Definition: serialize.h:970
void WriteCompactSize(CSizeComputer &os, uint64_t nSize)
Definition: serialize.h:975
size_t size() const
Definition: serialize.h:926
void ser_writedata32(Stream &s, uint32_t obj)
Definition: serialize.h:87
constexpr deserialize_type deserialize
Definition: serialize.h:41
unsigned int GetSizeOfCompactSize(uint64_t nSize)
Compact Size size < 253 – 1 byte size <= USHRT_MAX – 3 bytes (253 + 2 bytes) size <= UINT_MAX – 5 ...
Definition: serialize.h:242
CCompactSize(uint64_t &nIn)
Definition: serialize.h:473
void Unserialize(Stream &s)
Definition: serialize.h:481
BigEndian(I &val)
Definition: serialize.h:449
const int nVersion
Definition: serialize.h:904
void UnserializeMany(Stream &s)
Definition: serialize.h:946
BigEndian< I > WrapBigEndian(I &n)
Definition: serialize.h:519
uint32_t htole32(uint32_t host_32bits)
Definition: endian.h:191
Dummy data type to identify deserializing constructors.
Definition: serialize.h:40
char * CharCast(char *c)
Safely convert odd char pointer types to standard ones.
Definition: serialize.h:64
value_type * data()
Definition: prevector.h:519
size_t GetSerializeSize(const T &t, int nVersion=0)
Definition: serialize.h:981
void Serialize(Stream &s, char a)
Definition: serialize.h:193
CVarInt< Mode, I > WrapVarInt(I &n)
Definition: serialize.h:516
void Unserialize(Stream &s)
Definition: serialize.h:495
CSizeComputer & operator<<(const T &obj)
Definition: serialize.h:920
iterator end()
Definition: prevector.h:303
void Serialize(Stream &s) const
Definition: serialize.h:507
void SerReadWriteMany(Stream &s, CSerActionSerialize ser_action, const Args &... args)
Definition: serialize.h:958
uint16_t ser_readdata16(Stream &s)
Definition: serialize.h:103
uint32_t ser_readdata32(Stream &s)
Definition: serialize.h:115
void Serialize(Stream &s) const
Definition: serialize.h:476
Serialization wrapper class for big-endian integers.
Definition: serialize.h:444
constexpr CheckVarIntMode()
Definition: serialize.h:347
void ser_writedata16(Stream &s, uint16_t obj)
Definition: serialize.h:77
uint16_t htobe16(uint16_t host_16bits)
Definition: endian.h:156
constexpr bool ForRead() const
Definition: serialize.h:878
I & n
Definition: serialize.h:419
VarIntMode
Variable-length integers: bytes are a MSB base-128 encoding of the number.
Definition: serialize.h:343
I ReadVarInt(Stream &is)
Definition: serialize.h:390
uint16_t le16toh(uint16_t little_endian_16bits)
Definition: endian.h:177
double ser_uint64_to_double(uint64_t y)
Definition: serialize.h:139
Support for ADD_SERIALIZE_METHODS and READWRITE macro.
Definition: serialize.h:872
constexpr bool ForRead() const
Definition: serialize.h:874
void SerializeMany(Stream &s)
Definition: serialize.h:934
Implements a drop-in replacement for std::vector<T> which stores up to N elements directly (without h...
Definition: prevector.h:39
uint64_t ser_readdata64(Stream &s)
Definition: serialize.h:121
CVarInt(I &nIn)
Definition: serialize.h:421
#define X(name)
Definition: net.cpp:685
void seek(size_t _nSize)
Pretend _nSize bytes are written, without specifying them.
Definition: serialize.h:914
uint16_t htole16(uint16_t host_16bits)
Definition: endian.h:163
uint16_t ser_readdata16be(Stream &s)
Definition: serialize.h:109
uint64_t le64toh(uint64_t little_endian_64bits)
Definition: endian.h:233
uint16_t be16toh(uint16_t big_endian_16bits)
Definition: endian.h:170
constexpr C * data() const noexcept
Definition: span.h:27
int GetVersion() const
Definition: serialize.h:930
void Unserialize(Stream &s)
Definition: serialize.h:462
bool empty() const
Definition: prevector.h:297
uint64_t htole64(uint64_t host_64bits)
Definition: endian.h:219
void write(const char *psz, size_t _nSize)
Definition: serialize.h:908
void Serialize(Stream &s) const
Definition: serialize.h:424
unsigned int GetSizeOfVarInt(I n)
Definition: serialize.h:355
size_t GetSerializeSizeMany(int nVersion, const T &... t)
Definition: serialize.h:987
I & m_val
Definition: serialize.h:447
void Unserialize(Stream &s, char &a)
Definition: serialize.h:211
iterator begin()
Definition: prevector.h:301
void ser_writedata16be(Stream &s, uint16_t obj)
Definition: serialize.h:82
size_type size() const
Definition: prevector.h:293
void Serialize(Stream &s) const
Definition: serialize.h:456
A Span is an object that can refer to a contiguous sequence of objects.
Definition: span.h:17
void Serialize_impl(Stream &os, const prevector< N, T > &v, const unsigned char &)
prevector prevectors of unsigned char are a special case and are intended to be serialized as a singl...
Definition: serialize.h:630
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:58
void Unserialize_impl(Stream &is, prevector< N, T > &v, const unsigned char &)
Definition: serialize.h:653
uint32_t le32toh(uint32_t little_endian_32bits)
Definition: endian.h:205
T & REF(const T &val)
Used to bypass the rule against non-const reference to temporary where it makes sense with wrappers...
Definition: serialize.h:48
size_t nSize
Definition: serialize.h:902
LimitedString(std::string &_string)
Definition: serialize.h:492
void ser_writedata8(Stream &s, uint8_t obj)
Definition: serialize.h:73
float ser_uint32_to_float(uint32_t y)
Definition: serialize.h:145