Fabcoin Core  0.16.2
P2P Digital Currency
serialize.h
Go to the documentation of this file.
1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2017 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 FABCOIN_SERIALIZE_H
7 #define FABCOIN_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 <uint256.h>
26 
27 static const unsigned int MAX_SIZE = 0x10000000; // Fabcoin: Increase max serialized size to 256mb
28 //static const unsigned int MAX_SIZE = 0x02000000;
29 
41 struct deserialize_type {};
43 
48 template<typename T>
49 inline T& REF(const T& val)
50 {
51  return const_cast<T&>(val);
52 }
53 
58 template<typename T>
59 inline T* NCONST_PTR(const T* val)
60 {
61  return const_cast<T*>(val);
62 }
63 
64 /*
65  * Lowest-level serialization and conversion.
66  * @note Sizes of these types are verified in the tests
67  */
68 template<typename Stream> inline void ser_writedata8(Stream &s, uint8_t obj)
69 {
70  s.write((char*)&obj, 1);
71 }
72 template<typename Stream> inline void ser_writedata16(Stream &s, uint16_t obj)
73 {
74  obj = htole16(obj);
75  s.write((char*)&obj, 2);
76 }
77 template<typename Stream> inline void ser_writedata32(Stream &s, uint32_t obj)
78 {
79  obj = htole32(obj);
80  s.write((char*)&obj, 4);
81 }
82 
84 template<typename Stream> inline void ser_writedata32be(Stream &s, uint32_t obj)
85 {
86  obj = htobe32(obj);
87  s.write((char*)&obj, 4);
88 }
90 
91 template<typename Stream> inline void ser_writedata64(Stream &s, uint64_t obj)
92 {
93  obj = htole64(obj);
94  s.write((char*)&obj, 8);
95 }
96 template<typename Stream> inline uint8_t ser_readdata8(Stream &s)
97 {
98  uint8_t obj;
99  s.read((char*)&obj, 1);
100  return obj;
101 }
102 template<typename Stream> inline uint16_t ser_readdata16(Stream &s)
103 {
104  uint16_t obj;
105  s.read((char*)&obj, 2);
106  return le16toh(obj);
107 }
108 template<typename Stream> inline uint32_t ser_readdata32(Stream &s)
109 {
110  uint32_t obj;
111  s.read((char*)&obj, 4);
112  return le32toh(obj);
113 }
115 template<typename Stream> inline uint32_t ser_readdata32be(Stream &s)
116 {
117  uint32_t obj;
118  s.read((char*)&obj, 4);
119  return be32toh(obj);
120 }
121 
122 template<typename Stream> inline uint256 ser_readdata256(Stream &s)
123 {
124  uint256 obj;
125  s.read((char*)&obj, 32);
126  //return le64toh(obj);
127  return obj;
128 }
130 
131 template<typename Stream> inline uint64_t ser_readdata64(Stream &s)
132 {
133  uint64_t obj;
134  s.read((char*)&obj, 8);
135  return le64toh(obj);
136 }
137 inline uint64_t ser_double_to_uint64(double x)
138 {
139  union { double x; uint64_t y; } tmp;
140  tmp.x = x;
141  return tmp.y;
142 }
143 inline uint32_t ser_float_to_uint32(float x)
144 {
145  union { float x; uint32_t y; } tmp;
146  tmp.x = x;
147  return tmp.y;
148 }
149 inline double ser_uint64_to_double(uint64_t y)
150 {
151  union { double x; uint64_t y; } tmp;
152  tmp.y = y;
153  return tmp.x;
154 }
155 inline float ser_uint32_to_float(uint32_t y)
156 {
157  union { float x; uint32_t y; } tmp;
158  tmp.y = y;
159  return tmp.x;
160 }
161 
162 
164 //
165 // Templates for serializing to anything that looks like a stream,
166 // i.e. anything that supports .read(char*, size_t) and .write(char*, size_t)
167 //
168 
169 class CSizeComputer;
170 
171 enum
172 {
173  // primary actions
174  SER_NETWORK = (1 << 0),
175  SER_DISK = (1 << 1),
176  SER_GETHASH = (1 << 2),
177 };
178 
179 #define READWRITE(obj) (::SerReadWrite(s, (obj), ser_action))
180 #define READWRITEMANY(...) (::SerReadWriteMany(s, ser_action, __VA_ARGS__))
181 
188 #define ADD_SERIALIZE_METHODS \
189  template<typename Stream> \
190  void Serialize(Stream& s) const { \
191  NCONST_PTR(this)->SerializationOp(s, CSerActionSerialize()); \
192  } \
193  template<typename Stream> \
194  void Unserialize(Stream& s) { \
195  SerializationOp(s, CSerActionUnserialize()); \
196  }
197 
198 template<typename Stream> inline void Serialize(Stream& s, char a ) { ser_writedata8(s, a); } // TODO Get rid of bare char
199 template<typename Stream> inline void Serialize(Stream& s, int8_t a ) { ser_writedata8(s, a); }
200 template<typename Stream> inline void Serialize(Stream& s, uint8_t a ) { ser_writedata8(s, a); }
201 template<typename Stream> inline void Serialize(Stream& s, int16_t a ) { ser_writedata16(s, a); }
202 template<typename Stream> inline void Serialize(Stream& s, uint16_t a) { ser_writedata16(s, a); }
203 template<typename Stream> inline void Serialize(Stream& s, int32_t a ) { ser_writedata32(s, a); }
204 template<typename Stream> inline void Serialize(Stream& s, uint32_t a) { ser_writedata32(s, a); }
205 template<typename Stream> inline void Serialize(Stream& s, int64_t a ) { ser_writedata64(s, a); }
206 template<typename Stream> inline void Serialize(Stream& s, uint64_t a) { ser_writedata64(s, a); }
207 template<typename Stream> inline void Serialize(Stream& s, float a ) { ser_writedata32(s, ser_float_to_uint32(a)); }
208 template<typename Stream> inline void Serialize(Stream& s, double a ) { ser_writedata64(s, ser_double_to_uint64(a)); }
209 
210 template<typename Stream> inline void Unserialize(Stream& s, char& a ) { a = ser_readdata8(s); } // TODO Get rid of bare char
211 template<typename Stream> inline void Unserialize(Stream& s, int8_t& a ) { a = ser_readdata8(s); }
212 template<typename Stream> inline void Unserialize(Stream& s, uint8_t& a ) { a = ser_readdata8(s); }
213 template<typename Stream> inline void Unserialize(Stream& s, int16_t& a ) { a = ser_readdata16(s); }
214 template<typename Stream> inline void Unserialize(Stream& s, uint16_t& a) { a = ser_readdata16(s); }
215 template<typename Stream> inline void Unserialize(Stream& s, int32_t& a ) { a = ser_readdata32(s); }
216 template<typename Stream> inline void Unserialize(Stream& s, uint32_t& a) { a = ser_readdata32(s); }
217 template<typename Stream> inline void Unserialize(Stream& s, int64_t& a ) { a = ser_readdata64(s); }
218 template<typename Stream> inline void Unserialize(Stream& s, uint64_t& a) { a = ser_readdata64(s); }
219 template<typename Stream> inline void Unserialize(Stream& s, float& a ) { a = ser_uint32_to_float(ser_readdata32(s)); }
220 template<typename Stream> inline void Unserialize(Stream& s, double& a ) { a = ser_uint64_to_double(ser_readdata64(s)); }
221 
222 template<typename Stream> inline void Serialize(Stream& s, bool a) { char f=a; ser_writedata8(s, f); }
223 template<typename Stream> inline void Unserialize(Stream& s, bool& a) { char f=ser_readdata8(s); a=f; }
224 
225 
226 
227 
228 
229 
237 inline unsigned int GetSizeOfCompactSize(uint64_t nSize)
238 {
239  if (nSize < 253) return sizeof(unsigned char);
240  else if (nSize <= std::numeric_limits<unsigned short>::max()) return sizeof(unsigned char) + sizeof(unsigned short);
241  else if (nSize <= std::numeric_limits<unsigned int>::max()) return sizeof(unsigned char) + sizeof(unsigned int);
242  else return sizeof(unsigned char) + sizeof(uint64_t);
243 }
244 
245 inline void WriteCompactSize(CSizeComputer& os, uint64_t nSize);
246 
247 template<typename Stream>
248 void WriteCompactSize(Stream& os, uint64_t nSize)
249 {
250  if (nSize < 253)
251  {
252  ser_writedata8(os, nSize);
253  }
254  else if (nSize <= std::numeric_limits<unsigned short>::max())
255  {
256  ser_writedata8(os, 253);
257  ser_writedata16(os, nSize);
258  }
259  else if (nSize <= std::numeric_limits<unsigned int>::max())
260  {
261  ser_writedata8(os, 254);
262  ser_writedata32(os, nSize);
263  }
264  else
265  {
266  ser_writedata8(os, 255);
267  ser_writedata64(os, nSize);
268  }
269  return;
270 }
271 
272 template<typename Stream>
273 uint64_t ReadCompactSize(Stream& is)
274 {
275  uint8_t chSize = ser_readdata8(is);
276  uint64_t nSizeRet = 0;
277  if (chSize < 253)
278  {
279  nSizeRet = chSize;
280  }
281  else if (chSize == 253)
282  {
283  nSizeRet = ser_readdata16(is);
284  if (nSizeRet < 253)
285  throw std::ios_base::failure("non-canonical ReadCompactSize()");
286  }
287  else if (chSize == 254)
288  {
289  nSizeRet = ser_readdata32(is);
290  if (nSizeRet < 0x10000u)
291  throw std::ios_base::failure("non-canonical ReadCompactSize()");
292  }
293  else
294  {
295  nSizeRet = ser_readdata64(is);
296  if (nSizeRet < 0x100000000ULL)
297  throw std::ios_base::failure("non-canonical ReadCompactSize()");
298  }
299  if (nSizeRet > (uint64_t)MAX_SIZE)
300  throw std::ios_base::failure("ReadCompactSize(): size too large");
301  return nSizeRet;
302 }
303 
304 template<typename Stream>
305 uint256 ReadUint256(Stream& is)
306 {
307  return ser_readdata256(is);
308 }
309 
334 template<typename I>
335 inline unsigned int GetSizeOfVarInt(I n)
336 {
337  int nRet = 0;
338  while(true) {
339  nRet++;
340  if (n <= 0x7F)
341  break;
342  n = (n >> 7) - 1;
343  }
344  return nRet;
345 }
346 
347 template<typename I>
348 inline void WriteVarInt(CSizeComputer& os, I n);
349 
350 template<typename Stream, typename I>
351 void WriteVarInt(Stream& os, I n)
352 {
353  unsigned char tmp[(sizeof(n)*8+6)/7];
354  int len=0;
355  while(true) {
356  tmp[len] = (n & 0x7F) | (len ? 0x80 : 0x00);
357  if (n <= 0x7F)
358  break;
359  n = (n >> 7) - 1;
360  len++;
361  }
362  do {
363  ser_writedata8(os, tmp[len]);
364  } while(len--);
365 }
366 
367 template<typename Stream, typename I>
368 I ReadVarInt(Stream& is)
369 {
370  I n = 0;
371  while(true) {
372  unsigned char chData = ser_readdata8(is);
373  if (n > (std::numeric_limits<I>::max() >> 7)) {
374  throw std::ios_base::failure("ReadVarInt(): size too large");
375  }
376  n = (n << 7) | (chData & 0x7F);
377  if (chData & 0x80) {
378  if (n == std::numeric_limits<I>::max()) {
379  throw std::ios_base::failure("ReadVarInt(): size too large");
380  }
381  n++;
382  } else {
383  return n;
384  }
385  }
386 }
387 
388 #define FLATDATA(obj) REF(CFlatData((char*)&(obj), (char*)&(obj) + sizeof(obj)))
389 #define VARINT(obj) REF(WrapVarInt(REF(obj)))
390 #define COMPACTSIZE(obj) REF(CCompactSize(REF(obj)))
391 #define LIMITED_STRING(obj,n) REF(LimitedString< n >(REF(obj)))
392 
397 {
398 protected:
399  char* pbegin;
400  char* pend;
401 public:
402  CFlatData(void* pbeginIn, void* pendIn) : pbegin((char*)pbeginIn), pend((char*)pendIn) { }
403  template <class T, class TAl>
404  explicit CFlatData(std::vector<T,TAl> &v)
405  {
406  pbegin = (char*)v.data();
407  pend = (char*)(v.data() + v.size());
408  }
409  template <unsigned int N, typename T, typename S, typename D>
411  {
412  pbegin = (char*)v.data();
413  pend = (char*)(v.data() + v.size());
414  }
415  char* begin() { return pbegin; }
416  const char* begin() const { return pbegin; }
417  char* end() { return pend; }
418  const char* end() const { return pend; }
419 
420  template<typename Stream>
421  void Serialize(Stream& s) const
422  {
423  s.write(pbegin, pend - pbegin);
424  }
425 
426  template<typename Stream>
427  void Unserialize(Stream& s)
428  {
429  s.read(pbegin, pend - pbegin);
430  }
431 };
432 
433 template<typename I>
434 class CVarInt
435 {
436 protected:
437  I &n;
438 public:
439  CVarInt(I& nIn) : n(nIn) { }
440 
441  template<typename Stream>
442  void Serialize(Stream &s) const {
443  WriteVarInt<Stream,I>(s, n);
444  }
445 
446  template<typename Stream>
447  void Unserialize(Stream& s) {
448  n = ReadVarInt<Stream,I>(s);
449  }
450 };
451 
453 {
454 protected:
455  uint64_t &n;
456 public:
457  CCompactSize(uint64_t& nIn) : n(nIn) { }
458 
459  template<typename Stream>
460  void Serialize(Stream &s) const {
461  WriteCompactSize<Stream>(s, n);
462  }
463 
464  template<typename Stream>
465  void Unserialize(Stream& s) {
466  n = ReadCompactSize<Stream>(s);
467  }
468 };
469 
470 template<size_t Limit>
472 {
473 protected:
474  std::string& string;
475 public:
476  LimitedString(std::string& _string) : string(_string) {}
477 
478  template<typename Stream>
479  void Unserialize(Stream& s)
480  {
481  size_t size = ReadCompactSize(s);
482  if (size > Limit) {
483  throw std::ios_base::failure("String length limit exceeded");
484  }
485  string.resize(size);
486  if (size != 0)
487  s.read((char*)string.data(), size);
488  }
489 
490  template<typename Stream>
491  void Serialize(Stream& s) const
492  {
493  WriteCompactSize(s, string.size());
494  if (!string.empty())
495  s.write((char*)string.data(), string.size());
496  }
497 };
498 
499 template<typename I>
500 CVarInt<I> WrapVarInt(I& n) { return CVarInt<I>(n); }
501 
509 template<typename Stream, typename C> void Serialize(Stream& os, const std::basic_string<C>& str);
510 template<typename Stream, typename C> void Unserialize(Stream& is, std::basic_string<C>& str);
511 
516 template<typename Stream, unsigned int N, typename T> void Serialize_impl(Stream& os, const prevector<N, T>& v, const unsigned char&);
517 template<typename Stream, unsigned int N, typename T, typename V> void Serialize_impl(Stream& os, const prevector<N, T>& v, const V&);
518 template<typename Stream, unsigned int N, typename T> inline void Serialize(Stream& os, const prevector<N, T>& v);
519 template<typename Stream, unsigned int N, typename T> void Unserialize_impl(Stream& is, prevector<N, T>& v, const unsigned char&);
520 template<typename Stream, unsigned int N, typename T, typename V> void Unserialize_impl(Stream& is, prevector<N, T>& v, const V&);
521 template<typename Stream, unsigned int N, typename T> inline void Unserialize(Stream& is, prevector<N, T>& v);
522 
527 template<typename Stream, typename T, typename A> void Serialize_impl(Stream& os, const std::vector<T, A>& v, const unsigned char&);
528 template<typename Stream, typename T, typename A, typename V> void Serialize_impl(Stream& os, const std::vector<T, A>& v, const V&);
529 template<typename Stream, typename T, typename A> inline void Serialize(Stream& os, const std::vector<T, A>& v);
530 template<typename Stream, typename T, typename A> void Unserialize_impl(Stream& is, std::vector<T, A>& v, const unsigned char&);
531 template<typename Stream, typename T, typename A, typename V> void Unserialize_impl(Stream& is, std::vector<T, A>& v, const V&);
532 template<typename Stream, typename T, typename A> inline void Unserialize(Stream& is, std::vector<T, A>& v);
533 
537 template<typename Stream, typename K, typename T> void Serialize(Stream& os, const std::pair<K, T>& item);
538 template<typename Stream, typename K, typename T> void Unserialize(Stream& is, std::pair<K, T>& item);
539 
543 template<typename Stream, typename K, typename T, typename Pred, typename A> void Serialize(Stream& os, const std::map<K, T, Pred, A>& m);
544 template<typename Stream, typename K, typename T, typename Pred, typename A> void Unserialize(Stream& is, std::map<K, T, Pred, A>& m);
545 
549 template<typename Stream, typename K, typename Pred, typename A> void Serialize(Stream& os, const std::set<K, Pred, A>& m);
550 template<typename Stream, typename K, typename Pred, typename A> void Unserialize(Stream& is, std::set<K, Pred, A>& m);
551 
555 template<typename Stream, typename T> void Serialize(Stream& os, const std::shared_ptr<const T>& p);
556 template<typename Stream, typename T> void Unserialize(Stream& os, std::shared_ptr<const T>& p);
557 
561 template<typename Stream, typename T> void Serialize(Stream& os, const std::unique_ptr<const T>& p);
562 template<typename Stream, typename T> void Unserialize(Stream& os, std::unique_ptr<const T>& p);
563 
564 
565 
569 template<typename Stream, typename T>
570 inline void Serialize(Stream& os, const T& a)
571 {
572  a.Serialize(os);
573 }
574 
575 template<typename Stream, typename T>
576 inline void Unserialize(Stream& is, T& a)
577 {
578  a.Unserialize(is);
579 }
580 
581 
582 
583 
584 
588 template<typename Stream, typename C>
589 void Serialize(Stream& os, const std::basic_string<C>& str)
590 {
591  WriteCompactSize(os, str.size());
592  if (!str.empty())
593  os.write((char*)str.data(), str.size() * sizeof(C));
594 }
595 
596 template<typename Stream, typename C>
597 void Unserialize(Stream& is, std::basic_string<C>& str)
598 {
599  unsigned int nSize = ReadCompactSize(is);
600  str.resize(nSize);
601  if (nSize != 0)
602  is.read((char*)str.data(), nSize * sizeof(C));
603 }
604 
605 
606 
610 template<typename Stream, unsigned int N, typename T>
611 void Serialize_impl(Stream& os, const prevector<N, T>& v, const unsigned char&)
612 {
613  WriteCompactSize(os, v.size());
614  if (!v.empty())
615  os.write((char*)v.data(), v.size() * sizeof(T));
616 }
617 
618 template<typename Stream, unsigned int N, typename T, typename V>
619 void Serialize_impl(Stream& os, const prevector<N, T>& v, const V&)
620 {
621  WriteCompactSize(os, v.size());
622  for (typename prevector<N, T>::const_iterator vi = v.begin(); vi != v.end(); ++vi)
623  ::Serialize(os, (*vi));
624 }
625 
626 template<typename Stream, unsigned int N, typename T>
627 inline void Serialize(Stream& os, const prevector<N, T>& v)
628 {
629  Serialize_impl(os, v, T());
630 }
631 
632 
633 template<typename Stream, unsigned int N, typename T>
634 void Unserialize_impl(Stream& is, prevector<N, T>& v, const unsigned char&)
635 {
636  // Limit size per read so bogus size value won't cause out of memory
637  v.clear();
638  unsigned int nSize = ReadCompactSize(is);
639  unsigned int i = 0;
640  while (i < nSize)
641  {
642  unsigned int blk = std::min(nSize - i, (unsigned int)(1 + 4999999 / sizeof(T)));
643  v.resize(i + blk);
644  is.read((char*)&v[i], blk * sizeof(T));
645  i += blk;
646  }
647 }
648 
649 template<typename Stream, unsigned int N, typename T, typename V>
650 void Unserialize_impl(Stream& is, prevector<N, T>& v, const V&)
651 {
652  v.clear();
653  unsigned int nSize = ReadCompactSize(is);
654  unsigned int i = 0;
655  unsigned int nMid = 0;
656  while (nMid < nSize)
657  {
658  nMid += 5000000 / sizeof(T);
659  if (nMid > nSize)
660  nMid = nSize;
661  v.resize(nMid);
662  for (; i < nMid; i++)
663  Unserialize(is, v[i]);
664  }
665 }
666 
667 template<typename Stream, unsigned int N, typename T>
668 inline void Unserialize(Stream& is, prevector<N, T>& v)
669 {
670  Unserialize_impl(is, v, T());
671 }
672 
673 
674 
678 template<typename Stream, typename T, typename A>
679 void Serialize_impl(Stream& os, const std::vector<T, A>& v, const unsigned char&)
680 {
681  WriteCompactSize(os, v.size());
682  if (!v.empty())
683  os.write((char*)v.data(), v.size() * sizeof(T));
684 }
685 
686 template<typename Stream, typename T, typename A, typename V>
687 void Serialize_impl(Stream& os, const std::vector<T, A>& v, const V&)
688 {
689  WriteCompactSize(os, v.size());
690  for (typename std::vector<T, A>::const_iterator vi = v.begin(); vi != v.end(); ++vi)
691  ::Serialize(os, (*vi));
692 }
693 
694 template<typename Stream, typename T, typename A>
695 inline void Serialize(Stream& os, const std::vector<T, A>& v)
696 {
697  Serialize_impl(os, v, T());
698 }
699 
700 
701 template<typename Stream, typename T, typename A>
702 void Unserialize_impl(Stream& is, std::vector<T, A>& v, const unsigned char&)
703 {
704  // Limit size per read so bogus size value won't cause out of memory
705  v.clear();
706  unsigned int nSize = ReadCompactSize(is);
707  unsigned int i = 0;
708  while (i < nSize)
709  {
710  unsigned int blk = std::min(nSize - i, (unsigned int)(1 + 4999999 / sizeof(T)));
711  v.resize(i + blk);
712  is.read((char*)&v[i], blk * sizeof(T));
713  i += blk;
714  }
715 }
716 
717 template<typename Stream, typename T, typename A, typename V>
718 void Unserialize_impl(Stream& is, std::vector<T, A>& v, const V&)
719 {
720  v.clear();
721  unsigned int nSize = ReadCompactSize(is);
722  unsigned int i = 0;
723  unsigned int nMid = 0;
724  while (nMid < nSize)
725  {
726  nMid += 5000000 / sizeof(T);
727  if (nMid > nSize)
728  nMid = nSize;
729  v.resize(nMid);
730  for (; i < nMid; i++)
731  Unserialize(is, v[i]);
732  }
733 }
734 
735 template<typename Stream, typename T, typename A>
736 inline void Unserialize(Stream& is, std::vector<T, A>& v)
737 {
738  Unserialize_impl(is, v, T());
739 }
740 
741 
742 
746 template<typename Stream, typename K, typename T>
747 void Serialize(Stream& os, const std::pair<K, T>& item)
748 {
749  Serialize(os, item.first);
750  Serialize(os, item.second);
751 }
752 
753 template<typename Stream, typename K, typename T>
754 void Unserialize(Stream& is, std::pair<K, T>& item)
755 {
756  Unserialize(is, item.first);
757  Unserialize(is, item.second);
758 }
759 
760 
761 
765 template<typename Stream, typename K, typename T, typename Pred, typename A>
766 void Serialize(Stream& os, const std::map<K, T, Pred, A>& m)
767 {
768  WriteCompactSize(os, m.size());
769  for (typename std::map<K, T, Pred, A>::const_iterator mi = m.begin(); mi != m.end(); ++mi)
770  Serialize(os, (*mi));
771 }
772 
773 template<typename Stream, typename K, typename T, typename Pred, typename A>
774 void Unserialize(Stream& is, std::map<K, T, Pred, A>& m)
775 {
776  m.clear();
777  unsigned int nSize = ReadCompactSize(is);
778  typename std::map<K, T, Pred, A>::iterator mi = m.begin();
779  for (unsigned int i = 0; i < nSize; i++)
780  {
781  std::pair<K, T> item;
782  Unserialize(is, item);
783  mi = m.insert(mi, item);
784  }
785 }
786 
787 
788 
792 template<typename Stream, typename K, typename Pred, typename A>
793 void Serialize(Stream& os, const std::set<K, Pred, A>& m)
794 {
795  WriteCompactSize(os, m.size());
796  for (typename std::set<K, Pred, A>::const_iterator it = m.begin(); it != m.end(); ++it)
797  Serialize(os, (*it));
798 }
799 
800 template<typename Stream, typename K, typename Pred, typename A>
801 void Unserialize(Stream& is, std::set<K, Pred, A>& m)
802 {
803  m.clear();
804  unsigned int nSize = ReadCompactSize(is);
805  typename std::set<K, Pred, A>::iterator it = m.begin();
806  for (unsigned int i = 0; i < nSize; i++)
807  {
808  K key;
809  Unserialize(is, key);
810  it = m.insert(it, key);
811  }
812 }
813 
814 
815 
819 template<typename Stream, typename T> void
820 Serialize(Stream& os, const std::unique_ptr<const T>& p)
821 {
822  Serialize(os, *p);
823 }
824 
825 template<typename Stream, typename T>
826 void Unserialize(Stream& is, std::unique_ptr<const T>& p)
827 {
828  p.reset(new T(deserialize, is));
829 }
830 
831 
832 
836 template<typename Stream, typename T> void
837 Serialize(Stream& os, const std::shared_ptr<const T>& p)
838 {
839  Serialize(os, *p);
840 }
841 
842 template<typename Stream, typename T>
843 void Unserialize(Stream& is, std::shared_ptr<const T>& p)
844 {
845  p = std::make_shared<const T>(deserialize, is);
846 }
847 
848 
849 
854 {
855  constexpr bool ForRead() const { return false; }
856 };
858 {
859  constexpr bool ForRead() const { return true; }
860 };
861 
862 template<typename Stream, typename T>
863 inline void SerReadWrite(Stream& s, const T& obj, CSerActionSerialize ser_action)
864 {
865  ::Serialize(s, obj);
866 }
867 
868 template<typename Stream, typename T>
869 inline void SerReadWrite(Stream& s, T& obj, CSerActionUnserialize ser_action)
870 {
871  ::Unserialize(s, obj);
872 }
873 
874 
875 
876 
877 
878 
879 
880 
881 
882 /* ::GetSerializeSize implementations
883  *
884  * Computing the serialized size of objects is done through a special stream
885  * object of type CSizeComputer, which only records the number of bytes written
886  * to it.
887  *
888  * If your Serialize or SerializationOp method has non-trivial overhead for
889  * serialization, it may be worthwhile to implement a specialized version for
890  * CSizeComputer, which uses the s.seek() method to record bytes that would
891  * be written instead.
892  */
894 {
895 protected:
896  size_t nSize;
897 
898  const int nType;
899  const int nVersion;
900 public:
901  CSizeComputer(int nTypeIn, int nVersionIn) : nSize(0), nType(nTypeIn), nVersion(nVersionIn) {}
902 
903  void write(const char *psz, size_t _nSize)
904  {
905  this->nSize += _nSize;
906  }
907 
909  void seek(size_t _nSize)
910  {
911  this->nSize += _nSize;
912  }
913 
914  template<typename T>
916  {
917  ::Serialize(*this, obj);
918  return (*this);
919  }
920 
921  size_t size() const {
922  return nSize;
923  }
924 
925  int GetVersion() const { return nVersion; }
926  int GetType() const { return nType; }
927 };
928 
929 template<typename Stream>
930 void SerializeMany(Stream& s)
931 {
932 }
933 
934 template<typename Stream, typename Arg>
935 void SerializeMany(Stream& s, Arg&& arg)
936 {
937  ::Serialize(s, std::forward<Arg>(arg));
938 }
939 
940 template<typename Stream, typename Arg, typename... Args>
941 void SerializeMany(Stream& s, Arg&& arg, Args&&... args)
942 {
943  ::Serialize(s, std::forward<Arg>(arg));
944  ::SerializeMany(s, std::forward<Args>(args)...);
945 }
946 
947 template<typename Stream>
948 inline void UnserializeMany(Stream& s)
949 {
950 }
951 
952 template<typename Stream, typename Arg>
953 inline void UnserializeMany(Stream& s, Arg& arg)
954 {
955  ::Unserialize(s, arg);
956 }
957 
958 template<typename Stream, typename Arg, typename... Args>
959 inline void UnserializeMany(Stream& s, Arg& arg, Args&... args)
960 {
961  ::Unserialize(s, arg);
962  ::UnserializeMany(s, args...);
963 }
964 
965 template<typename Stream, typename... Args>
966 inline void SerReadWriteMany(Stream& s, CSerActionSerialize ser_action, Args&&... args)
967 {
968  ::SerializeMany(s, std::forward<Args>(args)...);
969 }
970 
971 template<typename Stream, typename... Args>
972 inline void SerReadWriteMany(Stream& s, CSerActionUnserialize ser_action, Args&... args)
973 {
974  ::UnserializeMany(s, args...);
975 }
976 
977 template<typename I>
978 inline void WriteVarInt(CSizeComputer &s, I n)
979 {
980  s.seek(GetSizeOfVarInt<I>(n));
981 }
982 
983 inline void WriteCompactSize(CSizeComputer &s, uint64_t nSize)
984 {
985  s.seek(GetSizeOfCompactSize(nSize));
986 }
987 
988 template <typename T>
989 size_t GetSerializeSize(const T& t, int nType, int nVersion = 0)
990 {
991  return (CSizeComputer(nType, nVersion) << t).size();
992 }
993 
994 template <typename S, typename T>
995 size_t GetSerializeSize(const S& s, const T& t)
996 {
997  return (CSizeComputer(s.GetType(), s.GetVersion()) << t).size();
998 }
999 
1000 #endif // FABCOIN_SERIALIZE_H
uint32_t htobe32(uint32_t host_32bits)
Definition: endian.h:139
uint64_t ser_double_to_uint64(double x)
Definition: serialize.h:137
std::string & string
Definition: serialize.h:474
void resize(size_type new_size)
Definition: prevector.h:316
uint32_t ser_float_to_uint32(float x)
Definition: serialize.h:143
int GetType() const
Definition: serialize.h:926
I & n
Definition: serialize.h:437
uint8_t ser_readdata8(Stream &s)
Definition: serialize.h:96
void clear()
Definition: prevector.h:339
void ser_writedata64(Stream &s, uint64_t obj)
Definition: serialize.h:91
uint64_t & n
Definition: serialize.h:455
uint64_t ReadCompactSize(Stream &is)
Definition: serialize.h:273
void WriteVarInt(CSizeComputer &os, I n)
Definition: serialize.h:978
void WriteCompactSize(CSizeComputer &os, uint64_t nSize)
Definition: serialize.h:983
void Serialize(Stream &s) const
Definition: serialize.h:421
void Serialize(Stream &s) const
Definition: serialize.h:442
uint64_t htole64(uint64_t host_64bits)
Definition: endian.h:174
#define T(i, x)
size_t GetSerializeSize(const T &t, int nType, int nVersion=0)
Definition: serialize.h:989
void ser_writedata32(Stream &s, uint32_t obj)
Definition: serialize.h:77
constexpr deserialize_type deserialize
Definition: serialize.h:42
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:237
CCompactSize(uint64_t &nIn)
Definition: serialize.h:457
CSizeComputer(int nTypeIn, int nVersionIn)
Definition: serialize.h:901
void SerReadWriteMany(Stream &s, CSerActionSerialize ser_action, Args &&...args)
Definition: serialize.h:966
bool empty() const
Definition: prevector.h:286
char * end()
Definition: serialize.h:417
void Unserialize(Stream &s)
Definition: serialize.h:465
char * begin()
Definition: serialize.h:415
ExecStats::duration min
Definition: ExecStats.cpp:35
const int nVersion
Definition: serialize.h:899
void UnserializeMany(Stream &s)
Definition: serialize.h:948
int GetVersion() const
Definition: serialize.h:925
Dummy data type to identify deserializing constructors.
Definition: serialize.h:41
value_type * data()
Definition: prevector.h:507
void Serialize(Stream &s, char a)
Definition: serialize.h:198
void Unserialize(Stream &s)
Definition: serialize.h:447
I ReadVarInt(Stream &is)
Definition: serialize.h:368
size_type size() const
Definition: prevector.h:282
void Unserialize(Stream &s)
Definition: serialize.h:479
#define a(i)
CSizeComputer & operator<<(const T &obj)
Definition: serialize.h:915
uint32_t le32toh(uint32_t little_endian_32bits)
Definition: endian.h:160
iterator end()
Definition: prevector.h:292
#define x(i)
uint16_t ser_readdata16(Stream &s)
Definition: serialize.h:102
constexpr bool ForRead() const
Definition: serialize.h:859
const char * begin() const
Definition: serialize.h:416
uint32_t ser_readdata32(Stream &s)
Definition: serialize.h:108
const char * end() const
Definition: serialize.h:418
const int nType
Definition: serialize.h:898
ExecStats::duration max
Definition: ExecStats.cpp:36
void ser_writedata16(Stream &s, uint16_t obj)
Definition: serialize.h:72
uint256 ReadUint256(Stream &is)
Definition: serialize.h:305
void SerReadWrite(Stream &s, const T &obj, CSerActionSerialize ser_action)
Definition: serialize.h:863
void Unserialize(Stream &s)
Definition: serialize.h:427
uint64_t le64toh(uint64_t little_endian_64bits)
Definition: endian.h:188
CVarInt(I &nIn)
Definition: serialize.h:439
char * pend
Definition: serialize.h:400
void ser_writedata32be(Stream &s, uint32_t obj)
Definition: serialize.h:84
double ser_uint64_to_double(uint64_t y)
Definition: serialize.h:149
unsigned int GetSizeOfVarInt(I n)
Variable-length integers: bytes are a MSB base-128 encoding of the number.
Definition: serialize.h:335
Support for ADD_SERIALIZE_METHODS and READWRITE macro.
Definition: serialize.h:853
uint16_t le16toh(uint16_t little_endian_16bits)
Definition: endian.h:132
void SerializeMany(Stream &s)
Definition: serialize.h:930
Implements a drop-in replacement for std::vector<T> which stores up to N elements directly (without h...
Definition: prevector.h:36
uint64_t ser_readdata64(Stream &s)
Definition: serialize.h:131
void Serialize(Stream &s) const
Definition: serialize.h:491
CFlatData(void *pbeginIn, void *pendIn)
Definition: serialize.h:402
void seek(size_t _nSize)
Pretend _nSize bytes are written, without specifying them.
Definition: serialize.h:909
#define f(x)
Definition: gost.cpp:57
256-bit opaque blob.
Definition: uint256.h:132
size_t size() const
Definition: serialize.h:921
constexpr bool ForRead() const
Definition: serialize.h:855
void Serialize(Stream &s) const
Definition: serialize.h:460
uint8_t const size_t const size
Definition: sha3.h:20
#define I(x, y, z)
Definition: Hash.cpp:82
uint256 ser_readdata256(Stream &s)
Definition: serialize.h:122
CFlatData(prevector< N, T, S, D > &v)
Definition: serialize.h:410
void write(const char *psz, size_t _nSize)
Definition: serialize.h:903
uint32_t ser_readdata32be(Stream &s)
Definition: serialize.h:115
void Unserialize(Stream &s, char &a)
Definition: serialize.h:210
iterator begin()
Definition: prevector.h:290
uint16_t htole16(uint16_t host_16bits)
Definition: endian.h:118
uint32_t htole32(uint32_t host_32bits)
Definition: endian.h:146
char * pbegin
Definition: serialize.h:399
CFlatData(std::vector< T, TAl > &v)
Definition: serialize.h:404
#define S(a)
Definition: mars.cpp:50
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:611
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:59
void Unserialize_impl(Stream &is, prevector< N, T > &v, const unsigned char &)
Definition: serialize.h:634
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:49
uint8_t const * data
Definition: sha3.h:19
size_t nSize
Definition: serialize.h:896
LimitedString(std::string &_string)
Definition: serialize.h:476
CVarInt< I > WrapVarInt(I &n)
Definition: serialize.h:500
void ser_writedata8(Stream &s, uint8_t obj)
Definition: serialize.h:68
Wrapper for serializing arrays and POD.
Definition: serialize.h:396
float ser_uint32_to_float(uint32_t y)
Definition: serialize.h:155
uint32_t be32toh(uint32_t big_endian_32bits)
Definition: endian.h:153