PIVX Core  5.6.99
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-2021 The PIVX Core developers
4 // Distributed under the MIT software license, see the accompanying
5 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
6 
7 #ifndef PIVX_SERIALIZE_H
8 #define PIVX_SERIALIZE_H
9 
10 #include <algorithm>
11 #include <array>
12 #include <assert.h>
13 #include <cstring>
14 #include <cstdint>
15 #include <ios>
16 #include <limits>
17 #include <list>
18 #include <map>
19 #include <memory>
20 #include <set>
21 #include <string.h>
22 #include <string>
23 #include <utility>
24 #include <vector>
25 
26 #include "compat/endian.h"
28 #include "libzerocoin/SpendType.h"
29 #include "optional.h"
30 #include "prevector.h"
31 #include "span.h"
32 #include "sporkid.h"
33 
34 class CScript;
35 
40 static constexpr uint64_t MAX_SIZE = 0x02000000;
41 
43 static const unsigned int MAX_VECTOR_ALLOCATE = 5000000;
44 
56 struct deserialize_type {};
58 
64 template <typename T>
65 inline T& REF(const T& val)
66 {
67  return const_cast<T&>(val);
68 }
69 
71 inline char* CharCast(char* c) { return c; }
72 inline char* CharCast(unsigned char* c) { return (char*)c; }
73 inline const char* CharCast(const char* c) { return c; }
74 inline const char* CharCast(const unsigned char* c) { return (const char*)c; }
75 
76 /*
77  * Lowest-level serialization and conversion.
78  * @note Sizes of these types are verified in the tests
79  */
80 template<typename Stream> inline void ser_writedata8(Stream &s, uint8_t obj)
81 {
82  s.write((char*)&obj, 1);
83 }
84 template<typename Stream> inline void ser_writedata16(Stream &s, uint16_t obj)
85 {
86  obj = htole16(obj);
87  s.write((char*)&obj, 2);
88 }
89 template<typename Stream> inline void ser_writedata16be(Stream &s, uint16_t obj)
90 {
91  obj = htobe16(obj);
92  s.write((char*)&obj, 2);
93 }
94 template<typename Stream> inline void ser_writedata32(Stream &s, uint32_t obj)
95 {
96  obj = htole32(obj);
97  s.write((char*)&obj, 4);
98 }
99 template<typename Stream> inline void ser_writedata64(Stream &s, uint64_t obj)
100 {
101  obj = htole64(obj);
102  s.write((char*)&obj, 8);
103 }
104 template<typename Stream> inline uint8_t ser_readdata8(Stream &s)
105 {
106  uint8_t obj;
107  s.read((char*)&obj, 1);
108  return obj;
109 }
110 template<typename Stream> inline uint16_t ser_readdata16(Stream &s)
111 {
112  uint16_t obj;
113  s.read((char*)&obj, 2);
114  return le16toh(obj);
115 }
116 template<typename Stream> inline uint16_t ser_readdata16be(Stream &s)
117 {
118  uint16_t obj;
119  s.read((char*)&obj, 2);
120  return be16toh(obj);
121 }
122 template<typename Stream> inline uint32_t ser_readdata32(Stream &s)
123 {
124  uint32_t obj;
125  s.read((char*)&obj, 4);
126  return le32toh(obj);
127 }
128 template<typename Stream> inline uint64_t ser_readdata64(Stream &s)
129 {
130  uint64_t obj;
131  s.read((char*)&obj, 8);
132  return le64toh(obj);
133 }
134 inline uint64_t ser_double_to_uint64(double x)
135 {
136  uint64_t tmp;
137  std::memcpy(&tmp, &x, sizeof(x));
138  static_assert(sizeof(tmp) == sizeof(x), "double and uint64_t assumed to have the same size");
139  return tmp;
140 }
141 inline uint32_t ser_float_to_uint32(float x)
142 {
143  uint32_t tmp;
144  std::memcpy(&tmp, &x, sizeof(x));
145  static_assert(sizeof(tmp) == sizeof(x), "float and uint32_t assumed to have the same size");
146  return tmp;
147 }
148 inline double ser_uint64_to_double(uint64_t y)
149 {
150  double tmp;
151  std::memcpy(&tmp, &y, sizeof(y));
152  static_assert(sizeof(tmp) == sizeof(y), "double and uint64_t assumed to have the same size");
153  return tmp;
154 }
155 inline float ser_uint32_to_float(uint32_t y)
156 {
157  float tmp;
158  std::memcpy(&tmp, &y, sizeof(y));
159  static_assert(sizeof(tmp) == sizeof(y), "float and uint32_t assumed to have the same size");
160  return tmp;
161 }
162 
163 
165 //
166 // Templates for serializing to anything that looks like a stream,
167 // i.e. anything that supports .read(char*, size_t) and .write(char*, size_t)
168 //
169 
170 class CSizeComputer;
171 
172 enum {
173  // primary actions
174  SER_NETWORK = (1 << 0),
175  SER_DISK = (1 << 1),
176  SER_GETHASH = (1 << 2),
177 };
178 
180 template<typename X> X& ReadWriteAsHelper(X& x) { return x; }
181 template<typename X> const X& ReadWriteAsHelper(const X& x) { return x; }
182 
183 #define READWRITE(...) (::SerReadWriteMany(s, ser_action, __VA_ARGS__))
184 #define READWRITEAS(type, obj) (::SerReadWriteMany(s, ser_action, ReadWriteAsHelper<type>(obj)))
185 #define SER_READ(obj, code) ::SerRead(s, ser_action, obj, [&](Stream& s, typename std::remove_const<Type>::type& obj) { code; })
186 #define SER_WRITE(obj, code) ::SerWrite(s, ser_action, obj, [&](Stream& s, const Type& obj) { code; })
187 
204 #define FORMATTER_METHODS(cls, obj) \
205  template<typename Stream> \
206  static void Ser(Stream& s, const cls& obj) { SerializationOps(obj, s, CSerActionSerialize()); } \
207  template<typename Stream> \
208  static void Unser(Stream& s, cls& obj) { SerializationOps(obj, s, CSerActionUnserialize()); } \
209  template<typename Stream, typename Type, typename Operation> \
210  static inline void SerializationOps(Type& obj, Stream& s, Operation ser_action) \
211 
219 #define SERIALIZE_METHODS(cls, obj) \
220  template<typename Stream> \
221  void Serialize(Stream& s) const \
222  { \
223  static_assert(std::is_same<const cls&, decltype(*this)>::value, "Serialize type mismatch"); \
224  Ser(s, *this); \
225  } \
226  template<typename Stream> \
227  void Unserialize(Stream& s) \
228  { \
229  static_assert(std::is_same<cls&, decltype(*this)>::value, "Unserialize type mismatch"); \
230  Unser(s, *this); \
231  } \
232  FORMATTER_METHODS(cls, obj)
233 
234 /*
235  * Basic Types
236  */
237 template<typename Stream> inline void Serialize(Stream& s, char a ) { ser_writedata8(s, a); } // TODO Get rid of bare char
238 template<typename Stream> inline void Serialize(Stream& s, int8_t a ) { ser_writedata8(s, a); }
239 template<typename Stream> inline void Serialize(Stream& s, uint8_t a ) { ser_writedata8(s, a); }
240 template<typename Stream> inline void Serialize(Stream& s, int16_t a ) { ser_writedata16(s, a); }
241 template<typename Stream> inline void Serialize(Stream& s, uint16_t a) { ser_writedata16(s, a); }
242 template<typename Stream> inline void Serialize(Stream& s, int32_t a ) { ser_writedata32(s, a); }
243 template<typename Stream> inline void Serialize(Stream& s, uint32_t a) { ser_writedata32(s, a); }
244 template<typename Stream> inline void Serialize(Stream& s, int64_t a ) { ser_writedata64(s, a); }
245 template<typename Stream> inline void Serialize(Stream& s, uint64_t a) { ser_writedata64(s, a); }
246 template<typename Stream> inline void Serialize(Stream& s, float a ) { ser_writedata32(s, ser_float_to_uint32(a)); }
247 template<typename Stream> inline void Serialize(Stream& s, double a ) { ser_writedata64(s, ser_double_to_uint64(a)); }
248 template<typename Stream, int N> inline void Serialize(Stream& s, const char (&a)[N]) { s.write(a, N); }
249 template<typename Stream, int N> inline void Serialize(Stream& s, const unsigned char (&a)[N]) { s.write(CharCast(a), N); }
250 template<typename Stream> inline void Serialize(Stream& s, const Span<const unsigned char>& span) { s.write(CharCast(span.data()), span.size()); }
251 template<typename Stream> inline void Serialize(Stream& s, const Span<unsigned char>& span) { s.write(CharCast(span.data()), span.size()); }
252 
253 template<typename Stream> inline void Unserialize(Stream& s, char& a ) { a = ser_readdata8(s); } // TODO Get rid of bare char
254 template<typename Stream> inline void Unserialize(Stream& s, int8_t& a ) { a = ser_readdata8(s); }
255 template<typename Stream> inline void Unserialize(Stream& s, uint8_t& a ) { a = ser_readdata8(s); }
256 template<typename Stream> inline void Unserialize(Stream& s, int16_t& a ) { a = ser_readdata16(s); }
257 template<typename Stream> inline void Unserialize(Stream& s, uint16_t& a) { a = ser_readdata16(s); }
258 template<typename Stream> inline void Unserialize(Stream& s, int32_t& a ) { a = ser_readdata32(s); }
259 template<typename Stream> inline void Unserialize(Stream& s, uint32_t& a) { a = ser_readdata32(s); }
260 template<typename Stream> inline void Unserialize(Stream& s, int64_t& a ) { a = ser_readdata64(s); }
261 template<typename Stream> inline void Unserialize(Stream& s, uint64_t& a) { a = ser_readdata64(s); }
262 template<typename Stream> inline void Unserialize(Stream& s, float& a ) { a = ser_uint32_to_float(ser_readdata32(s)); }
263 template<typename Stream> inline void Unserialize(Stream& s, double& a ) { a = ser_uint64_to_double(ser_readdata64(s)); }
264 template<typename Stream, int N> inline void Unserialize(Stream& s, char (&a)[N]) { s.read(a, N); }
265 template<typename Stream, int N> inline void Unserialize(Stream& s, unsigned char (&a)[N]) { s.read(CharCast(a), N); }
266 template<typename Stream> inline void Unserialize(Stream& s, Span<unsigned char>& span) { s.read(CharCast(span.data()), span.size()); }
267 
268 template<typename Stream> inline void Serialize(Stream& s, bool a) { char f=a; ser_writedata8(s, f); }
269 template<typename Stream> inline void Unserialize(Stream& s, bool& a) { char f=ser_readdata8(s); a=f; }
270 
271 // Serializatin for libzerocoin::CoinDenomination
272 template <typename Stream>
273 inline void Serialize(Stream& s, libzerocoin::CoinDenomination a)
274 {
276  ser_writedata32(s, f);
277 }
278 
279 template <typename Stream>
280 inline void Unserialize(Stream& s, libzerocoin::CoinDenomination& a)
281 {
282  int f = ser_readdata32(s);
284 }
285 
286 // Serialization for libzerocoin::SpendType
287 template <typename Stream>
288 inline void Serialize(Stream& s, libzerocoin::SpendType a)
289 {
290  uint8_t f = static_cast<uint8_t>(a);
291  ser_writedata8(s, f);
292 }
293 
294 template <typename Stream>
295 inline void Unserialize(Stream& s, libzerocoin::SpendType & a)
296 {
297  uint8_t f = ser_readdata8(s);
298  a = static_cast<libzerocoin::SpendType>(f);
299 }
300 
301 // Serialization for SporkId
302 template <typename Stream>
303 inline void Serialize(Stream& s, SporkId sporkID)
304 {
305  int32_t f = static_cast<int32_t>(sporkID);
306  ser_writedata32(s, f);
307 }
308 
309 template <typename Stream>
310 inline void Unserialize(Stream& s, SporkId& sporkID)
311 {
312  int32_t f = ser_readdata32(s);
313  sporkID = (SporkId) f;
314 }
315 
316 
324 inline unsigned int GetSizeOfCompactSize(uint64_t nSize)
325 {
326  if (nSize < 253) return sizeof(unsigned char);
327  else if (nSize <= std::numeric_limits<uint16_t>::max()) return sizeof(unsigned char) + sizeof(uint16_t);
328  else if (nSize <= std::numeric_limits<unsigned int>::max()) return sizeof(unsigned char) + sizeof(unsigned int);
329  else return sizeof(unsigned char) + sizeof(uint64_t);
330 }
331 
332 inline void WriteCompactSize(CSizeComputer& os, uint64_t nSize);
333 
334 template <typename Stream>
335 void WriteCompactSize(Stream& os, uint64_t nSize)
336 {
337  if (nSize < 253) {
338  ser_writedata8(os, nSize);
339  } else if (nSize <= std::numeric_limits<uint16_t>::max()) {
340  ser_writedata8(os, 253);
341  ser_writedata16(os, nSize);
342  } else if (nSize <= std::numeric_limits<unsigned int>::max()) {
343  ser_writedata8(os, 254);
344  ser_writedata32(os, nSize);
345  } else {
346  ser_writedata8(os, 255);
347  ser_writedata64(os, nSize);
348  }
349  return;
350 }
351 
358 template<typename Stream>
359 uint64_t ReadCompactSize(Stream& is, bool range_check = true)
360 {
361  uint8_t chSize = ser_readdata8(is);
362  uint64_t nSizeRet = 0;
363  if (chSize < 253) {
364  nSizeRet = chSize;
365  } else if (chSize == 253) {
366  nSizeRet = ser_readdata16(is);
367  if (nSizeRet < 253)
368  throw std::ios_base::failure("non-canonical ReadCompactSize()");
369  } else if (chSize == 254) {
370  nSizeRet = ser_readdata32(is);
371  if (nSizeRet < 0x10000u)
372  throw std::ios_base::failure("non-canonical ReadCompactSize()");
373  } else {
374  nSizeRet = ser_readdata64(is);
375  if (nSizeRet < 0x100000000ULL)
376  throw std::ios_base::failure("non-canonical ReadCompactSize()");
377  }
378  if (range_check && nSizeRet > MAX_SIZE) {
379  throw std::ios_base::failure("ReadCompactSize(): size too large");
380  }
381  return nSizeRet;
382 }
383 
419 
420 template <VarIntMode Mode, typename I>
422  constexpr CheckVarIntMode()
423  {
424  static_assert(Mode != VarIntMode::DEFAULT || std::is_unsigned<I>::value, "Unsigned type required with mode DEFAULT.");
425  static_assert(Mode != VarIntMode::NONNEGATIVE_SIGNED || std::is_signed<I>::value, "Signed type required with mode NONNEGATIVE_SIGNED.");
426  }
427 };
428 
429 template<VarIntMode Mode, typename I>
430 inline unsigned int GetSizeOfVarInt(I n)
431 {
433  int nRet = 0;
434  while (true) {
435  nRet++;
436  if (n <= 0x7F)
437  break;
438  n = (n >> 7) - 1;
439  }
440  return nRet;
441 }
442 
443 template<typename I>
444 inline void WriteVarInt(CSizeComputer& os, I n);
445 
446 template<typename Stream, VarIntMode Mode, typename I>
447 void WriteVarInt(Stream& os, I n)
448 {
450  unsigned char tmp[(sizeof(n)*8+6)/7];
451  int len=0;
452  while(true) {
453  tmp[len] = (n & 0x7F) | (len ? 0x80 : 0x00);
454  if (n <= 0x7F)
455  break;
456  n = (n >> 7) - 1;
457  len++;
458  }
459  do {
460  ser_writedata8(os, tmp[len]);
461  } while (len--);
462 }
463 
464 template<typename Stream, VarIntMode Mode, typename I>
465 I ReadVarInt(Stream& is)
466 {
468  I n = 0;
469  while (true) {
470  unsigned char chData = ser_readdata8(is);
471  if (n > (std::numeric_limits<I>::max() >> 7)) {
472  throw std::ios_base::failure("ReadVarInt(): size too large");
473  }
474  n = (n << 7) | (chData & 0x7F);
475  if (chData & 0x80) {
476  if (n == std::numeric_limits<I>::max()) {
477  throw std::ios_base::failure("ReadVarInt(): size too large");
478  }
479  n++;
480  } else {
481  return n;
482  }
483  }
484 }
485 
487 template<typename Formatter, typename T>
488 class Wrapper
489 {
490  static_assert(std::is_lvalue_reference<T>::value, "Wrapper needs an lvalue reference type T");
491 protected:
493 public:
494  explicit Wrapper(T obj) : m_object(obj) {}
495  template<typename Stream> void Serialize(Stream &s) const { Formatter().Ser(s, m_object); }
496  template<typename Stream> void Unserialize(Stream &s) { Formatter().Unser(s, m_object); }
497 };
498 
509 template<typename Formatter, typename T>
510 static inline Wrapper<Formatter, T&> Using(T&& t) { return Wrapper<Formatter, T&>(t); }
511 
512 #define VARINT_MODE(obj, mode) Using<VarIntFormatter<mode>>(obj)
513 #define VARINT(obj) Using<VarIntFormatter<VarIntMode::DEFAULT>>(obj)
514 #define COMPACTSIZE(obj) Using<CompactSizeFormatter<true>>(obj)
515 #define LIMITED_STRING(obj,n) Using<LimitedStringFormatter<n>>(obj)
516 
518 template<VarIntMode Mode>
520 {
521  template<typename Stream, typename I> void Ser(Stream &s, I v)
522  {
523  WriteVarInt<Stream,Mode,typename std::remove_cv<I>::type>(s, v);
524  }
525 
526  template<typename Stream, typename I> void Unser(Stream& s, I& v)
527  {
528  v = ReadVarInt<Stream,Mode,typename std::remove_cv<I>::type>(s);
529  }
530 };
531 
532 #define FIXEDBITSET(obj, size) Using<BitSetFormatter<size>>(obj)
533 #define DYNBITSET(obj) Using<BitSetFormatter<0>>(obj)
534 #define FIXEDVARINTSBITSET(obj, size) REF(CFixedVarIntsBitSet(REF(obj), (size)))
535 #define AUTOBITSET(obj, size) REF(CAutoBitSet(REF(obj), (size)))
536 
537 /* Formatter for fixed (size N), or dynamic (size 0) bitsets */
538 
539 template<size_t N>
541 {
542  template<typename Stream>
543  void Ser(Stream& s, const std::vector<bool>& vec)
544  {
545  size_t size = (N == 0 ? vec.size() : N);
546  if (N == 0) {
547  WriteCompactSize(s, size);
548  }
549  std::vector<unsigned char> vBytes((size + 7) / 8);
550  size_t ms = std::min(size, vec.size());
551  for (size_t p = 0; p < ms; p++)
552  vBytes[p / 8] |= vec[p] << (p % 8);
553  s.write((char*)vBytes.data(), vBytes.size());
554  }
555 
556  template<typename Stream>
557  void Unser(Stream& s, std::vector<bool>& vec)
558  {
559  size_t size = (N == 0 ? ReadCompactSize(s) : N);
560  vec.resize(size);
561  std::vector<unsigned char> vBytes((size + 7) / 8);
562  s.read((char*)vBytes.data(), vBytes.size());
563  for (size_t p = 0; p < size; p++)
564  vec[p] = (vBytes[p / 8] & (1 << (p % 8))) != 0;
565  if (vBytes.size() * 8 != size) {
566  size_t rem = vBytes.size() * 8 - size;
567  uint8_t m = ~(uint8_t)(0xff >> rem);
568  if (vBytes[vBytes.size() - 1] & m) {
569  throw std::ios_base::failure("Out-of-range bits set");
570  }
571  }
572  }
573 };
574 
581 {
582 protected:
583  std::vector<bool>& vec;
584  size_t size;
585 
586 public:
587  CFixedVarIntsBitSet(std::vector<bool>& vecIn, size_t sizeIn) : vec(vecIn), size(sizeIn) {}
588 
589  template <typename Stream>
590  void Serialize(Stream& s) const
591  {
592  int32_t last = -1;
593  for (int32_t i = 0; i < (int32_t)vec.size(); i++) {
594  if (vec[i]) {
595  WriteVarInt<Stream, VarIntMode::DEFAULT, uint32_t>(s, (uint32_t)(i - last));
596  last = i;
597  }
598  }
599  WriteVarInt<Stream, VarIntMode::DEFAULT, uint32_t>(s, 0); // stopper
600  }
601 
602  template <typename Stream>
603  void Unserialize(Stream& s)
604  {
605  vec.assign(size, false);
606 
607  int32_t last = -1;
608  while (true) {
609  uint32_t offset = ReadVarInt<Stream, VarIntMode::DEFAULT, uint32_t>(s);
610  if (offset == 0) {
611  break;
612  }
613  int32_t idx = last + offset;
614  if (idx >= size) {
615  throw std::ios_base::failure("out of bounds index");
616  }
617  if (last != -1 && idx <= last) {
618  throw std::ios_base::failure("offset overflow");
619  }
620  vec[idx] = true;
621  last = idx;
622  }
623  }
624 };
625 
631 {
632 protected:
633  std::vector<bool>& vec;
634  size_t size;
635 
636 public:
637  explicit CAutoBitSet(std::vector<bool>& vecIn, size_t sizeIn) : vec(vecIn), size(sizeIn) {}
638 
639  template <typename Stream>
640  void Serialize(Stream& s) const
641  {
642  assert(vec.size() == size);
643 
644  ser_writedata8(s, 0);
645  s << FIXEDVARINTSBITSET(vec, vec.size());
646  }
647 
648  template <typename Stream>
649  void Unserialize(Stream& s)
650  {
651  uint8_t isVarInts = ser_readdata8(s);
652  if (isVarInts != 0) {
653  throw std::ios_base::failure("invalid value for isVarInts byte");
654  }
655  s >> FIXEDVARINTSBITSET(vec, size);
656  }
657 };
658 
668 template<int Bytes, bool BigEndian = false>
670 {
671  static_assert(Bytes > 0 && Bytes <= 8, "CustomUintFormatter Bytes out of range");
672  static constexpr uint64_t MAX = 0xffffffffffffffff >> (8 * (8 - Bytes));
673 
674  template <typename Stream, typename I> void Ser(Stream& s, I v)
675  {
676  if (v < 0 || v > MAX) throw std::ios_base::failure("CustomUintFormatter value out of range");
677  if (BigEndian) {
678  uint64_t raw = htobe64(v);
679  s.write(((const char*)&raw) + 8 - Bytes, Bytes);
680  } else {
681  uint64_t raw = htole64(v);
682  s.write((const char*)&raw, Bytes);
683  }
684  }
685 
686  template <typename Stream, typename I> void Unser(Stream& s, I& v)
687  {
688  using U = typename std::conditional<std::is_enum<I>::value, std::underlying_type<I>, std::common_type<I>>::type::type;
689  static_assert(std::numeric_limits<U>::max() >= MAX && std::numeric_limits<U>::min() <= 0, "Assigned type too small");
690  uint64_t raw = 0;
691  if (BigEndian) {
692  s.read(((char*)&raw) + 8 - Bytes, Bytes);
693  v = static_cast<I>(be64toh(raw));
694  } else {
695  s.read((char*)&raw, Bytes);
696  v = static_cast<I>(le64toh(raw));
697  }
698  }
699 };
700 
702 
704 template<bool RangeCheck>
706 {
707  template<typename Stream, typename I>
708  void Unser(Stream& s, I& v)
709  {
710  uint64_t n = ReadCompactSize<Stream>(s, RangeCheck);
711  if (n < std::numeric_limits<I>::min() || n > std::numeric_limits<I>::max()) {
712  throw std::ios_base::failure("CompactSize exceeds limit of type");
713  }
714  v = n;
715  }
716 
717  template<typename Stream, typename I>
718  void Ser(Stream& s, I v)
719  {
720  static_assert(std::is_unsigned<I>::value, "CompactSize only supported for unsigned integers");
721  static_assert(std::numeric_limits<I>::max() <= std::numeric_limits<uint64_t>::max(), "CompactSize only supports 64-bit integers and below");
722 
723  WriteCompactSize<Stream>(s, v);
724  }
725 };
726 
727 template<size_t Limit>
729 {
730  template<typename Stream>
731  void Unser(Stream& s, std::string& v)
732  {
733  size_t size = ReadCompactSize(s);
734  if (size > Limit) {
735  throw std::ios_base::failure("String length limit exceeded");
736  }
737  v.resize(size);
738  if (size != 0) s.read((char*)v.data(), size);
739  }
740 
741  template<typename Stream>
742  void Ser(Stream& s, const std::string& v)
743  {
744  s << v;
745  }
746 };
747 
761 template<class Formatter>
763 {
764  template<typename Stream, typename V>
765  void Ser(Stream& s, const V& v)
766  {
767  Formatter formatter;
768  WriteCompactSize(s, v.size());
769  for (const typename V::value_type& elem : v) {
770  formatter.Ser(s, elem);
771  }
772  }
773 
774  template<typename Stream, typename V>
775  void Unser(Stream& s, V& v)
776  {
777  Formatter formatter;
778  v.clear();
779  size_t size = ReadCompactSize(s);
780  size_t allocated = 0;
781  while (allocated < size) {
782  // For DoS prevention, do not blindly allocate as much as the stream claims to contain.
783  // Instead, allocate in 5MiB batches, so that an attacker actually needs to provide
784  // X MiB of data to make us allocate X+5 Mib.
785  static_assert(sizeof(typename V::value_type) <= MAX_VECTOR_ALLOCATE, "Vector element size too large");
786  allocated = std::min(size, allocated + MAX_VECTOR_ALLOCATE / sizeof(typename V::value_type));
787  v.reserve(allocated);
788  while (v.size() < allocated) {
789  v.emplace_back();
790  formatter.Unser(s, v.back());
791  }
792  }
793  };
794 };
795 
803 template<typename Stream, typename C> void Serialize(Stream& os, const std::basic_string<C>& str);
804 template<typename Stream, typename C> void Unserialize(Stream& is, std::basic_string<C>& str);
805 
810 template<typename Stream, unsigned int N, typename T> void Serialize_impl(Stream& os, const prevector<N, T>& v, const unsigned char&);
811 template<typename Stream, unsigned int N, typename T, typename V> void Serialize_impl(Stream& os, const prevector<N, T>& v, const V&);
812 template<typename Stream, unsigned int N, typename T> inline void Serialize(Stream& os, const prevector<N, T>& v);
813 template<typename Stream, unsigned int N, typename T> void Unserialize_impl(Stream& is, prevector<N, T>& v, const unsigned char&);
814 template<typename Stream, unsigned int N, typename T, typename V> void Unserialize_impl(Stream& is, prevector<N, T>& v, const V&);
815 template<typename Stream, unsigned int N, typename T> inline void Unserialize(Stream& is, prevector<N, T>& v);
816 
821 template<typename Stream, typename T, typename A> void Serialize_impl(Stream& os, const std::vector<T, A>& v, const unsigned char&);
822 template<typename Stream, typename T, typename A> void Serialize_impl(Stream& os, const std::vector<T, A>& v, const bool&);
823 template<typename Stream, typename T, typename A, typename V> void Serialize_impl(Stream& os, const std::vector<T, A>& v, const V&);
824 template<typename Stream, typename T, typename A> inline void Serialize(Stream& os, const std::vector<T, A>& v);
825 template<typename Stream, typename T, typename A> void Unserialize_impl(Stream& is, std::vector<T, A>& v, const unsigned char&);
826 template<typename Stream, typename T, typename A, typename V> void Unserialize_impl(Stream& is, std::vector<T, A>& v, const V&);
827 template<typename Stream, typename T, typename A> inline void Unserialize(Stream& is, std::vector<T, A>& v);
828 
832 template<typename T, std::size_t N> unsigned int GetSerializeSize(const std::array<T, N> &item);
833 template<typename Stream, typename T, std::size_t N> void Serialize(Stream& os, const std::array<T, N>& item);
834 template<typename Stream, typename T, std::size_t N> void Unserialize(Stream& is, std::array<T, N>& item);
835 
839 template<typename T> unsigned int GetSerializeSize(const Optional<T> &item);
840 template<typename Stream, typename T> void Serialize(Stream& os, const Optional<T>& item);
841 template<typename Stream, typename T> void Unserialize(Stream& is, Optional<T>& item);
842 
846 template<typename T, std::size_t N>
847 unsigned int GetSerializeSize(const std::array<T, N> &item)
848 {
849  unsigned int size = 0;
850  for (size_t i = 0; i < N; i++) {
851  size += GetSerializeSize(item[0]);
852  }
853  return size;
854 }
855 
856 template<typename Stream, typename T>
857 void Serialize(Stream& os, const Optional<T>& item)
858 {
859  // If the value is there, put 0x01 and then serialize the value.
860  // If it's not, put 0x00.
861  if (item) {
862  unsigned char discriminant = 0x01;
863  Serialize(os, discriminant);
864  Serialize(os, *item);
865  } else {
866  unsigned char discriminant = 0x00;
867  Serialize(os, discriminant);
868  }
869 }
870 
871 template<typename Stream, typename T>
872 void Unserialize(Stream& is, Optional<T>& item)
873 {
874  unsigned char discriminant = 0x00;
875  Unserialize(is, discriminant);
876 
877  if (discriminant == 0x00) {
878  item = boost::none;
879  } else {
880  T object;
881  Unserialize(is, object);
882  item = object;
883  }
884 }
885 
886 
887 template<typename Stream, typename T, std::size_t N>
888 void Serialize(Stream& os, const std::array<T, N>& item)
889 {
890  for (size_t i = 0; i < N; i++) {
891  Serialize(os, item[i]);
892  }
893 }
894 
895 template<typename Stream, typename T, std::size_t N>
896 void Unserialize(Stream& is, std::array<T, N>& item)
897 {
898  for (size_t i = 0; i < N; i++) {
899  Unserialize(is, item[i]);
900  }
901 }
902 
903 
907 template<typename Stream, typename K, typename T> void Serialize(Stream& os, const std::pair<K, T>& item);
908 template<typename Stream, typename K, typename T> void Unserialize(Stream& is, std::pair<K, T>& item);
909 
913 template<typename Stream, typename... Elements> void Serialize(Stream& os, const std::tuple<Elements...>& item);
914 template<typename Stream, typename... Elements> void Unserialize(Stream& is, std::tuple<Elements...>& item);
915 
919 template<typename Stream, typename K, typename T, typename Pred, typename A> void Serialize(Stream& os, const std::map<K, T, Pred, A>& m);
920 template<typename Stream, typename K, typename T, typename Pred, typename A> void Unserialize(Stream& is, std::map<K, T, Pred, A>& m);
921 
925 template<typename Stream, typename K, typename Pred, typename A> void Serialize(Stream& os, const std::set<K, Pred, A>& m);
926 template<typename Stream, typename K, typename Pred, typename A> void Unserialize(Stream& is, std::set<K, Pred, A>& m);
927 
931 template<typename Stream, typename T> void Serialize(Stream& os, const std::shared_ptr<const T>& p);
932 template<typename Stream, typename T> void Unserialize(Stream& os, std::shared_ptr<const T>& p);
933 
934 template<typename Stream, typename T> void Serialize(Stream& os, const std::shared_ptr<T>& p);
935 template<typename Stream, typename T> void Unserialize(Stream& os, std::shared_ptr<T>& p);
936 
940 template<typename Stream, typename T> void Serialize(Stream& os, const std::unique_ptr<const T>& p);
941 template<typename Stream, typename T> void Unserialize(Stream& os, std::unique_ptr<const T>& p);
942 
943 
944 
948 template <typename Stream, typename T>
949 inline void Serialize(Stream& os, const T& a)
950 {
951  a.Serialize(os);
952 }
953 
954 template<typename Stream, typename T>
955 inline void Unserialize(Stream& is, T&& a)
956 {
957  a.Unserialize(is);
958 }
959 
966 {
967  template<typename Stream, typename T>
968  static void Ser(Stream& s, const T& t) { Serialize(s, t); }
969 
970  template<typename Stream, typename T>
971  static void Unser(Stream& s, T& t) { Unserialize(s, t); }
972 };
973 
974 
978 template <typename Stream, typename C>
979 void Serialize(Stream& os, const std::basic_string<C>& str)
980 {
981  WriteCompactSize(os, str.size());
982  if (!str.empty())
983  os.write((char*)str.data(), str.size() * sizeof(C));
984 }
985 
986 template <typename Stream, typename C>
987 void Unserialize(Stream& is, std::basic_string<C>& str)
988 {
989  unsigned int nSize = ReadCompactSize(is);
990  str.resize(nSize);
991  if (nSize != 0)
992  is.read((char*)str.data(), nSize * sizeof(C));
993 }
994 
998 template<typename T, typename A> unsigned int GetSerializeSize(const std::list<T, A>& m);
999 template<typename Stream, typename T, typename A> void Serialize(Stream& os, const std::list<T, A>& m);
1000 template<typename Stream, typename T, typename A> void Unserialize(Stream& is, std::list<T, A>& m);
1001 
1002 template<typename T, typename A>
1003 unsigned int GetSerializeSize(const std::list<T, A>& l)
1004 {
1005  unsigned int nSize = GetSizeOfCompactSize(l.size());
1006  for (typename std::list<T, A>::const_iterator it = l.begin(); it != l.end(); ++it)
1007  nSize += GetSerializeSize((*it));
1008  return nSize;
1009 }
1010 
1011 template<typename Stream, typename T, typename A>
1012 void Serialize(Stream& os, const std::list<T, A>& l)
1013 {
1014  WriteCompactSize(os, l.size());
1015  for (typename std::list<T, A>::const_iterator it = l.begin(); it != l.end(); ++it)
1016  Serialize(os, (*it));
1017 }
1018 
1019 template<typename Stream, typename T, typename A>
1020 void Unserialize(Stream& is, std::list<T, A>& l)
1021 {
1022  l.clear();
1023  unsigned int nSize = ReadCompactSize(is);
1024  for (unsigned int i = 0; i < nSize; i++)
1025  {
1026  T item;
1027  Unserialize(is, item);
1028  l.push_back(item);
1029  }
1030 }
1031 
1032 
1036 template<typename Stream, unsigned int N, typename T>
1037 void Serialize_impl(Stream& os, const prevector<N, T>& v, const unsigned char&)
1038 {
1039  WriteCompactSize(os, v.size());
1040  if (!v.empty())
1041  os.write((char*)v.data(), v.size() * sizeof(T));
1042 }
1043 
1044 template<typename Stream, unsigned int N, typename T, typename V>
1045 void Serialize_impl(Stream& os, const prevector<N, T>& v, const V&)
1046 {
1048 }
1049 
1050 template<typename Stream, unsigned int N, typename T>
1051 inline void Serialize(Stream& os, const prevector<N, T>& v)
1052 {
1053  Serialize_impl(os, v, T());
1054 }
1055 
1056 
1057 template<typename Stream, unsigned int N, typename T>
1058 void Unserialize_impl(Stream& is, prevector<N, T>& v, const unsigned char&)
1059 {
1060  // Limit size per read so bogus size value won't cause out of memory
1061  v.clear();
1062  unsigned int nSize = ReadCompactSize(is);
1063  unsigned int i = 0;
1064  while (i < nSize)
1065  {
1066  unsigned int blk = std::min(nSize - i, (unsigned int)(1 + 4999999 / sizeof(T)));
1067  v.resize_uninitialized(i + blk);
1068  is.read((char*)&v[i], blk * sizeof(T));
1069  i += blk;
1070  }
1071 }
1072 
1073 template<typename Stream, unsigned int N, typename T, typename V>
1074 void Unserialize_impl(Stream& is, prevector<N, T>& v, const V&)
1075 {
1077 }
1078 
1079 template<typename Stream, unsigned int N, typename T>
1080 inline void Unserialize(Stream& is, prevector<N, T>& v)
1081 {
1082  Unserialize_impl(is, v, T());
1083 }
1084 
1085 
1086 
1090 template <typename Stream, typename T, typename A>
1091 void Serialize_impl(Stream& os, const std::vector<T, A>& v, const unsigned char&)
1092 {
1093  WriteCompactSize(os, v.size());
1094  if (!v.empty())
1095  os.write((char*)v.data(), v.size() * sizeof(T));
1096 }
1097 
1098 template <typename Stream, typename T, typename A>
1099 void Serialize_impl(Stream& os, const std::vector<T, A>& v, const bool&)
1100 {
1101  // A special case for std::vector<bool>, as dereferencing
1102  // std::vector<bool>::const_iterator does not result in a const bool&
1103  // due to std::vector's special casing for bool arguments.
1104  WriteCompactSize(os, v.size());
1105  for (bool elem : v) {
1106  ::Serialize(os, elem);
1107  }
1108 }
1109 
1110 template <typename Stream, typename T, typename A, typename V>
1111 void Serialize_impl(Stream& os, const std::vector<T, A>& v, const V&)
1112 {
1114 }
1115 
1116 template <typename Stream, typename T, typename A>
1117 inline void Serialize(Stream& os, const std::vector<T, A>& v)
1118 {
1119  Serialize_impl(os, v, T());
1120 }
1121 
1122 
1123 template <typename Stream, typename T, typename A>
1124 void Unserialize_impl(Stream& is, std::vector<T, A>& v, const unsigned char&)
1125 {
1126  // Limit size per read so bogus size value won't cause out of memory
1127  v.clear();
1128  unsigned int nSize = ReadCompactSize(is);
1129  unsigned int i = 0;
1130  while (i < nSize) {
1131  unsigned int blk = std::min(nSize - i, (unsigned int)(1 + 4999999 / sizeof(T)));
1132  v.resize(i + blk);
1133  is.read((char*)&v[i], blk * sizeof(T));
1134  i += blk;
1135  }
1136 }
1137 
1138 template <typename Stream, typename T, typename A, typename V>
1139 void Unserialize_impl(Stream& is, std::vector<T, A>& v, const V&)
1140 {
1142 }
1143 
1144 template <typename Stream, typename T, typename A>
1145 inline void Unserialize(Stream& is, std::vector<T, A>& v)
1146 {
1147  Unserialize_impl(is, v, T());
1148 }
1149 
1150 
1151 
1155 template <typename Stream, typename K, typename T>
1156 void Serialize(Stream& os, const std::pair<K, T>& item)
1157 {
1158  Serialize(os, item.first);
1159  Serialize(os, item.second);
1160 }
1161 
1162 template <typename Stream, typename K, typename T>
1163 void Unserialize(Stream& is, std::pair<K, T>& item)
1164 {
1165  Unserialize(is, item.first);
1166  Unserialize(is, item.second);
1167 }
1168 
1172 template<typename Stream, int index, typename... Ts>
1174  void operator() (Stream&s, std::tuple<Ts...>& t) {
1175  SerializeTuple<Stream, index - 1, Ts...>{}(s, t);
1176  s << std::get<index>(t);
1177  }
1178 };
1179 
1180 template<typename Stream, typename... Ts>
1181 struct SerializeTuple<Stream, 0, Ts...> {
1182  void operator() (Stream&s, std::tuple<Ts...>& t) {
1183  s << std::get<0>(t);
1184  }
1185 };
1186 
1187 template<typename Stream, int index, typename... Ts>
1189  void operator() (Stream&s, std::tuple<Ts...>& t) {
1190  DeserializeTuple<Stream, index - 1, Ts...>{}(s, t);
1191  s >> std::get<index>(t);
1192  }
1193 };
1194 
1195 template<typename Stream, typename... Ts>
1196 struct DeserializeTuple<Stream, 0, Ts...> {
1197  void operator() (Stream&s, std::tuple<Ts...>& t) {
1198  s >> std::get<0>(t);
1199  }
1200 };
1201 
1202 
1203 template<typename Stream, typename... Elements>
1204 void Serialize(Stream& os, const std::tuple<Elements...>& item)
1205 {
1206  const auto size = std::tuple_size<std::tuple<Elements...>>::value;
1207  SerializeTuple<Stream, size - 1, Elements...>{}(os, const_cast<std::tuple<Elements...>&>(item));
1208 }
1209 
1210 template<typename Stream, typename... Elements>
1211 void Unserialize(Stream& is, std::tuple<Elements...>& item)
1212 {
1213  const auto size = std::tuple_size<std::tuple<Elements...>>::value;
1214  DeserializeTuple<Stream, size - 1, Elements...>{}(is, item);
1215 }
1216 
1217 
1221 template <typename Stream, typename K, typename T, typename Pred, typename A>
1222 void Serialize(Stream& os, const std::map<K, T, Pred, A>& m)
1223 {
1224  WriteCompactSize(os, m.size());
1225  for (const auto& entry : m)
1226  Serialize(os, entry);
1227 }
1228 
1229 template <typename Stream, typename K, typename T, typename Pred, typename A>
1230 void Unserialize(Stream& is, std::map<K, T, Pred, A>& m)
1231 {
1232  m.clear();
1233  unsigned int nSize = ReadCompactSize(is);
1234  typename std::map<K, T, Pred, A>::iterator mi = m.begin();
1235  for (unsigned int i = 0; i < nSize; i++) {
1236  std::pair<K, T> item;
1237  Unserialize(is, item);
1238  mi = m.insert(mi, item);
1239  }
1240 }
1241 
1242 
1246 template <typename Stream, typename K, typename Pred, typename A>
1247 void Serialize(Stream& os, const std::set<K, Pred, A>& m)
1248 {
1249  WriteCompactSize(os, m.size());
1250  for (typename std::set<K, Pred, A>::const_iterator it = m.begin(); it != m.end(); ++it)
1251  Serialize(os, (*it));
1252 }
1253 
1254 template <typename Stream, typename K, typename Pred, typename A>
1255 void Unserialize(Stream& is, std::set<K, Pred, A>& m)
1256 {
1257  m.clear();
1258  unsigned int nSize = ReadCompactSize(is);
1259  typename std::set<K, Pred, A>::iterator it = m.begin();
1260  for (unsigned int i = 0; i < nSize; i++) {
1261  K key;
1262  Unserialize(is, key);
1263  it = m.insert(it, key);
1264  }
1265 }
1266 
1267 
1268 
1272 template<typename Stream, typename T> void
1273 Serialize(Stream& os, const std::unique_ptr<const T>& p)
1274 {
1275  Serialize(os, *p);
1276 }
1277 
1278 template<typename Stream, typename T>
1279 void Unserialize(Stream& is, std::unique_ptr<const T>& p)
1280 {
1281  p.reset(new T(deserialize, is));
1282 }
1283 
1284 
1285 
1289 template<typename Stream, typename T> void
1290 Serialize(Stream& os, const std::shared_ptr<const T>& p)
1291 {
1292  Serialize(os, *p);
1293 }
1294 
1295 template<typename Stream, typename T>
1296 void Unserialize(Stream& is, std::shared_ptr<const T>& p)
1297 {
1298  p = std::make_shared<const T>(deserialize, is);
1299 }
1300 
1301 template<typename Stream, typename T> void
1302 Serialize(Stream& os, const std::shared_ptr<T>& p)
1303 {
1304  Serialize(os, *p);
1305 }
1306 
1307 template<typename Stream, typename T>
1308 void Unserialize(Stream& is, std::shared_ptr<T>& p)
1309 {
1310  p = std::make_shared<T>(deserialize, is);
1311 }
1312 
1317  constexpr bool ForRead() const { return false; }
1318 };
1320  constexpr bool ForRead() const { return true; }
1321 };
1322 
1323 
1324 /* ::GetSerializeSize implementations
1325  *
1326  * Computing the serialized size of objects is done through a special stream
1327  * object of type CSizeComputer, which only records the number of bytes written
1328  * to it.
1329  *
1330  * If your Serialize or SerializationOp method has non-trivial overhead for
1331  * serialization, it may be worthwhile to implement a specialized version for
1332  * CSizeComputer, which uses the s.seek() method to record bytes that would
1333  * be written instead.
1334  */
1336 {
1337 protected:
1338  size_t nSize;
1339 
1340  const int nVersion;
1341 
1342 public:
1343  explicit CSizeComputer(int nVersionIn) : nSize(0), nVersion(nVersionIn) {}
1344 
1345  void write(const char* psz, size_t _nSize)
1346  {
1347  this->nSize += _nSize;
1348  }
1349 
1351  void seek(size_t _nSize)
1352  {
1353  this->nSize += _nSize;
1354  }
1355 
1356  template <typename T>
1358  {
1359  ::Serialize(*this, obj);
1360  return (*this);
1361  }
1362 
1363  size_t size() const
1364  {
1365  return nSize;
1366  }
1367 
1368  int GetVersion() const { return nVersion; }
1369 };
1370 
1371 template<typename Stream>
1372 void SerializeMany(Stream& s)
1373 {
1374 }
1375 
1376 template<typename Stream, typename Arg, typename... Args>
1377 void SerializeMany(Stream& s, const Arg& arg, const Args&... args)
1378 {
1379  ::Serialize(s, arg);
1380  ::SerializeMany(s, args...);
1381 }
1382 
1383 template<typename Stream>
1384 inline void UnserializeMany(Stream& s)
1385 {
1386 }
1387 
1388 template<typename Stream, typename Arg, typename... Args>
1389 inline void UnserializeMany(Stream& s, Arg&& arg, Args&&... args)
1390 {
1391  ::Unserialize(s, arg);
1392  ::UnserializeMany(s, args...);
1393 }
1394 
1395 template<typename Stream, typename... Args>
1396 inline void SerReadWriteMany(Stream& s, CSerActionSerialize ser_action, const Args&... args)
1397 {
1398  ::SerializeMany(s, args...);
1399 }
1400 
1401 template<typename Stream, typename... Args>
1402 inline void SerReadWriteMany(Stream& s, CSerActionUnserialize ser_action, Args&&... args)
1403 {
1404  ::UnserializeMany(s, args...);
1405 }
1406 
1407 template<typename Stream, typename Type, typename Fn>
1408 inline void SerRead(Stream& s, CSerActionSerialize ser_action, Type&&, Fn&&)
1409 {
1410 }
1411 
1412 template<typename Stream, typename Type, typename Fn>
1413 inline void SerRead(Stream& s, CSerActionUnserialize ser_action, Type&& obj, Fn&& fn)
1414 {
1415  fn(s, std::forward<Type>(obj));
1416 }
1417 
1418 template<typename Stream, typename Type, typename Fn>
1419 inline void SerWrite(Stream& s, CSerActionSerialize ser_action, Type&& obj, Fn&& fn)
1420 {
1421  fn(s, std::forward<Type>(obj));
1422 }
1423 
1424 template<typename Stream, typename Type, typename Fn>
1425 inline void SerWrite(Stream& s, CSerActionUnserialize ser_action, Type&&, Fn&&)
1426 {
1427 }
1428 
1429 template<typename I>
1430 inline void WriteVarInt(CSizeComputer &s, I n)
1431 {
1432  s.seek(GetSizeOfVarInt<I>(n));
1433 }
1434 
1435 inline void WriteCompactSize(CSizeComputer &s, uint64_t nSize)
1436 {
1437  s.seek(GetSizeOfCompactSize(nSize));
1438 }
1439 
1440 template <typename T>
1441 size_t GetSerializeSize(const T& t, int nVersion = 0)
1442 {
1443  return (CSizeComputer(nVersion) << t).size();
1444 }
1445 
1446 template <typename... T>
1447 size_t GetSerializeSizeMany(int nVersion, const T&... t)
1448 {
1449  CSizeComputer sc(nVersion);
1450  SerializeMany(sc, t...);
1451  return sc.size();
1452 }
1453 
1457 template<typename T>
1458 unsigned int GetSerializeSize(const Optional<T> &item)
1459 {
1460  if (item) {
1461  return 1 + GetSerializeSize(*item);
1462  } else {
1463  return 1;
1464  }
1465 }
1466 
1467 #endif // PIVX_SERIALIZE_H
Serializes either as a or CFixedVarIntsBitSet.
Definition: serialize.h:631
CAutoBitSet(std::vector< bool > &vecIn, size_t sizeIn)
Definition: serialize.h:637
void Serialize(Stream &s) const
Definition: serialize.h:640
std::vector< bool > & vec
Definition: serialize.h:633
void Unserialize(Stream &s)
Definition: serialize.h:649
size_t size
Definition: serialize.h:634
Stores a fixed size bitset as a series of VarInts.
Definition: serialize.h:581
CFixedVarIntsBitSet(std::vector< bool > &vecIn, size_t sizeIn)
Definition: serialize.h:587
std::vector< bool > & vec
Definition: serialize.h:583
void Unserialize(Stream &s)
Definition: serialize.h:603
void Serialize(Stream &s) const
Definition: serialize.h:590
Serialized script, used inside transaction inputs and outputs.
Definition: script.h:381
CSizeComputer & operator<<(const T &obj)
Definition: serialize.h:1357
void write(const char *psz, size_t _nSize)
Definition: serialize.h:1345
CSizeComputer(int nVersionIn)
Definition: serialize.h:1343
size_t nSize
Definition: serialize.h:1338
size_t size() const
Definition: serialize.h:1363
const int nVersion
Definition: serialize.h:1340
void seek(size_t _nSize)
Pretend _nSize bytes are written, without specifying them.
Definition: serialize.h:1351
int GetVersion() const
Definition: serialize.h:1368
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:182
constexpr C * data() const noexcept
Definition: span.h:169
Simple wrapper class to serialize objects using a formatter; used by Using().
Definition: serialize.h:489
Wrapper(T obj)
Definition: serialize.h:494
T m_object
Definition: serialize.h:490
void Serialize(Stream &s) const
Definition: serialize.h:495
void Unserialize(Stream &s)
Definition: serialize.h:496
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:281
void clear()
Definition: prevector.h:338
size_type size() const
Definition: prevector.h:277
value_type * data()
Definition: prevector.h:526
void resize_uninitialized(size_type new_size)
Definition: prevector.h:384
uint16_t be16toh(uint16_t big_endian_16bits)
Definition: endian.h:170
uint16_t htobe16(uint16_t host_16bits)
Definition: endian.h:156
uint32_t le32toh(uint32_t little_endian_32bits)
Definition: endian.h:205
uint16_t le16toh(uint16_t little_endian_16bits)
Definition: endian.h:177
uint64_t htobe64(uint64_t host_64bits)
Definition: endian.h:212
uint64_t be64toh(uint64_t big_endian_64bits)
Definition: endian.h:226
uint64_t htole64(uint64_t host_64bits)
Definition: endian.h:219
uint32_t htole32(uint32_t host_32bits)
Definition: endian.h:191
uint16_t htole16(uint16_t host_16bits)
Definition: endian.h:163
uint64_t le64toh(uint64_t little_endian_64bits)
Definition: endian.h:233
void * memcpy(void *a, const void *b, size_t c)
#define T(expected, seed, data)
CoinDenomination IntToZerocoinDenomination(int64_t amount)
int64_t ZerocoinDenominationToInt(const CoinDenomination &denomination)
#define X(name)
Definition: net.cpp:664
boost::optional< T > Optional
Substitute for C++17 std::optional.
Definition: optional.h:12
@ SER_DISK
Definition: serialize.h:175
@ SER_NETWORK
Definition: serialize.h:174
@ SER_GETHASH
Definition: serialize.h:176
void SerializeMany(Stream &s)
Definition: serialize.h:1372
uint8_t ser_readdata8(Stream &s)
Definition: serialize.h:104
float ser_uint32_to_float(uint32_t y)
Definition: serialize.h:155
I ReadVarInt(Stream &is)
Definition: serialize.h:465
void WriteVarInt(CSizeComputer &os, I n)
Definition: serialize.h:1430
VarIntMode
Variable-length integers: bytes are a MSB base-128 encoding of the number.
Definition: serialize.h:418
@ NONNEGATIVE_SIGNED
void ser_writedata32(Stream &s, uint32_t obj)
Definition: serialize.h:94
unsigned int GetSerializeSize(const std::array< T, N > &item)
array
Definition: serialize.h:847
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:324
constexpr deserialize_type deserialize
Definition: serialize.h:57
void Serialize(Stream &s, char a)
Definition: serialize.h:237
void ser_writedata16(Stream &s, uint16_t obj)
Definition: serialize.h:84
uint32_t ser_float_to_uint32(float x)
Definition: serialize.h:141
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:1037
X & ReadWriteAsHelper(X &x)
Convert the reference base type to X, without changing constness or reference type.
Definition: serialize.h:180
void SerReadWriteMany(Stream &s, CSerActionSerialize ser_action, const Args &... args)
Definition: serialize.h:1396
void Unserialize_impl(Stream &is, prevector< N, T > &v, const unsigned char &)
Definition: serialize.h:1058
void Unserialize(Stream &s, char &a)
Definition: serialize.h:253
#define FIXEDVARINTSBITSET(obj, size)
Definition: serialize.h:534
void SerWrite(Stream &s, CSerActionSerialize ser_action, Type &&obj, Fn &&fn)
Definition: serialize.h:1419
char * CharCast(char *c)
Safely convert odd char pointer types to standard ones.
Definition: serialize.h:71
void ser_writedata16be(Stream &s, uint16_t obj)
Definition: serialize.h:89
uint16_t ser_readdata16(Stream &s)
Definition: serialize.h:110
uint64_t ser_readdata64(Stream &s)
Definition: serialize.h:128
double ser_uint64_to_double(uint64_t y)
Definition: serialize.h:148
void ser_writedata8(Stream &s, uint8_t obj)
Definition: serialize.h:80
uint64_t ReadCompactSize(Stream &is, bool range_check=true)
Decode a CompactSize-encoded variable-length integer.
Definition: serialize.h:359
unsigned int GetSizeOfVarInt(I n)
Definition: serialize.h:430
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:65
uint32_t ser_readdata32(Stream &s)
Definition: serialize.h:122
uint16_t ser_readdata16be(Stream &s)
Definition: serialize.h:116
void SerRead(Stream &s, CSerActionSerialize ser_action, Type &&, Fn &&)
Definition: serialize.h:1408
void UnserializeMany(Stream &s)
Definition: serialize.h:1384
uint64_t ser_double_to_uint64(double x)
Definition: serialize.h:134
size_t GetSerializeSizeMany(int nVersion, const T &... t)
Definition: serialize.h:1447
void ser_writedata64(Stream &s, uint64_t obj)
Definition: serialize.h:99
void WriteCompactSize(CSizeComputer &os, uint64_t nSize)
Definition: serialize.h:1435
SporkId
Definition: sporkid.h:14
void Ser(Stream &s, const std::vector< bool > &vec)
Definition: serialize.h:543
void Unser(Stream &s, std::vector< bool > &vec)
Definition: serialize.h:557
Support for SERIALIZE_METHODS and READWRITE macro.
Definition: serialize.h:1316
constexpr bool ForRead() const
Definition: serialize.h:1317
constexpr bool ForRead() const
Definition: serialize.h:1320
constexpr CheckVarIntMode()
Definition: serialize.h:422
Formatter for integers in CompactSize format.
Definition: serialize.h:706
void Unser(Stream &s, I &v)
Definition: serialize.h:708
void Ser(Stream &s, I v)
Definition: serialize.h:718
Serialization wrapper class for custom integers and enums.
Definition: serialize.h:670
static constexpr uint64_t MAX
Definition: serialize.h:672
void Ser(Stream &s, I v)
Definition: serialize.h:674
void Unser(Stream &s, I &v)
Definition: serialize.h:686
Default formatter.
Definition: serialize.h:966
static void Ser(Stream &s, const T &t)
Definition: serialize.h:968
static void Unser(Stream &s, T &t)
Definition: serialize.h:971
void operator()(Stream &s, std::tuple< Ts... > &t)
Definition: serialize.h:1189
void Unser(Stream &s, std::string &v)
Definition: serialize.h:731
void Ser(Stream &s, const std::string &v)
Definition: serialize.h:742
void operator()(Stream &s, std::tuple< Ts... > &t)
Definition: serialize.h:1174
Serialization wrapper class for integers in VarInt format.
Definition: serialize.h:520
void Ser(Stream &s, I v)
Definition: serialize.h:521
void Unser(Stream &s, I &v)
Definition: serialize.h:526
Formatter to serialize/deserialize vector elements using another formatter.
Definition: serialize.h:763
void Unser(Stream &s, V &v)
Definition: serialize.h:775
void Ser(Stream &s, const V &v)
Definition: serialize.h:765
Dummy data type to identify deserializing constructors.
Definition: serialize.h:56