Bitcoin ABC  0.26.3
P2P Digital Currency
serialize.h
Go to the documentation of this file.
1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2016 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 #include <prevector.h>
11 #include <rcu.h>
12 #include <span.h>
13 
14 #include <algorithm>
15 #include <array>
16 #include <cstdint>
17 #include <cstring>
18 #include <ios>
19 #include <limits>
20 #include <map>
21 #include <memory>
22 #include <set>
23 #include <string>
24 #include <utility>
25 #include <vector>
26 
31 static constexpr uint64_t MAX_SIZE = 0x02000000;
32 
37 static const unsigned int MAX_VECTOR_ALLOCATE = 5000000;
38 
49 struct deserialize_type {};
51 
53 inline char *CharCast(char *c) {
54  return c;
55 }
56 inline char *CharCast(uint8_t *c) {
57  return (char *)c;
58 }
59 inline const char *CharCast(const char *c) {
60  return c;
61 }
62 inline const char *CharCast(const uint8_t *c) {
63  return (const char *)c;
64 }
65 
70 template <typename Stream> inline void ser_writedata8(Stream &s, uint8_t obj) {
71  s.write((char *)&obj, 1);
72 }
73 template <typename Stream>
74 inline void ser_writedata16(Stream &s, uint16_t obj) {
75  obj = htole16(obj);
76  s.write((char *)&obj, 2);
77 }
78 template <typename Stream>
79 inline void ser_writedata16be(Stream &s, uint16_t obj) {
80  obj = htobe16(obj);
81  s.write((char *)&obj, 2);
82 }
83 template <typename Stream>
84 inline void ser_writedata32(Stream &s, uint32_t obj) {
85  obj = htole32(obj);
86  s.write((char *)&obj, 4);
87 }
88 template <typename Stream>
89 inline void ser_writedata32be(Stream &s, uint32_t obj) {
90  obj = htobe32(obj);
91  s.write((char *)&obj, 4);
92 }
93 template <typename Stream>
94 inline void ser_writedata64(Stream &s, uint64_t obj) {
95  obj = htole64(obj);
96  s.write((char *)&obj, 8);
97 }
98 template <typename Stream> inline uint8_t ser_readdata8(Stream &s) {
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  uint16_t obj;
105  s.read((char *)&obj, 2);
106  return le16toh(obj);
107 }
108 template <typename Stream> inline uint16_t ser_readdata16be(Stream &s) {
109  uint16_t obj;
110  s.read((char *)&obj, 2);
111  return be16toh(obj);
112 }
113 template <typename Stream> inline uint32_t ser_readdata32(Stream &s) {
114  uint32_t obj;
115  s.read((char *)&obj, 4);
116  return le32toh(obj);
117 }
118 template <typename Stream> inline uint32_t ser_readdata32be(Stream &s) {
119  uint32_t obj;
120  s.read((char *)&obj, 4);
121  return be32toh(obj);
122 }
123 template <typename Stream> inline uint64_t ser_readdata64(Stream &s) {
124  uint64_t obj;
125  s.read((char *)&obj, 8);
126  return le64toh(obj);
127 }
128 inline uint64_t ser_double_to_uint64(double x) {
129  uint64_t tmp;
130  std::memcpy(&tmp, &x, sizeof(x));
131  static_assert(sizeof(tmp) == sizeof(x),
132  "double and uint64_t assumed to have the same size");
133  return tmp;
134 }
135 inline uint32_t ser_float_to_uint32(float x) {
136  uint32_t tmp;
137  std::memcpy(&tmp, &x, sizeof(x));
138  static_assert(sizeof(tmp) == sizeof(x),
139  "float and uint32_t assumed to have the same size");
140  return tmp;
141 }
142 inline double ser_uint64_to_double(uint64_t y) {
143  double tmp;
144  std::memcpy(&tmp, &y, sizeof(y));
145  static_assert(sizeof(tmp) == sizeof(y),
146  "double and uint64_t assumed to have the same size");
147  return tmp;
148 }
149 inline float ser_uint32_to_float(uint32_t y) {
150  float tmp;
151  std::memcpy(&tmp, &y, sizeof(y));
152  static_assert(sizeof(tmp) == sizeof(y),
153  "float and uint32_t assumed to have the same size");
154  return tmp;
155 }
156 
158 //
159 // Templates for serializing to anything that looks like a stream,
160 // i.e. anything that supports .read(char*, size_t) and .write(char*, size_t)
161 //
162 class CSizeComputer;
163 
164 enum {
165  // primary actions
166  SER_NETWORK = (1 << 0),
167  SER_DISK = (1 << 1),
168  SER_GETHASH = (1 << 2),
169 };
170 
173 template <typename X> X &ReadWriteAsHelper(X &x) {
174  return x;
175 }
176 template <typename X> const X &ReadWriteAsHelper(const X &x) {
177  return x;
178 }
179 
180 #define READWRITE(...) (::SerReadWriteMany(s, ser_action, __VA_ARGS__))
181 #define READWRITEAS(type, obj) \
182  (::SerReadWriteMany(s, ser_action, ReadWriteAsHelper<type>(obj)))
183 #define SER_READ(obj, code) \
184  ::SerRead( \
185  s, ser_action, obj, \
186  [&](Stream &s, typename std::remove_const<Type>::type &obj) { code; })
187 #define SER_WRITE(obj, code) \
188  ::SerWrite(s, ser_action, obj, [&](Stream &s, const Type &obj) { code; })
189 
208 #define FORMATTER_METHODS(cls, obj) \
209  template <typename Stream> static void Ser(Stream &s, const cls &obj) { \
210  SerializationOps(obj, s, CSerActionSerialize()); \
211  } \
212  template <typename Stream> static void Unser(Stream &s, cls &obj) { \
213  SerializationOps(obj, s, CSerActionUnserialize()); \
214  } \
215  template <typename Stream, typename Type, typename Operation> \
216  static inline void SerializationOps(Type &obj, Stream &s, \
217  Operation ser_action)
218 
227 #define SERIALIZE_METHODS(cls, obj) \
228  template <typename Stream> void Serialize(Stream &s) const { \
229  static_assert(std::is_same<const cls &, decltype(*this)>::value, \
230  "Serialize type mismatch"); \
231  Ser(s, *this); \
232  } \
233  template <typename Stream> void Unserialize(Stream &s) { \
234  static_assert(std::is_same<cls &, decltype(*this)>::value, \
235  "Unserialize type mismatch"); \
236  Unser(s, *this); \
237  } \
238  FORMATTER_METHODS(cls, obj)
239 
240 #ifndef CHAR_EQUALS_INT8
241 // TODO Get rid of bare char
242 template <typename Stream> inline void Serialize(Stream &s, char a) {
243  ser_writedata8(s, a);
244 }
245 #endif
246 template <typename Stream> inline void Serialize(Stream &s, int8_t a) {
247  ser_writedata8(s, a);
248 }
249 template <typename Stream> inline void Serialize(Stream &s, uint8_t a) {
250  ser_writedata8(s, a);
251 }
252 template <typename Stream> inline void Serialize(Stream &s, int16_t a) {
253  ser_writedata16(s, a);
254 }
255 template <typename Stream> inline void Serialize(Stream &s, uint16_t a) {
256  ser_writedata16(s, a);
257 }
258 template <typename Stream> inline void Serialize(Stream &s, int32_t a) {
259  ser_writedata32(s, a);
260 }
261 template <typename Stream> inline void Serialize(Stream &s, uint32_t a) {
262  ser_writedata32(s, a);
263 }
264 template <typename Stream> inline void Serialize(Stream &s, int64_t a) {
265  ser_writedata64(s, a);
266 }
267 template <typename Stream> inline void Serialize(Stream &s, uint64_t a) {
268  ser_writedata64(s, a);
269 }
270 template <typename Stream> inline void Serialize(Stream &s, float a) {
272 }
273 template <typename Stream> inline void Serialize(Stream &s, double a) {
275 }
276 template <typename Stream, size_t N>
277 inline void Serialize(Stream &s, const int8_t (&a)[N]) {
278  s.write(a, N);
279 }
280 template <typename Stream, size_t N>
281 inline void Serialize(Stream &s, const uint8_t (&a)[N]) {
282  s.write(CharCast(a), N);
283 }
284 template <typename Stream, size_t N>
285 inline void Serialize(Stream &s, const std::array<int8_t, N> &a) {
286  s.write(a.data(), N);
287 }
288 template <typename Stream, size_t N>
289 inline void Serialize(Stream &s, const std::array<uint8_t, N> &a) {
290  s.write(CharCast(a.data()), N);
291 }
292 #ifndef CHAR_EQUALS_INT8
293 // TODO Get rid of bare char
294 template <typename Stream> inline void Unserialize(Stream &s, char &a) {
295  a = ser_readdata8(s);
296 }
297 template <typename Stream, size_t N>
298 inline void Serialize(Stream &s, const char (&a)[N]) {
299  s.write(a, N);
300 }
301 template <typename Stream, size_t N>
302 inline void Serialize(Stream &s, const std::array<char, N> &a) {
303  s.write(a.data(), N);
304 }
305 #endif
306 template <typename Stream>
307 inline void Serialize(Stream &s, const Span<const uint8_t> &span) {
308  s.write(CharCast(span.data()), span.size());
309 }
310 template <typename Stream>
311 inline void Serialize(Stream &s, const Span<uint8_t> &span) {
312  s.write(CharCast(span.data()), span.size());
313 }
314 template <typename Stream> inline void Unserialize(Stream &s, int8_t &a) {
315  a = ser_readdata8(s);
316 }
317 template <typename Stream> inline void Unserialize(Stream &s, uint8_t &a) {
318  a = ser_readdata8(s);
319 }
320 template <typename Stream> inline void Unserialize(Stream &s, int16_t &a) {
321  a = ser_readdata16(s);
322 }
323 template <typename Stream> inline void Unserialize(Stream &s, uint16_t &a) {
324  a = ser_readdata16(s);
325 }
326 template <typename Stream> inline void Unserialize(Stream &s, int32_t &a) {
327  a = ser_readdata32(s);
328 }
329 template <typename Stream> inline void Unserialize(Stream &s, uint32_t &a) {
330  a = ser_readdata32(s);
331 }
332 template <typename Stream> inline void Unserialize(Stream &s, int64_t &a) {
333  a = ser_readdata64(s);
334 }
335 template <typename Stream> inline void Unserialize(Stream &s, uint64_t &a) {
336  a = ser_readdata64(s);
337 }
338 template <typename Stream> inline void Unserialize(Stream &s, float &a) {
340 }
341 template <typename Stream> inline void Unserialize(Stream &s, double &a) {
343 }
344 template <typename Stream, size_t N>
345 inline void Unserialize(Stream &s, int8_t (&a)[N]) {
346  s.read(a, N);
347 }
348 template <typename Stream, size_t N>
349 inline void Unserialize(Stream &s, uint8_t (&a)[N]) {
350  s.read(CharCast(a), N);
351 }
352 template <typename Stream, size_t N>
353 inline void Unserialize(Stream &s, std::array<int8_t, N> &a) {
354  s.read(a.data(), N);
355 }
356 template <typename Stream, size_t N>
357 inline void Unserialize(Stream &s, std::array<uint8_t, N> &a) {
358  s.read(CharCast(a.data()), N);
359 }
360 #ifndef CHAR_EQUALS_INT8
361 template <typename Stream, size_t N>
362 inline void Unserialize(Stream &s, char (&a)[N]) {
363  s.read(CharCast(a), N);
364 }
365 template <typename Stream, size_t N>
366 inline void Unserialize(Stream &s, std::array<char, N> &a) {
367  s.read(CharCast(a.data()), N);
368 }
369 #endif
370 
371 template <typename Stream> inline void Serialize(Stream &s, bool a) {
372  char f = a;
373  ser_writedata8(s, f);
374 }
375 template <typename Stream> inline void Unserialize(Stream &s, bool &a) {
376  char f = ser_readdata8(s);
377  a = f;
378 }
379 template <typename Stream>
380 inline void Unserialize(Stream &s, Span<uint8_t> &span) {
381  s.read(CharCast(span.data()), span.size());
382 }
383 
391 inline uint32_t GetSizeOfCompactSize(uint64_t nSize) {
392  if (nSize < 253) {
393  return sizeof(uint8_t);
394  }
395  if (nSize <= std::numeric_limits<uint16_t>::max()) {
396  return sizeof(uint8_t) + sizeof(uint16_t);
397  }
398  if (nSize <= std::numeric_limits<uint32_t>::max()) {
399  return sizeof(uint8_t) + sizeof(uint32_t);
400  }
401 
402  return sizeof(uint8_t) + sizeof(uint64_t);
403 }
404 
405 inline void WriteCompactSize(CSizeComputer &os, uint64_t nSize);
406 
407 template <typename Stream> void WriteCompactSize(Stream &os, uint64_t nSize) {
408  if (nSize < 253) {
409  ser_writedata8(os, nSize);
410  } else if (nSize <= std::numeric_limits<uint16_t>::max()) {
411  ser_writedata8(os, 253);
412  ser_writedata16(os, nSize);
413  } else if (nSize <= std::numeric_limits<uint32_t>::max()) {
414  ser_writedata8(os, 254);
415  ser_writedata32(os, nSize);
416  } else {
417  ser_writedata8(os, 255);
418  ser_writedata64(os, nSize);
419  }
420  return;
421 }
422 
430 template <typename Stream>
431 uint64_t ReadCompactSize(Stream &is, bool range_check = true) {
432  uint8_t chSize = ser_readdata8(is);
433  uint64_t nSizeRet = 0;
434  if (chSize < 253) {
435  nSizeRet = chSize;
436  } else if (chSize == 253) {
437  nSizeRet = ser_readdata16(is);
438  if (nSizeRet < 253) {
439  throw std::ios_base::failure("non-canonical ReadCompactSize()");
440  }
441  } else if (chSize == 254) {
442  nSizeRet = ser_readdata32(is);
443  if (nSizeRet < 0x10000u) {
444  throw std::ios_base::failure("non-canonical ReadCompactSize()");
445  }
446  } else {
447  nSizeRet = ser_readdata64(is);
448  if (nSizeRet < 0x100000000ULL) {
449  throw std::ios_base::failure("non-canonical ReadCompactSize()");
450  }
451  }
452  if (range_check && nSizeRet > MAX_SIZE) {
453  throw std::ios_base::failure("ReadCompactSize(): size too large");
454  }
455  return nSizeRet;
456 }
457 
493 
494 template <VarIntMode Mode, typename I> struct CheckVarIntMode {
495  constexpr CheckVarIntMode() {
496  static_assert(Mode != VarIntMode::DEFAULT || std::is_unsigned<I>::value,
497  "Unsigned type required with mode DEFAULT.");
498  static_assert(Mode != VarIntMode::NONNEGATIVE_SIGNED ||
499  std::is_signed<I>::value,
500  "Signed type required with mode NONNEGATIVE_SIGNED.");
501  }
502 };
503 
504 template <VarIntMode Mode, typename I>
505 inline unsigned int GetSizeOfVarInt(I n) {
507  int nRet = 0;
508  while (true) {
509  nRet++;
510  if (n <= 0x7F) {
511  return nRet;
512  }
513  n = (n >> 7) - 1;
514  }
515 }
516 
517 template <typename I> inline void WriteVarInt(CSizeComputer &os, I n);
518 
519 template <typename Stream, VarIntMode Mode, typename I>
520 void WriteVarInt(Stream &os, I n) {
522  uint8_t tmp[(sizeof(n) * 8 + 6) / 7];
523  int len = 0;
524  while (true) {
525  tmp[len] = (n & 0x7F) | (len ? 0x80 : 0x00);
526  if (n <= 0x7F) {
527  break;
528  }
529  n = (n >> 7) - 1;
530  len++;
531  }
532  do {
533  ser_writedata8(os, tmp[len]);
534  } while (len--);
535 }
536 
537 template <typename Stream, VarIntMode Mode, typename I>
538 I ReadVarInt(Stream &is) {
540  I n = 0;
541  while (true) {
542  uint8_t chData = ser_readdata8(is);
543  if (n > (std::numeric_limits<I>::max() >> 7)) {
544  throw std::ios_base::failure("ReadVarInt(): size too large");
545  }
546  n = (n << 7) | (chData & 0x7F);
547  if ((chData & 0x80) == 0) {
548  return n;
549  }
550  if (n == std::numeric_limits<I>::max()) {
551  throw std::ios_base::failure("ReadVarInt(): size too large");
552  }
553  n++;
554  }
555 }
556 
561 template <typename Formatter, typename T> class Wrapper {
562  static_assert(std::is_lvalue_reference<T>::value,
563  "Wrapper needs an lvalue reference type T");
564 
565 protected:
567 
568 public:
569  explicit Wrapper(T obj) : m_object(obj) {}
570  template <typename Stream> void Serialize(Stream &s) const {
571  Formatter().Ser(s, m_object);
572  }
573  template <typename Stream> void Unserialize(Stream &s) {
574  Formatter().Unser(s, m_object);
575  }
576 };
577 
591 template <typename Formatter, typename T>
592 static inline Wrapper<Formatter, T &> Using(T &&t) {
593  return Wrapper<Formatter, T &>(t);
594 }
595 
596 #define VARINT_MODE(obj, mode) Using<VarIntFormatter<mode>>(obj)
597 #define VARINT(obj) Using<VarIntFormatter<VarIntMode::DEFAULT>>(obj)
598 #define COMPACTSIZE(obj) Using<CompactSizeFormatter<true>>(obj)
599 #define LIMITED_STRING(obj, n) Using<LimitedStringFormatter<n>>(obj)
600 
604 template <VarIntMode Mode> struct VarIntFormatter {
605  template <typename Stream, typename I> void Ser(Stream &s, I v) {
606  WriteVarInt<Stream, Mode, typename std::remove_cv<I>::type>(s, v);
607  }
608 
609  template <typename Stream, typename I> void Unser(Stream &s, I &v) {
610  v = ReadVarInt<Stream, Mode, typename std::remove_cv<I>::type>(s);
611  }
612 };
613 
624 template <int Bytes, bool BigEndian = false> struct CustomUintFormatter {
625  static_assert(Bytes > 0 && Bytes <= 8,
626  "CustomUintFormatter Bytes out of range");
627  static constexpr uint64_t MAX = 0xffffffffffffffff >> (8 * (8 - Bytes));
628 
629  template <typename Stream, typename I> void Ser(Stream &s, I v) {
630  if (v < 0 || v > MAX) {
631  throw std::ios_base::failure(
632  "CustomUintFormatter value out of range");
633  }
634  if (BigEndian) {
635  uint64_t raw = htobe64(v);
636  s.write(((const char *)&raw) + 8 - Bytes, Bytes);
637  } else {
638  uint64_t raw = htole64(v);
639  s.write((const char *)&raw, Bytes);
640  }
641  }
642 
643  template <typename Stream, typename I> void Unser(Stream &s, I &v) {
644  using U = typename std::conditional<std::is_enum<I>::value,
645  std::underlying_type<I>,
646  std::common_type<I>>::type::type;
647  static_assert(std::numeric_limits<U>::max() >= MAX &&
648  std::numeric_limits<U>::min() <= 0,
649  "Assigned type too small");
650  uint64_t raw = 0;
651  if (BigEndian) {
652  s.read(((char *)&raw) + 8 - Bytes, Bytes);
653  v = static_cast<I>(be64toh(raw));
654  } else {
655  s.read((char *)&raw, Bytes);
656  v = static_cast<I>(le64toh(raw));
657  }
658  }
659 };
660 
661 template <int Bytes>
663 
665 template <bool RangeCheck> struct CompactSizeFormatter {
666  template <typename Stream, typename I> void Unser(Stream &s, I &v) {
667  uint64_t n = ReadCompactSize<Stream>(s, RangeCheck);
668  if (n < std::numeric_limits<I>::min() ||
669  n > std::numeric_limits<I>::max()) {
670  throw std::ios_base::failure("CompactSize exceeds limit of type");
671  }
672  v = n;
673  }
674 
675  template <typename Stream, typename I> void Ser(Stream &s, I v) {
676  static_assert(std::is_unsigned<I>::value,
677  "CompactSize only supported for unsigned integers");
678  static_assert(std::numeric_limits<I>::max() <=
679  std::numeric_limits<uint64_t>::max(),
680  "CompactSize only supports 64-bit integers and below");
681 
682  WriteCompactSize<Stream>(s, v);
683  }
684 };
685 
686 template <size_t Limit> struct LimitedStringFormatter {
687  template <typename Stream> void Unser(Stream &s, std::string &v) {
688  size_t size = ReadCompactSize(s);
689  if (size > Limit) {
690  throw std::ios_base::failure("String length limit exceeded");
691  }
692  v.resize(size);
693  if (size != 0) {
694  s.read((char *)v.data(), size);
695  }
696  }
697 
698  template <typename Stream> void Ser(Stream &s, const std::string &v) {
699  s << v;
700  }
701 };
702 
719 template <class Formatter> struct VectorFormatter {
720  template <typename Stream, typename V> void Ser(Stream &s, const V &v) {
721  Formatter formatter;
722  WriteCompactSize(s, v.size());
723  for (const typename V::value_type &elem : v) {
724  formatter.Ser(s, elem);
725  }
726  }
727 
728  template <typename Stream, typename V> void Unser(Stream &s, V &v) {
729  Formatter formatter;
730  v.clear();
731  size_t size = ReadCompactSize(s);
732  size_t allocated = 0;
733  while (allocated < size) {
734  // For DoS prevention, do not blindly allocate as much as the stream
735  // claims to contain. Instead, allocate in 5MiB batches, so that an
736  // attacker actually needs to provide X MiB of data to make us
737  // allocate X+5 Mib.
738  static_assert(sizeof(typename V::value_type) <= MAX_VECTOR_ALLOCATE,
739  "Vector element size too large");
740  allocated =
741  std::min(size, allocated + MAX_VECTOR_ALLOCATE /
742  sizeof(typename V::value_type));
743  v.reserve(allocated);
744  while (v.size() < allocated) {
745  v.emplace_back();
746  formatter.Unser(s, v.back());
747  }
748  }
749  };
750 };
751 
763  uint64_t m_shift = 0;
764 
765 public:
766  template <typename Stream, typename I> void Ser(Stream &s, I v) {
767  if (v < m_shift || v >= std::numeric_limits<uint64_t>::max()) {
768  throw std::ios_base::failure("differential value overflow");
769  }
770  WriteCompactSize(s, v - m_shift);
771  m_shift = uint64_t(v) + 1;
772  }
773  template <typename Stream, typename I> void Unser(Stream &s, I &v) {
774  uint64_t n = ReadCompactSize(s);
775  m_shift += n;
776  if (m_shift < n || m_shift >= std::numeric_limits<uint64_t>::max() ||
777  m_shift < std::numeric_limits<I>::min() ||
778  m_shift > std::numeric_limits<I>::max()) {
779  throw std::ios_base::failure("differential value overflow");
780  }
781  v = I(m_shift++);
782  }
783 };
784 
796  template <typename Stream, typename T> void Ser(Stream &s, T v) {
797  DifferenceFormatter::Ser(s, v.index);
798  v.SerData(s);
799  }
800 
801  template <typename Stream, typename T> void Unser(Stream &s, T &v) {
802  DifferenceFormatter::Unser(s, v.index);
803  v.UnserData(s);
804  }
805 };
806 
814 template <typename Stream, typename C>
815 void Serialize(Stream &os, const std::basic_string<C> &str);
816 template <typename Stream, typename C>
817 void Unserialize(Stream &is, std::basic_string<C> &str);
818 
824 template <typename Stream, unsigned int N, typename T>
825 void Serialize_impl(Stream &os, const prevector<N, T> &v, const uint8_t &);
826 template <typename Stream, unsigned int N, typename T, typename V>
827 void Serialize_impl(Stream &os, const prevector<N, T> &v, const V &);
828 template <typename Stream, unsigned int N, typename T>
829 inline void Serialize(Stream &os, const prevector<N, T> &v);
830 template <typename Stream, unsigned int N, typename T>
831 void Unserialize_impl(Stream &is, prevector<N, T> &v, const uint8_t &);
832 template <typename Stream, unsigned int N, typename T, typename V>
833 void Unserialize_impl(Stream &is, prevector<N, T> &v, const V &);
834 template <typename Stream, unsigned int N, typename T>
835 inline void Unserialize(Stream &is, prevector<N, T> &v);
836 
842 template <typename Stream, typename T, typename A>
843 void Serialize_impl(Stream &os, const std::vector<T, A> &v, const uint8_t &);
844 template <typename Stream, typename T, typename A>
845 void Serialize_impl(Stream &os, const std::vector<T, A> &v, const bool &);
846 template <typename Stream, typename T, typename A, typename V>
847 void Serialize_impl(Stream &os, const std::vector<T, A> &v, const V &);
848 template <typename Stream, typename T, typename A>
849 inline void Serialize(Stream &os, const std::vector<T, A> &v);
850 template <typename Stream, typename T, typename A>
851 void Unserialize_impl(Stream &is, std::vector<T, A> &v, const uint8_t &);
852 template <typename Stream, typename T, typename A, typename V>
853 void Unserialize_impl(Stream &is, std::vector<T, A> &v, const V &);
854 template <typename Stream, typename T, typename A>
855 inline void Unserialize(Stream &is, std::vector<T, A> &v);
856 
860 template <typename Stream, typename K, typename T>
861 void Serialize(Stream &os, const std::pair<K, T> &item);
862 template <typename Stream, typename K, typename T>
863 void Unserialize(Stream &is, std::pair<K, T> &item);
864 
868 template <typename Stream, typename K, typename T, typename Pred, typename A>
869 void Serialize(Stream &os, const std::map<K, T, Pred, A> &m);
870 template <typename Stream, typename K, typename T, typename Pred, typename A>
871 void Unserialize(Stream &is, std::map<K, T, Pred, A> &m);
872 
876 template <typename Stream, typename K, typename Pred, typename A>
877 void Serialize(Stream &os, const std::set<K, Pred, A> &m);
878 template <typename Stream, typename K, typename Pred, typename A>
879 void Unserialize(Stream &is, std::set<K, Pred, A> &m);
880 
884 template <typename Stream, typename T>
885 void Serialize(Stream &os, const std::shared_ptr<const T> &p);
886 template <typename Stream, typename T>
887 void Unserialize(Stream &os, std::shared_ptr<const T> &p);
888 
892 template <typename Stream, typename T>
893 void Serialize(Stream &os, const std::unique_ptr<const T> &p);
894 template <typename Stream, typename T>
895 void Unserialize(Stream &os, std::unique_ptr<const T> &p);
896 
900 template <typename Stream, typename T>
901 void Serialize(Stream &os, const RCUPtr<const T> &p);
902 template <typename Stream, typename T>
903 void Unserialize(Stream &os, RCUPtr<const T> &p);
904 
909 template <typename Stream, typename T>
910 inline void Serialize(Stream &os, const T &a) {
911  a.Serialize(os);
912 }
913 
914 template <typename Stream, typename T>
915 inline void Unserialize(Stream &is, T &&a) {
916  a.Unserialize(is);
917 }
918 
926  template <typename Stream, typename T>
927  static void Ser(Stream &s, const T &t) {
928  Serialize(s, t);
929  }
930 
931  template <typename Stream, typename T> static void Unser(Stream &s, T &t) {
932  Unserialize(s, t);
933  }
934 };
935 
939 template <typename Stream, typename C>
940 void Serialize(Stream &os, const std::basic_string<C> &str) {
941  WriteCompactSize(os, str.size());
942  if (!str.empty()) {
943  os.write((char *)str.data(), str.size() * sizeof(C));
944  }
945 }
946 
947 template <typename Stream, typename C>
948 void Unserialize(Stream &is, std::basic_string<C> &str) {
949  size_t nSize = ReadCompactSize(is);
950  str.resize(nSize);
951  if (nSize != 0) {
952  is.read((char *)str.data(), nSize * sizeof(C));
953  }
954 }
955 
959 template <typename Stream, unsigned int N, typename T>
960 void Serialize_impl(Stream &os, const prevector<N, T> &v, const uint8_t &) {
961  WriteCompactSize(os, v.size());
962  if (!v.empty()) {
963  os.write((char *)v.data(), v.size() * sizeof(T));
964  }
965 }
966 
967 template <typename Stream, unsigned int N, typename T, typename V>
968 void Serialize_impl(Stream &os, const prevector<N, T> &v, const V &) {
970 }
971 
972 template <typename Stream, unsigned int N, typename T>
973 inline void Serialize(Stream &os, const prevector<N, T> &v) {
974  Serialize_impl(os, v, T());
975 }
976 
977 template <typename Stream, unsigned int N, typename T>
978 void Unserialize_impl(Stream &is, prevector<N, T> &v, const uint8_t &) {
979  // Limit size per read so bogus size value won't cause out of memory
980  v.clear();
981  size_t nSize = ReadCompactSize(is);
982  size_t i = 0;
983  while (i < nSize) {
984  size_t blk = std::min(nSize - i, size_t(1 + 4999999 / sizeof(T)));
985  v.resize_uninitialized(i + blk);
986  is.read((char *)&v[i], blk * sizeof(T));
987  i += blk;
988  }
989 }
990 
991 template <typename Stream, unsigned int N, typename T, typename V>
992 void Unserialize_impl(Stream &is, prevector<N, T> &v, const V &) {
994 }
995 
996 template <typename Stream, unsigned int N, typename T>
997 inline void Unserialize(Stream &is, prevector<N, T> &v) {
998  Unserialize_impl(is, v, T());
999 }
1000 
1004 template <typename Stream, typename T, typename A>
1005 void Serialize_impl(Stream &os, const std::vector<T, A> &v, const uint8_t &) {
1006  WriteCompactSize(os, v.size());
1007  if (!v.empty()) {
1008  os.write((char *)v.data(), v.size() * sizeof(T));
1009  }
1010 }
1011 
1012 template <typename Stream, typename T, typename A>
1013 void Serialize_impl(Stream &os, const std::vector<T, A> &v, const bool &) {
1014  // A special case for std::vector<bool>, as dereferencing
1015  // std::vector<bool>::const_iterator does not result in a const bool&
1016  // due to std::vector's special casing for bool arguments.
1017  WriteCompactSize(os, v.size());
1018  for (bool elem : v) {
1019  ::Serialize(os, elem);
1020  }
1021 }
1022 
1023 template <typename Stream, typename T, typename A, typename V>
1024 void Serialize_impl(Stream &os, const std::vector<T, A> &v, const V &) {
1026 }
1027 
1028 template <typename Stream, typename T, typename A>
1029 inline void Serialize(Stream &os, const std::vector<T, A> &v) {
1030  Serialize_impl(os, v, T());
1031 }
1032 
1033 template <typename Stream, typename T, typename A>
1034 void Unserialize_impl(Stream &is, std::vector<T, A> &v, const uint8_t &) {
1035  // Limit size per read so bogus size value won't cause out of memory
1036  v.clear();
1037  size_t nSize = ReadCompactSize(is);
1038  size_t i = 0;
1039  while (i < nSize) {
1040  size_t blk = std::min(nSize - i, size_t(1 + 4999999 / sizeof(T)));
1041  v.resize(i + blk);
1042  is.read((char *)&v[i], blk * sizeof(T));
1043  i += blk;
1044  }
1045 }
1046 
1047 template <typename Stream, typename T, typename A, typename V>
1048 void Unserialize_impl(Stream &is, std::vector<T, A> &v, const V &) {
1050 }
1051 
1052 template <typename Stream, typename T, typename A>
1053 inline void Unserialize(Stream &is, std::vector<T, A> &v) {
1054  Unserialize_impl(is, v, T());
1055 }
1056 
1060 template <typename Stream, typename K, typename T>
1061 void Serialize(Stream &os, const std::pair<K, T> &item) {
1062  Serialize(os, item.first);
1063  Serialize(os, item.second);
1064 }
1065 
1066 template <typename Stream, typename K, typename T>
1067 void Unserialize(Stream &is, std::pair<K, T> &item) {
1068  Unserialize(is, item.first);
1069  Unserialize(is, item.second);
1070 }
1071 
1075 template <typename Stream, typename K, typename T, typename Pred, typename A>
1076 void Serialize(Stream &os, const std::map<K, T, Pred, A> &m) {
1077  WriteCompactSize(os, m.size());
1078  for (const auto &entry : m) {
1079  Serialize(os, entry);
1080  }
1081 }
1082 
1083 template <typename Stream, typename K, typename T, typename Pred, typename A>
1084 void Unserialize(Stream &is, std::map<K, T, Pred, A> &m) {
1085  m.clear();
1086  size_t nSize = ReadCompactSize(is);
1087  typename std::map<K, T, Pred, A>::iterator mi = m.begin();
1088  for (size_t i = 0; i < nSize; i++) {
1089  std::pair<K, T> item;
1090  Unserialize(is, item);
1091  mi = m.insert(mi, item);
1092  }
1093 }
1094 
1098 template <typename Stream, typename K, typename Pred, typename A>
1099 void Serialize(Stream &os, const std::set<K, Pred, A> &m) {
1100  WriteCompactSize(os, m.size());
1101  for (const K &i : m) {
1102  Serialize(os, i);
1103  }
1104 }
1105 
1106 template <typename Stream, typename K, typename Pred, typename A>
1107 void Unserialize(Stream &is, std::set<K, Pred, A> &m) {
1108  m.clear();
1109  size_t nSize = ReadCompactSize(is);
1110  typename std::set<K, Pred, A>::iterator it = m.begin();
1111  for (size_t i = 0; i < nSize; i++) {
1112  K key;
1113  Unserialize(is, key);
1114  it = m.insert(it, key);
1115  }
1116 }
1117 
1121 template <typename Stream, typename T>
1122 void Serialize(Stream &os, const std::unique_ptr<const T> &p) {
1123  Serialize(os, *p);
1124 }
1125 
1126 template <typename Stream, typename T>
1127 void Unserialize(Stream &is, std::unique_ptr<const T> &p) {
1128  p.reset(new T(deserialize, is));
1129 }
1130 
1134 template <typename Stream, typename T>
1135 void Serialize(Stream &os, const std::shared_ptr<const T> &p) {
1136  Serialize(os, *p);
1137 }
1138 
1139 template <typename Stream, typename T>
1140 void Unserialize(Stream &is, std::shared_ptr<const T> &p) {
1141  p = std::make_shared<const T>(deserialize, is);
1142 }
1143 
1147 template <typename Stream, typename T>
1148 void Serialize(Stream &os, const RCUPtr<const T> &p) {
1149  Serialize(os, *p);
1150 }
1151 
1152 template <typename Stream, typename T>
1153 void Unserialize(Stream &is, RCUPtr<const T> &p) {
1155 }
1156 
1161  constexpr bool ForRead() const { return false; }
1162 };
1164  constexpr bool ForRead() const { return true; }
1165 };
1166 
1180 protected:
1181  size_t nSize;
1182 
1183  const int nVersion;
1184 
1185 public:
1186  explicit CSizeComputer(int nVersionIn) : nSize(0), nVersion(nVersionIn) {}
1187 
1188  void write(const char *psz, size_t _nSize) { this->nSize += _nSize; }
1189 
1191  void seek(size_t _nSize) { this->nSize += _nSize; }
1192 
1193  template <typename T> CSizeComputer &operator<<(const T &obj) {
1194  ::Serialize(*this, obj);
1195  return (*this);
1196  }
1197 
1198  size_t size() const { return nSize; }
1199 
1200  int GetVersion() const { return nVersion; }
1201 };
1202 
1203 template <typename Stream> void SerializeMany(Stream &s) {}
1204 
1205 template <typename Stream, typename Arg, typename... Args>
1206 void SerializeMany(Stream &s, const Arg &arg, const Args &...args) {
1207  ::Serialize(s, arg);
1208  ::SerializeMany(s, args...);
1209 }
1210 
1211 template <typename Stream> inline void UnserializeMany(Stream &s) {}
1212 
1213 template <typename Stream, typename Arg, typename... Args>
1214 inline void UnserializeMany(Stream &s, Arg &&arg, Args &&...args) {
1215  ::Unserialize(s, arg);
1216  ::UnserializeMany(s, args...);
1217 }
1218 
1219 template <typename Stream, typename... Args>
1220 inline void SerReadWriteMany(Stream &s, CSerActionSerialize ser_action,
1221  const Args &...args) {
1222  ::SerializeMany(s, args...);
1223 }
1224 
1225 template <typename Stream, typename... Args>
1226 inline void SerReadWriteMany(Stream &s, CSerActionUnserialize ser_action,
1227  Args &&...args) {
1228  ::UnserializeMany(s, args...);
1229 }
1230 
1231 template <typename Stream, typename Type, typename Fn>
1232 inline void SerRead(Stream &s, CSerActionSerialize ser_action, Type &&, Fn &&) {
1233 }
1234 
1235 template <typename Stream, typename Type, typename Fn>
1236 inline void SerRead(Stream &s, CSerActionUnserialize ser_action, Type &&obj,
1237  Fn &&fn) {
1238  fn(s, std::forward<Type>(obj));
1239 }
1240 
1241 template <typename Stream, typename Type, typename Fn>
1242 inline void SerWrite(Stream &s, CSerActionSerialize ser_action, Type &&obj,
1243  Fn &&fn) {
1244  fn(s, std::forward<Type>(obj));
1245 }
1246 
1247 template <typename Stream, typename Type, typename Fn>
1248 inline void SerWrite(Stream &s, CSerActionUnserialize ser_action, Type &&,
1249  Fn &&) {}
1250 
1251 template <typename I> inline void WriteVarInt(CSizeComputer &s, I n) {
1252  s.seek(GetSizeOfVarInt<I>(n));
1253 }
1254 
1255 inline void WriteCompactSize(CSizeComputer &s, uint64_t nSize) {
1256  s.seek(GetSizeOfCompactSize(nSize));
1257 }
1258 
1259 template <typename T> size_t GetSerializeSize(const T &t, int nVersion = 0) {
1260  return (CSizeComputer(nVersion) << t).size();
1261 }
1262 
1263 template <typename... T>
1264 size_t GetSerializeSizeMany(int nVersion, const T &...t) {
1265  CSizeComputer sc(nVersion);
1266  SerializeMany(sc, t...);
1267  return sc.size();
1268 }
1269 
1270 #endif // BITCOIN_SERIALIZE_H
GetSerializeSize implementations
Definition: serialize.h:1179
CSizeComputer & operator<<(const T &obj)
Definition: serialize.h:1193
void write(const char *psz, size_t _nSize)
Definition: serialize.h:1188
CSizeComputer(int nVersionIn)
Definition: serialize.h:1186
size_t nSize
Definition: serialize.h:1181
size_t size() const
Definition: serialize.h:1198
const int nVersion
Definition: serialize.h:1183
void seek(size_t _nSize)
Pretend _nSize bytes are written, without specifying them.
Definition: serialize.h:1191
int GetVersion() const
Definition: serialize.h:1200
Helper for differentially encoded Compact Size integers in lists.
Definition: serialize.h:762
void Unser(Stream &s, I &v)
Definition: serialize.h:773
void Ser(Stream &s, I v)
Definition: serialize.h:766
Definition: rcu.h:85
static RCUPtr make(Args &&...args)
Construct a new object that is owned by the pointer.
Definition: rcu.h:112
A Span is an object that can refer to a contiguous sequence of objects.
Definition: span.h:93
constexpr std::size_t size() const noexcept
Definition: span.h:209
constexpr C * data() const noexcept
Definition: span.h:198
Simple wrapper class to serialize objects using a formatter; used by Using().
Definition: serialize.h:561
Wrapper(T obj)
Definition: serialize.h:569
T m_object
Definition: serialize.h:563
void Serialize(Stream &s) const
Definition: serialize.h:570
void Unserialize(Stream &s)
Definition: serialize.h:573
Implements a drop-in replacement for std::vector<T> which stores up to N elements directly (without h...
Definition: prevector.h:38
bool empty() const
Definition: prevector.h:388
void clear()
Definition: prevector.h:441
size_type size() const
Definition: prevector.h:386
value_type * data()
Definition: prevector.h:610
void resize_uninitialized(size_type new_size)
Definition: prevector.h:482
uint16_t be16toh(uint16_t big_endian_16bits)
Definition: endian.h:156
uint16_t htobe16(uint16_t host_16bits)
Definition: endian.h:144
uint32_t le32toh(uint32_t little_endian_32bits)
Definition: endian.h:186
uint32_t htobe32(uint32_t host_32bits)
Definition: endian.h:168
uint16_t le16toh(uint16_t little_endian_16bits)
Definition: endian.h:162
uint64_t htobe64(uint64_t host_64bits)
Definition: endian.h:192
uint64_t be64toh(uint64_t big_endian_64bits)
Definition: endian.h:204
uint32_t be32toh(uint32_t big_endian_32bits)
Definition: endian.h:180
uint64_t htole64(uint64_t host_64bits)
Definition: endian.h:198
uint32_t htole32(uint32_t host_32bits)
Definition: endian.h:174
uint16_t htole16(uint16_t host_16bits)
Definition: endian.h:150
uint64_t le64toh(uint64_t little_endian_64bits)
Definition: endian.h:210
void SerializeMany(Stream &s)
Definition: serialize.h:1203
static const unsigned int MAX_VECTOR_ALLOCATE
Maximum amount of memory (in bytes) to allocate at once when deserializing vectors.
Definition: serialize.h:37
uint8_t ser_readdata8(Stream &s)
Definition: serialize.h:98
float ser_uint32_to_float(uint32_t y)
Definition: serialize.h:149
I ReadVarInt(Stream &is)
Definition: serialize.h:538
void ser_writedata32be(Stream &s, uint32_t obj)
Definition: serialize.h:89
void WriteVarInt(CSizeComputer &os, I n)
Definition: serialize.h:1251
VarIntMode
Variable-length integers: bytes are a MSB base-128 encoding of the number.
Definition: serialize.h:492
@ NONNEGATIVE_SIGNED
void ser_writedata32(Stream &s, uint32_t obj)
Definition: serialize.h:84
size_t GetSerializeSizeMany(int nVersion, const T &...t)
Definition: serialize.h:1264
uint32_t 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:391
static constexpr uint64_t MAX_SIZE
The maximum size of a serialized object in bytes or number of elements (for eg vectors) when the size...
Definition: serialize.h:31
constexpr deserialize_type deserialize
Definition: serialize.h:50
void Serialize(Stream &s, char a)
Definition: serialize.h:242
void ser_writedata16(Stream &s, uint16_t obj)
Definition: serialize.h:74
uint32_t ser_float_to_uint32(float x)
Definition: serialize.h:135
static Wrapper< Formatter, T & > Using(T &&t)
Cause serialization/deserialization of an object to be done using a specified formatter class.
Definition: serialize.h:592
X & ReadWriteAsHelper(X &x)
Convert the reference base type to X, without changing constness or reference type.
Definition: serialize.h:173
@ SER_DISK
Definition: serialize.h:167
@ SER_NETWORK
Definition: serialize.h:166
@ SER_GETHASH
Definition: serialize.h:168
void Unserialize_impl(Stream &is, prevector< N, T > &v, const uint8_t &)
Definition: serialize.h:978
void Unserialize(Stream &s, char &a)
Definition: serialize.h:294
void SerReadWriteMany(Stream &s, CSerActionSerialize ser_action, const Args &...args)
Definition: serialize.h:1220
void SerWrite(Stream &s, CSerActionSerialize ser_action, Type &&obj, Fn &&fn)
Definition: serialize.h:1242
char * CharCast(char *c)
Safely convert odd char pointer types to standard ones.
Definition: serialize.h:53
void ser_writedata16be(Stream &s, uint16_t obj)
Definition: serialize.h:79
uint16_t ser_readdata16(Stream &s)
Definition: serialize.h:103
uint64_t ser_readdata64(Stream &s)
Definition: serialize.h:123
double ser_uint64_to_double(uint64_t y)
Definition: serialize.h:142
void ser_writedata8(Stream &s, uint8_t obj)
Lowest-level serialization and conversion.
Definition: serialize.h:70
uint64_t ReadCompactSize(Stream &is, bool range_check=true)
Decode a CompactSize-encoded variable-length integer.
Definition: serialize.h:431
unsigned int GetSizeOfVarInt(I n)
Definition: serialize.h:505
uint32_t ser_readdata32(Stream &s)
Definition: serialize.h:113
uint16_t ser_readdata16be(Stream &s)
Definition: serialize.h:108
void SerRead(Stream &s, CSerActionSerialize ser_action, Type &&, Fn &&)
Definition: serialize.h:1232
void Serialize_impl(Stream &os, const prevector< N, T > &v, const uint8_t &)
prevector prevectors of uint8_t are a special case and are intended to be serialized as a single opaq...
Definition: serialize.h:960
size_t GetSerializeSize(const T &t, int nVersion=0)
Definition: serialize.h:1259
void UnserializeMany(Stream &s)
Definition: serialize.h:1211
uint64_t ser_double_to_uint64(double x)
Definition: serialize.h:128
void ser_writedata64(Stream &s, uint64_t obj)
Definition: serialize.h:94
uint32_t ser_readdata32be(Stream &s)
Definition: serialize.h:118
void WriteCompactSize(CSizeComputer &os, uint64_t nSize)
Definition: serialize.h:1255
Support for SERIALIZE_METHODS and READWRITE macro.
Definition: serialize.h:1160
constexpr bool ForRead() const
Definition: serialize.h:1161
constexpr bool ForRead() const
Definition: serialize.h:1164
constexpr CheckVarIntMode()
Definition: serialize.h:495
Formatter for integers in CompactSize format.
Definition: serialize.h:665
void Unser(Stream &s, I &v)
Definition: serialize.h:666
void Ser(Stream &s, I v)
Definition: serialize.h:675
Serialization wrapper class for custom integers and enums.
Definition: serialize.h:624
static constexpr uint64_t MAX
Definition: serialize.h:627
void Ser(Stream &s, I v)
Definition: serialize.h:629
void Unser(Stream &s, I &v)
Definition: serialize.h:643
Default formatter.
Definition: serialize.h:925
static void Ser(Stream &s, const T &t)
Definition: serialize.h:927
static void Unser(Stream &s, T &t)
Definition: serialize.h:931
Helper for a list of items containing a differentially encoded index as their first member.
Definition: serialize.h:795
void Unser(Stream &s, T &v)
Definition: serialize.h:801
void Ser(Stream &s, T v)
Definition: serialize.h:796
void Unser(Stream &s, std::string &v)
Definition: serialize.h:687
void Ser(Stream &s, const std::string &v)
Definition: serialize.h:698
Serialization wrapper class for integers in VarInt format.
Definition: serialize.h:604
void Ser(Stream &s, I v)
Definition: serialize.h:605
void Unser(Stream &s, I &v)
Definition: serialize.h:609
Formatter to serialize/deserialize vector elements using another formatter.
Definition: serialize.h:719
void Unser(Stream &s, V &v)
Definition: serialize.h:728
void Ser(Stream &s, const V &v)
Definition: serialize.h:720
Dummy data type to identify deserializing constructors.
Definition: serialize.h:49