Raven Core  3.0.0
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 // Copyright (c) 2017-2019 The Raven 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 RAVEN_SERIALIZE_H
8 #define RAVEN_SERIALIZE_H
9 
10 #include "compat/endian.h"
11 
12 #include <algorithm>
13 #include <assert.h>
14 #include <ios>
15 #include <limits>
16 #include <map>
17 #include <memory>
18 #include <set>
19 #include <stdint.h>
20 #include <string>
21 #include <string.h>
22 #include <utility>
23 #include <vector>
24 
25 #include "prevector.h"
26 
27 static const unsigned int MAX_SIZE = 0x02000000;
28 
40 struct deserialize_type {};
42 
47 template<typename T>
48 inline T& REF(const T& val)
49 {
50  return const_cast<T&>(val);
51 }
52 
57 template<typename T>
58 inline T* NCONST_PTR(const T* val)
59 {
60  return const_cast<T*>(val);
61 }
62 
63 /*
64  * Lowest-level serialization and conversion.
65  * @note Sizes of these types are verified in the tests
66  */
67 template<typename Stream> inline void ser_writedata8(Stream &s, uint8_t obj)
68 {
69  s.write((char*)&obj, 1);
70 }
71 template<typename Stream> inline void ser_writedata16(Stream &s, uint16_t obj)
72 {
73  obj = htole16(obj);
74  s.write((char*)&obj, 2);
75 }
76 template<typename Stream> inline void ser_writedata32(Stream &s, uint32_t obj)
77 {
78  obj = htole32(obj);
79  s.write((char*)&obj, 4);
80 }
81 template<typename Stream> inline void ser_writedata32be(Stream &s, uint32_t obj)
82 {
83  obj = htobe32(obj);
84  s.write((char*)&obj, 4);
85 }
86 template<typename Stream> inline void ser_writedata64(Stream &s, uint64_t obj)
87 {
88  obj = htole64(obj);
89  s.write((char*)&obj, 8);
90 }
91 template<typename Stream> inline uint8_t ser_readdata8(Stream &s)
92 {
93  uint8_t obj;
94  s.read((char*)&obj, 1);
95  return obj;
96 }
97 template<typename Stream> inline uint16_t ser_readdata16(Stream &s)
98 {
99  uint16_t obj;
100  s.read((char*)&obj, 2);
101  return le16toh(obj);
102 }
103 template<typename Stream> inline uint32_t ser_readdata32(Stream &s)
104 {
105  uint32_t obj;
106  s.read((char*)&obj, 4);
107  return le32toh(obj);
108 }
109 template<typename Stream> inline uint32_t ser_readdata32be(Stream &s)
110 {
111  uint32_t obj;
112  s.read((char*)&obj, 4);
113  return be32toh(obj);
114 }
115 template<typename Stream> inline uint64_t ser_readdata64(Stream &s)
116 {
117  uint64_t obj;
118  s.read((char*)&obj, 8);
119  return le64toh(obj);
120 }
121 inline uint64_t ser_double_to_uint64(double x)
122 {
123  union { double x; uint64_t y; } tmp;
124  tmp.x = x;
125  return tmp.y;
126 }
127 inline uint32_t ser_float_to_uint32(float x)
128 {
129  union { float x; uint32_t y; } tmp;
130  tmp.x = x;
131  return tmp.y;
132 }
133 inline double ser_uint64_to_double(uint64_t y)
134 {
135  union { double x; uint64_t y; } tmp;
136  tmp.y = y;
137  return tmp.x;
138 }
139 inline float ser_uint32_to_float(uint32_t y)
140 {
141  union { float x; uint32_t y; } tmp;
142  tmp.y = y;
143  return tmp.x;
144 }
145 
146 
148 //
149 // Templates for serializing to anything that looks like a stream,
150 // i.e. anything that supports .read(char*, size_t) and .write(char*, size_t)
151 //
152 
153 class CSizeComputer;
154 
155 enum
156 {
157  // primary actions
158  SER_NETWORK = (1 << 0),
159  SER_DISK = (1 << 1),
160  SER_GETHASH = (1 << 2),
161 };
162 
163 #define READWRITE(obj) (::SerReadWrite(s, (obj), ser_action))
164 #define READWRITEMANY(...) (::SerReadWriteMany(s, ser_action, __VA_ARGS__))
165 
172 #define ADD_SERIALIZE_METHODS \
173  template<typename Stream> \
174  void Serialize(Stream& s) const { \
175  NCONST_PTR(this)->SerializationOp(s, CSerActionSerialize()); \
176  } \
177  template<typename Stream> \
178  void Unserialize(Stream& s) { \
179  SerializationOp(s, CSerActionUnserialize()); \
180  }
181 
182 template<typename Stream> inline void Serialize(Stream& s, char a ) { ser_writedata8(s, a); } // TODO Get rid of bare char
183 template<typename Stream> inline void Serialize(Stream& s, int8_t a ) { ser_writedata8(s, a); }
184 template<typename Stream> inline void Serialize(Stream& s, uint8_t a ) { ser_writedata8(s, a); }
185 template<typename Stream> inline void Serialize(Stream& s, int16_t a ) { ser_writedata16(s, a); }
186 template<typename Stream> inline void Serialize(Stream& s, uint16_t a) { ser_writedata16(s, a); }
187 template<typename Stream> inline void Serialize(Stream& s, int32_t a ) { ser_writedata32(s, a); }
188 template<typename Stream> inline void Serialize(Stream& s, uint32_t a) { ser_writedata32(s, a); }
189 template<typename Stream> inline void Serialize(Stream& s, int64_t a ) { ser_writedata64(s, a); }
190 template<typename Stream> inline void Serialize(Stream& s, uint64_t a) { ser_writedata64(s, a); }
191 template<typename Stream> inline void Serialize(Stream& s, float a ) { ser_writedata32(s, ser_float_to_uint32(a)); }
192 template<typename Stream> inline void Serialize(Stream& s, double a ) { ser_writedata64(s, ser_double_to_uint64(a)); }
193 
194 template<typename Stream> inline void Unserialize(Stream& s, char& a ) { a = ser_readdata8(s); } // TODO Get rid of bare char
195 template<typename Stream> inline void Unserialize(Stream& s, int8_t& a ) { a = ser_readdata8(s); }
196 template<typename Stream> inline void Unserialize(Stream& s, uint8_t& a ) { a = ser_readdata8(s); }
197 template<typename Stream> inline void Unserialize(Stream& s, int16_t& a ) { a = ser_readdata16(s); }
198 template<typename Stream> inline void Unserialize(Stream& s, uint16_t& a) { a = ser_readdata16(s); }
199 template<typename Stream> inline void Unserialize(Stream& s, int32_t& a ) { a = ser_readdata32(s); }
200 template<typename Stream> inline void Unserialize(Stream& s, uint32_t& a) { a = ser_readdata32(s); }
201 template<typename Stream> inline void Unserialize(Stream& s, int64_t& a ) { a = ser_readdata64(s); }
202 template<typename Stream> inline void Unserialize(Stream& s, uint64_t& a) { a = ser_readdata64(s); }
203 template<typename Stream> inline void Unserialize(Stream& s, float& a ) { a = ser_uint32_to_float(ser_readdata32(s)); }
204 template<typename Stream> inline void Unserialize(Stream& s, double& a ) { a = ser_uint64_to_double(ser_readdata64(s)); }
205 
206 template<typename Stream> inline void Serialize(Stream& s, bool a) { char f=a; ser_writedata8(s, f); }
207 template<typename Stream> inline void Unserialize(Stream& s, bool& a) { char f=ser_readdata8(s); a=f; }
208 
209 
210 
211 
212 
213 
221 inline unsigned int GetSizeOfCompactSize(uint64_t nSize)
222 {
223  if (nSize < 253) return sizeof(unsigned char);
224  else if (nSize <= std::numeric_limits<unsigned short>::max()) return sizeof(unsigned char) + sizeof(unsigned short);
225  else if (nSize <= std::numeric_limits<unsigned int>::max()) return sizeof(unsigned char) + sizeof(unsigned int);
226  else return sizeof(unsigned char) + sizeof(uint64_t);
227 }
228 
229 inline void WriteCompactSize(CSizeComputer& os, uint64_t nSize);
230 
231 template<typename Stream>
232 void WriteCompactSize(Stream& os, uint64_t nSize)
233 {
234  if (nSize < 253)
235  {
236  ser_writedata8(os, nSize);
237  }
238  else if (nSize <= std::numeric_limits<unsigned short>::max())
239  {
240  ser_writedata8(os, 253);
241  ser_writedata16(os, nSize);
242  }
243  else if (nSize <= std::numeric_limits<unsigned int>::max())
244  {
245  ser_writedata8(os, 254);
246  ser_writedata32(os, nSize);
247  }
248  else
249  {
250  ser_writedata8(os, 255);
251  ser_writedata64(os, nSize);
252  }
253  return;
254 }
255 
256 template<typename Stream>
257 uint64_t ReadCompactSize(Stream& is)
258 {
259  uint8_t chSize = ser_readdata8(is);
260  uint64_t nSizeRet = 0;
261  if (chSize < 253)
262  {
263  nSizeRet = chSize;
264  }
265  else if (chSize == 253)
266  {
267  nSizeRet = ser_readdata16(is);
268  if (nSizeRet < 253)
269  throw std::ios_base::failure("non-canonical ReadCompactSize()");
270  }
271  else if (chSize == 254)
272  {
273  nSizeRet = ser_readdata32(is);
274  if (nSizeRet < 0x10000u)
275  throw std::ios_base::failure("non-canonical ReadCompactSize()");
276  }
277  else
278  {
279  nSizeRet = ser_readdata64(is);
280  if (nSizeRet < 0x100000000ULL)
281  throw std::ios_base::failure("non-canonical ReadCompactSize()");
282  }
283  if (nSizeRet > (uint64_t)MAX_SIZE)
284  throw std::ios_base::failure("ReadCompactSize(): size too large");
285  return nSizeRet;
286 }
287 
312 template<typename I>
313 inline unsigned int GetSizeOfVarInt(I n)
314 {
315  int nRet = 0;
316  while(true) {
317  nRet++;
318  if (n <= 0x7F)
319  break;
320  n = (n >> 7) - 1;
321  }
322  return nRet;
323 }
324 
325 template<typename I>
326 inline void WriteVarInt(CSizeComputer& os, I n);
327 
328 template<typename Stream, typename I>
329 void WriteVarInt(Stream& os, I n)
330 {
331  unsigned char tmp[(sizeof(n)*8+6)/7];
332  int len=0;
333  while(true) {
334  tmp[len] = (n & 0x7F) | (len ? 0x80 : 0x00);
335  if (n <= 0x7F)
336  break;
337  n = (n >> 7) - 1;
338  len++;
339  }
340  do {
341  ser_writedata8(os, tmp[len]);
342  } while(len--);
343 }
344 
345 template<typename Stream, typename I>
346 I ReadVarInt(Stream& is)
347 {
348  I n = 0;
349  while(true) {
350  unsigned char chData = ser_readdata8(is);
351  if (n > (std::numeric_limits<I>::max() >> 7)) {
352  throw std::ios_base::failure("ReadVarInt(): size too large");
353  }
354  n = (n << 7) | (chData & 0x7F);
355  if (chData & 0x80) {
356  if (n == std::numeric_limits<I>::max()) {
357  throw std::ios_base::failure("ReadVarInt(): size too large");
358  }
359  n++;
360  } else {
361  return n;
362  }
363  }
364 }
365 
366 #define FLATDATA(obj) REF(CFlatData((char*)&(obj), (char*)&(obj) + sizeof(obj)))
367 #define VARINT(obj) REF(WrapVarInt(REF(obj)))
368 #define COMPACTSIZE(obj) REF(CCompactSize(REF(obj)))
369 #define LIMITED_STRING(obj,n) REF(LimitedString< n >(REF(obj)))
370 
375 {
376 protected:
377  char* pbegin;
378  char* pend;
379 public:
380  CFlatData(void* pbeginIn, void* pendIn) : pbegin((char*)pbeginIn), pend((char*)pendIn) { }
381  template <class T, class TAl>
382  explicit CFlatData(std::vector<T,TAl> &v)
383  {
384  pbegin = (char*)v.data();
385  pend = (char*)(v.data() + v.size());
386  }
387  template <unsigned int N, typename T, typename S, typename D>
389  {
390  pbegin = (char*)v.data();
391  pend = (char*)(v.data() + v.size());
392  }
393  char* begin() { return pbegin; }
394  const char* begin() const { return pbegin; }
395  char* end() { return pend; }
396  const char* end() const { return pend; }
397 
398  template<typename Stream>
399  void Serialize(Stream& s) const
400  {
401  s.write(pbegin, pend - pbegin);
402  }
403 
404  template<typename Stream>
405  void Unserialize(Stream& s)
406  {
407  s.read(pbegin, pend - pbegin);
408  }
409 };
410 
411 template<typename I>
412 class CVarInt
413 {
414 protected:
415  I &n;
416 public:
417  explicit CVarInt(I& nIn) : n(nIn) { }
418 
419  template<typename Stream>
420  void Serialize(Stream &s) const {
421  WriteVarInt<Stream,I>(s, n);
422  }
423 
424  template<typename Stream>
425  void Unserialize(Stream& s) {
426  n = ReadVarInt<Stream,I>(s);
427  }
428 };
429 
431 {
432 protected:
433  uint64_t &n;
434 public:
435  explicit CCompactSize(uint64_t& nIn) : n(nIn) { }
436 
437  template<typename Stream>
438  void Serialize(Stream &s) const {
439  WriteCompactSize<Stream>(s, n);
440  }
441 
442  template<typename Stream>
443  void Unserialize(Stream& s) {
444  n = ReadCompactSize<Stream>(s);
445  }
446 };
447 
448 template<size_t Limit>
450 {
451 protected:
452  std::string& string;
453 public:
454  explicit LimitedString(std::string& _string) : string(_string) {}
455 
456  template<typename Stream>
457  void Unserialize(Stream& s)
458  {
459  size_t size = ReadCompactSize(s);
460  if (size > Limit) {
461  throw std::ios_base::failure("String length limit exceeded");
462  }
463  string.resize(size);
464  if (size != 0)
465  s.read((char*)string.data(), size);
466  }
467 
468  template<typename Stream>
469  void Serialize(Stream& s) const
470  {
471  WriteCompactSize(s, string.size());
472  if (!string.empty())
473  s.write((char*)string.data(), string.size());
474  }
475 };
476 
477 template<typename I>
478 CVarInt<I> WrapVarInt(I& n) { return CVarInt<I>(n); }
479 
487 template<typename Stream, typename C> void Serialize(Stream& os, const std::basic_string<C>& str);
488 template<typename Stream, typename C> void Unserialize(Stream& is, std::basic_string<C>& str);
489 
494 template<typename Stream, unsigned int N, typename T> void Serialize_impl(Stream& os, const prevector<N, T>& v, const unsigned char&);
495 template<typename Stream, unsigned int N, typename T, typename V> void Serialize_impl(Stream& os, const prevector<N, T>& v, const V&);
496 template<typename Stream, unsigned int N, typename T> inline void Serialize(Stream& os, const prevector<N, T>& v);
497 template<typename Stream, unsigned int N, typename T> void Unserialize_impl(Stream& is, prevector<N, T>& v, const unsigned char&);
498 template<typename Stream, unsigned int N, typename T, typename V> void Unserialize_impl(Stream& is, prevector<N, T>& v, const V&);
499 template<typename Stream, unsigned int N, typename T> inline void Unserialize(Stream& is, prevector<N, T>& v);
500 
505 template<typename Stream, typename T, typename A> void Serialize_impl(Stream& os, const std::vector<T, A>& v, const unsigned char&);
506 template<typename Stream, typename T, typename A, typename V> void Serialize_impl(Stream& os, const std::vector<T, A>& v, const V&);
507 template<typename Stream, typename T, typename A> inline void Serialize(Stream& os, const std::vector<T, A>& v);
508 template<typename Stream, typename T, typename A> void Unserialize_impl(Stream& is, std::vector<T, A>& v, const unsigned char&);
509 template<typename Stream, typename T, typename A, typename V> void Unserialize_impl(Stream& is, std::vector<T, A>& v, const V&);
510 template<typename Stream, typename T, typename A> inline void Unserialize(Stream& is, std::vector<T, A>& v);
511 
515 template<typename Stream, typename K, typename T> void Serialize(Stream& os, const std::pair<K, T>& item);
516 template<typename Stream, typename K, typename T> void Unserialize(Stream& is, std::pair<K, T>& item);
517 
521 template<typename Stream, typename K, typename T, typename Pred, typename A> void Serialize(Stream& os, const std::map<K, T, Pred, A>& m);
522 template<typename Stream, typename K, typename T, typename Pred, typename A> void Unserialize(Stream& is, std::map<K, T, Pred, A>& m);
523 
527 template<typename Stream, typename K, typename Pred, typename A> void Serialize(Stream& os, const std::set<K, Pred, A>& m);
528 template<typename Stream, typename K, typename Pred, typename A> void Unserialize(Stream& is, std::set<K, Pred, A>& m);
529 
533 template<typename Stream, typename T> void Serialize(Stream& os, const std::shared_ptr<const T>& p);
534 template<typename Stream, typename T> void Unserialize(Stream& os, std::shared_ptr<const T>& p);
535 
539 template<typename Stream, typename T> void Serialize(Stream& os, const std::unique_ptr<const T>& p);
540 template<typename Stream, typename T> void Unserialize(Stream& os, std::unique_ptr<const T>& p);
541 
542 
543 
547 template<typename Stream, typename T>
548 inline void Serialize(Stream& os, const T& a)
549 {
550  a.Serialize(os);
551 }
552 
553 template<typename Stream, typename T>
554 inline void Unserialize(Stream& is, T& a)
555 {
556  a.Unserialize(is);
557 }
558 
559 
560 
561 
562 
566 template<typename Stream, typename C>
567 void Serialize(Stream& os, const std::basic_string<C>& str)
568 {
569  WriteCompactSize(os, str.size());
570  if (!str.empty())
571  os.write((char*)str.data(), str.size() * sizeof(C));
572 }
573 
574 template<typename Stream, typename C>
575 void Unserialize(Stream& is, std::basic_string<C>& str)
576 {
577  unsigned int nSize = ReadCompactSize(is);
578  str.resize(nSize);
579  if (nSize != 0)
580  is.read((char*)str.data(), nSize * sizeof(C));
581 }
582 
583 
584 
588 template<typename Stream, unsigned int N, typename T>
589 void Serialize_impl(Stream& os, const prevector<N, T>& v, const unsigned char&)
590 {
591  WriteCompactSize(os, v.size());
592  if (!v.empty())
593  os.write((char*)v.data(), v.size() * sizeof(T));
594 }
595 
596 template<typename Stream, unsigned int N, typename T, typename V>
597 void Serialize_impl(Stream& os, const prevector<N, T>& v, const V&)
598 {
599  WriteCompactSize(os, v.size());
600  for (typename prevector<N, T>::const_iterator vi = v.begin(); vi != v.end(); ++vi)
601  ::Serialize(os, (*vi));
602 }
603 
604 template<typename Stream, unsigned int N, typename T>
605 inline void Serialize(Stream& os, const prevector<N, T>& v)
606 {
607  Serialize_impl(os, v, T());
608 }
609 
610 
611 template<typename Stream, unsigned int N, typename T>
612 void Unserialize_impl(Stream& is, prevector<N, T>& v, const unsigned char&)
613 {
614  // Limit size per read so bogus size value won't cause out of memory
615  v.clear();
616  unsigned int nSize = ReadCompactSize(is);
617  unsigned int i = 0;
618  while (i < nSize)
619  {
620  unsigned int blk = std::min(nSize - i, (unsigned int)(1 + 4999999 / sizeof(T)));
621  v.resize(i + blk);
622  is.read((char*)&v[i], blk * sizeof(T));
623  i += blk;
624  }
625 }
626 
627 template<typename Stream, unsigned int N, typename T, typename V>
628 void Unserialize_impl(Stream& is, prevector<N, T>& v, const V&)
629 {
630  v.clear();
631  unsigned int nSize = ReadCompactSize(is);
632  unsigned int i = 0;
633  unsigned int nMid = 0;
634  while (nMid < nSize)
635  {
636  nMid += 5000000 / sizeof(T);
637  if (nMid > nSize)
638  nMid = nSize;
639  v.resize(nMid);
640  for (; i < nMid; i++)
641  Unserialize(is, v[i]);
642  }
643 }
644 
645 template<typename Stream, unsigned int N, typename T>
646 inline void Unserialize(Stream& is, prevector<N, T>& v)
647 {
648  Unserialize_impl(is, v, T());
649 }
650 
651 
652 
656 template<typename Stream, typename T, typename A>
657 void Serialize_impl(Stream& os, const std::vector<T, A>& v, const unsigned char&)
658 {
659  WriteCompactSize(os, v.size());
660  if (!v.empty())
661  os.write((char*)v.data(), v.size() * sizeof(T));
662 }
663 
664 template<typename Stream, typename T, typename A, typename V>
665 void Serialize_impl(Stream& os, const std::vector<T, A>& v, const V&)
666 {
667  WriteCompactSize(os, v.size());
668  for (typename std::vector<T, A>::const_iterator vi = v.begin(); vi != v.end(); ++vi)
669  ::Serialize(os, (*vi));
670 }
671 
672 template<typename Stream, typename T, typename A>
673 inline void Serialize(Stream& os, const std::vector<T, A>& v)
674 {
675  Serialize_impl(os, v, T());
676 }
677 
678 
679 template<typename Stream, typename T, typename A>
680 void Unserialize_impl(Stream& is, std::vector<T, A>& v, const unsigned char&)
681 {
682  // Limit size per read so bogus size value won't cause out of memory
683  v.clear();
684  unsigned int nSize = ReadCompactSize(is);
685  unsigned int i = 0;
686  while (i < nSize)
687  {
688  unsigned int blk = std::min(nSize - i, (unsigned int)(1 + 4999999 / sizeof(T)));
689  v.resize(i + blk);
690  is.read((char*)&v[i], blk * sizeof(T));
691  i += blk;
692  }
693 }
694 
695 template<typename Stream, typename T, typename A, typename V>
696 void Unserialize_impl(Stream& is, std::vector<T, A>& v, const V&)
697 {
698  v.clear();
699  unsigned int nSize = ReadCompactSize(is);
700  unsigned int i = 0;
701  unsigned int nMid = 0;
702  while (nMid < nSize)
703  {
704  nMid += 5000000 / sizeof(T);
705  if (nMid > nSize)
706  nMid = nSize;
707  v.resize(nMid);
708  for (; i < nMid; i++)
709  Unserialize(is, v[i]);
710  }
711 }
712 
713 template<typename Stream, typename T, typename A>
714 inline void Unserialize(Stream& is, std::vector<T, A>& v)
715 {
716  Unserialize_impl(is, v, T());
717 }
718 
719 
720 
724 template<typename Stream, typename K, typename T>
725 void Serialize(Stream& os, const std::pair<K, T>& item)
726 {
727  Serialize(os, item.first);
728  Serialize(os, item.second);
729 }
730 
731 template<typename Stream, typename K, typename T>
732 void Unserialize(Stream& is, std::pair<K, T>& item)
733 {
734  Unserialize(is, item.first);
735  Unserialize(is, item.second);
736 }
737 
738 
739 
743 template<typename Stream, typename K, typename T, typename Pred, typename A>
744 void Serialize(Stream& os, const std::map<K, T, Pred, A>& m)
745 {
746  WriteCompactSize(os, m.size());
747  for (typename std::map<K, T, Pred, A>::const_iterator mi = m.begin(); mi != m.end(); ++mi)
748  Serialize(os, (*mi));
749 }
750 
751 template<typename Stream, typename K, typename T, typename Pred, typename A>
752 void Unserialize(Stream& is, std::map<K, T, Pred, A>& m)
753 {
754  m.clear();
755  unsigned int nSize = ReadCompactSize(is);
756  typename std::map<K, T, Pred, A>::iterator mi = m.begin();
757  for (unsigned int i = 0; i < nSize; i++)
758  {
759  std::pair<K, T> item;
760  Unserialize(is, item);
761  mi = m.insert(mi, item);
762  }
763 }
764 
765 
766 
770 template<typename Stream, typename K, typename Pred, typename A>
771 void Serialize(Stream& os, const std::set<K, Pred, A>& m)
772 {
773  WriteCompactSize(os, m.size());
774  for (typename std::set<K, Pred, A>::const_iterator it = m.begin(); it != m.end(); ++it)
775  Serialize(os, (*it));
776 }
777 
778 template<typename Stream, typename K, typename Pred, typename A>
779 void Unserialize(Stream& is, std::set<K, Pred, A>& m)
780 {
781  m.clear();
782  unsigned int nSize = ReadCompactSize(is);
783  typename std::set<K, Pred, A>::iterator it = m.begin();
784  for (unsigned int i = 0; i < nSize; i++)
785  {
786  K key;
787  Unserialize(is, key);
788  it = m.insert(it, key);
789  }
790 }
791 
792 
793 
797 template<typename Stream, typename T> void
798 Serialize(Stream& os, const std::unique_ptr<const T>& p)
799 {
800  Serialize(os, *p);
801 }
802 
803 template<typename Stream, typename T>
804 void Unserialize(Stream& is, std::unique_ptr<const T>& p)
805 {
806  p.reset(new T(deserialize, is));
807 }
808 
809 
810 
814 template<typename Stream, typename T> void
815 Serialize(Stream& os, const std::shared_ptr<const T>& p)
816 {
817  Serialize(os, *p);
818 }
819 
820 template<typename Stream, typename T>
821 void Unserialize(Stream& is, std::shared_ptr<const T>& p)
822 {
823  p = std::make_shared<const T>(deserialize, is);
824 }
825 
826 
827 
832 {
833  constexpr bool ForRead() const { return false; }
834 };
836 {
837  constexpr bool ForRead() const { return true; }
838 };
839 
840 template<typename Stream, typename T>
841 inline void SerReadWrite(Stream& s, const T& obj, CSerActionSerialize ser_action)
842 {
843  ::Serialize(s, obj);
844 }
845 
846 template<typename Stream, typename T>
847 inline void SerReadWrite(Stream& s, T& obj, CSerActionUnserialize ser_action)
848 {
849  ::Unserialize(s, obj);
850 }
851 
852 
853 
854 
855 
856 
857 
858 
859 
860 /* ::GetSerializeSize implementations
861  *
862  * Computing the serialized size of objects is done through a special stream
863  * object of type CSizeComputer, which only records the number of bytes written
864  * to it.
865  *
866  * If your Serialize or SerializationOp method has non-trivial overhead for
867  * serialization, it may be worthwhile to implement a specialized version for
868  * CSizeComputer, which uses the s.seek() method to record bytes that would
869  * be written instead.
870  */
872 {
873 protected:
874  size_t nSize;
875 
876  const int nType;
877  const int nVersion;
878 public:
879  CSizeComputer(int nTypeIn, int nVersionIn) : nSize(0), nType(nTypeIn), nVersion(nVersionIn) {}
880 
881  void write(const char *psz, size_t _nSize)
882  {
883  this->nSize += _nSize;
884  }
885 
887  void seek(size_t _nSize)
888  {
889  this->nSize += _nSize;
890  }
891 
892  template<typename T>
893  CSizeComputer& operator<<(const T& obj)
894  {
895  ::Serialize(*this, obj);
896  return (*this);
897  }
898 
899  size_t size() const {
900  return nSize;
901  }
902 
903  int GetVersion() const { return nVersion; }
904  int GetType() const { return nType; }
905 };
906 
907 template<typename Stream>
908 void SerializeMany(Stream& s)
909 {
910 }
911 
912 template<typename Stream, typename Arg>
913 void SerializeMany(Stream& s, Arg&& arg)
914 {
915  ::Serialize(s, std::forward<Arg>(arg));
916 }
917 
918 template<typename Stream, typename Arg, typename... Args>
919 void SerializeMany(Stream& s, Arg&& arg, Args&&... args)
920 {
921  ::Serialize(s, std::forward<Arg>(arg));
922  ::SerializeMany(s, std::forward<Args>(args)...);
923 }
924 
925 template<typename Stream>
926 inline void UnserializeMany(Stream& s)
927 {
928 }
929 
930 template<typename Stream, typename Arg>
931 inline void UnserializeMany(Stream& s, Arg& arg)
932 {
933  ::Unserialize(s, arg);
934 }
935 
936 template<typename Stream, typename Arg, typename... Args>
937 inline void UnserializeMany(Stream& s, Arg& arg, Args&... args)
938 {
939  ::Unserialize(s, arg);
940  ::UnserializeMany(s, args...);
941 }
942 
943 template<typename Stream, typename... Args>
944 inline void SerReadWriteMany(Stream& s, CSerActionSerialize ser_action, Args&&... args)
945 {
946  ::SerializeMany(s, std::forward<Args>(args)...);
947 }
948 
949 template<typename Stream, typename... Args>
950 inline void SerReadWriteMany(Stream& s, CSerActionUnserialize ser_action, Args&... args)
951 {
952  ::UnserializeMany(s, args...);
953 }
954 
955 template<typename I>
956 inline void WriteVarInt(CSizeComputer &s, I n)
957 {
958  s.seek(GetSizeOfVarInt<I>(n));
959 }
960 
961 inline void WriteCompactSize(CSizeComputer &s, uint64_t nSize)
962 {
963  s.seek(GetSizeOfCompactSize(nSize));
964 }
965 
966 template <typename T>
967 size_t GetSerializeSize(const T& t, int nType, int nVersion = 0)
968 {
969  return (CSizeComputer(nType, nVersion) << t).size();
970 }
971 
972 template <typename S, typename T>
973 size_t GetSerializeSize(const S& s, const T& t)
974 {
975  return (CSizeComputer(s.GetType(), s.GetVersion()) << t).size();
976 }
977 
978 #endif // RAVEN_SERIALIZE_H
uint64_t ser_double_to_uint64(double x)
Definition: serialize.h:121
std::string & string
Definition: serialize.h:452
void resize(size_type new_size)
Definition: prevector.h:317
uint32_t ser_float_to_uint32(float x)
Definition: serialize.h:127
I & n
Definition: serialize.h:415
void Serialize(Stream &s) const
Definition: serialize.h:399
uint8_t ser_readdata8(Stream &s)
Definition: serialize.h:91
void clear()
Definition: prevector.h:340
void ser_writedata64(Stream &s, uint64_t obj)
Definition: serialize.h:86
uint64_t & n
Definition: serialize.h:433
uint64_t ReadCompactSize(Stream &is)
Definition: serialize.h:257
void WriteVarInt(CSizeComputer &os, I n)
Definition: serialize.h:956
void WriteCompactSize(CSizeComputer &os, uint64_t nSize)
Definition: serialize.h:961
void SerReadWriteMany(Stream &s, CSerActionSerialize ser_action, Args &&... args)
Definition: serialize.h:944
size_t GetSerializeSize(const T &t, int nType, int nVersion=0)
Definition: serialize.h:967
size_t size() const
Definition: serialize.h:899
void ser_writedata32(Stream &s, uint32_t obj)
Definition: serialize.h:76
constexpr deserialize_type deserialize
Definition: serialize.h:41
unsigned int GetSizeOfCompactSize(uint64_t nSize)
Compact Size size < 253 – 1 byte size <= USHRT_MAX – 3 bytes (253 + 2 bytes) size <= UINT_MAX – 5 ...
Definition: serialize.h:221
CCompactSize(uint64_t &nIn)
Definition: serialize.h:435
CSizeComputer(int nTypeIn, int nVersionIn)
Definition: serialize.h:879
char * end()
Definition: serialize.h:395
void Unserialize(Stream &s)
Definition: serialize.h:443
uint32_t be32toh(uint32_t big_endian_32bits)
Definition: endian.h:154
const char * end() const
Definition: serialize.h:396
char * begin()
Definition: serialize.h:393
const int nVersion
Definition: serialize.h:877
void UnserializeMany(Stream &s)
Definition: serialize.h:926
uint32_t htole32(uint32_t host_32bits)
Definition: endian.h:147
Dummy data type to identify deserializing constructors.
Definition: serialize.h:40
void Serialize(Stream &s) const
Definition: serialize.h:420
value_type * data()
Definition: prevector.h:508
void Serialize(Stream &s, char a)
Definition: serialize.h:182
uint32_t htobe32(uint32_t host_32bits)
Definition: endian.h:140
void Unserialize(Stream &s)
Definition: serialize.h:425
I ReadVarInt(Stream &is)
Definition: serialize.h:346
void Unserialize(Stream &s)
Definition: serialize.h:457
CSizeComputer & operator<<(const T &obj)
Definition: serialize.h:893
iterator end()
Definition: prevector.h:293
void Serialize(Stream &s) const
Definition: serialize.h:469
uint16_t ser_readdata16(Stream &s)
Definition: serialize.h:97
uint32_t ser_readdata32(Stream &s)
Definition: serialize.h:103
void Serialize(Stream &s) const
Definition: serialize.h:438
const int nType
Definition: serialize.h:876
void ser_writedata16(Stream &s, uint16_t obj)
Definition: serialize.h:71
void SerReadWrite(Stream &s, const T &obj, CSerActionSerialize ser_action)
Definition: serialize.h:841
void Unserialize(Stream &s)
Definition: serialize.h:405
#define S(x0, x1, x2, x3, cb, r)
Definition: jh.c:494
CVarInt(I &nIn)
Definition: serialize.h:417
constexpr bool ForRead() const
Definition: serialize.h:837
char * pend
Definition: serialize.h:378
int GetType() const
Definition: serialize.h:904
uint16_t le16toh(uint16_t little_endian_16bits)
Definition: endian.h:133
void ser_writedata32be(Stream &s, uint32_t obj)
Definition: serialize.h:81
double ser_uint64_to_double(uint64_t y)
Definition: serialize.h:133
unsigned int GetSizeOfVarInt(I n)
Variable-length integers: bytes are a MSB base-128 encoding of the number.
Definition: serialize.h:313
Support for ADD_SERIALIZE_METHODS and READWRITE macro.
Definition: serialize.h:831
constexpr bool ForRead() const
Definition: serialize.h:833
void SerializeMany(Stream &s)
Definition: serialize.h:908
Implements a drop-in replacement for std::vector<T> which stores up to N elements directly (without h...
Definition: prevector.h:37
uint64_t ser_readdata64(Stream &s)
Definition: serialize.h:115
const char * begin() const
Definition: serialize.h:394
CFlatData(void *pbeginIn, void *pendIn)
Definition: serialize.h:380
void seek(size_t _nSize)
Pretend _nSize bytes are written, without specifying them.
Definition: serialize.h:887
uint16_t htole16(uint16_t host_16bits)
Definition: endian.h:119
uint64_t le64toh(uint64_t little_endian_64bits)
Definition: endian.h:189
int GetVersion() const
Definition: serialize.h:903
CFlatData(prevector< N, T, S, D > &v)
Definition: serialize.h:388
bool empty() const
Definition: prevector.h:287
uint64_t htole64(uint64_t host_64bits)
Definition: endian.h:175
void write(const char *psz, size_t _nSize)
Definition: serialize.h:881
uint32_t ser_readdata32be(Stream &s)
Definition: serialize.h:109
void Unserialize(Stream &s, char &a)
Definition: serialize.h:194
iterator begin()
Definition: prevector.h:291
size_type size() const
Definition: prevector.h:283
char * pbegin
Definition: serialize.h:377
CFlatData(std::vector< T, TAl > &v)
Definition: serialize.h:382
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:589
T * NCONST_PTR(const T *val)
Used to acquire a non-const pointer "this" to generate bodies of const serialization operations from ...
Definition: serialize.h:58
void Unserialize_impl(Stream &is, prevector< N, T > &v, const unsigned char &)
Definition: serialize.h:612
uint32_t le32toh(uint32_t little_endian_32bits)
Definition: endian.h:161
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:48
size_t nSize
Definition: serialize.h:874
LimitedString(std::string &_string)
Definition: serialize.h:454
CVarInt< I > WrapVarInt(I &n)
Definition: serialize.h:478
void ser_writedata8(Stream &s, uint8_t obj)
Definition: serialize.h:67
Wrapper for serializing arrays and POD.
Definition: serialize.h:374
float ser_uint32_to_float(uint32_t y)
Definition: serialize.h:139