hdac SDK
SDK for hdac blockchain development
serialize.h
1 #ifndef SERIALIZE_H
2 #define SERIALIZE_H
3 
4 #include <limits>
5 #include <ios>
6 #include <set>
7 #include <vector>
8 
9 class CScript;
10 
11 // TODO : make MAX_SIZE changed from extern
12 //#ifndef MAX_SIZE
13 //#define MAX_SIZE 0x02000000
14 //unsigned int MAX_SIZE = 0x02000000;
15 //#endif
16 static uint64_t MAX_SIZE = 0x02000000;
17 
18 // TODO : how to manage protoco version
19 static const int PROTOCOL_VERSION = 70002;
20 
25 template<typename T>
26 inline T& REF(const T& val)
27 {
28  return const_cast<T&>(val);
29 }
30 
35 template<typename T>
36 inline T* NCONST_PTR(const T* val)
37 {
38  return const_cast<T*>(val);
39 }
40 
46 template <class T, class TAl>
47 inline T* begin_ptr(std::vector<T,TAl>& v)
48 {
49  return v.empty() ? NULL : &v[0];
50 }
52 template <class T, class TAl>
53 inline const T* begin_ptr(const std::vector<T,TAl>& v)
54 {
55  return v.empty() ? NULL : &v[0];
56 }
58 template <class T, class TAl>
59 inline T* end_ptr(std::vector<T,TAl>& v)
60 {
61  return v.empty() ? NULL : (&v[0] + v.size());
62 }
64 template <class T, class TAl>
65 inline const T* end_ptr(const std::vector<T,TAl>& v)
66 {
67  return v.empty() ? NULL : (&v[0] + v.size());
68 }
69 
71 //
72 // Templates for serializing to anything that looks like a stream,
73 // i.e. anything that supports .read(char*, size_t) and .write(char*, size_t)
74 //
75 
76 enum
77 {
78  // primary actions
79  SER_NETWORK = (1 << 0),
80  SER_DISK = (1 << 1),
81  SER_GETHASH = (1 << 2),
82 };
83 
84 #define READWRITE(obj) (::SerReadWrite(s, (obj), nType, nVersion, ser_action))
85 
92 #define ADD_SERIALIZE_METHODS \
93  size_t GetSerializeSize(int nType, int nVersion) const { \
94  CSizeComputer s(nType, nVersion); \
95  NCONST_PTR(this)->SerializationOp(s, CSerActionSerialize(), nType, nVersion);\
96  return s.size(); \
97  } \
98  template<typename Stream> \
99  void Serialize(Stream& s, int nType, int nVersion) const { \
100  NCONST_PTR(this)->SerializationOp(s, CSerActionSerialize(), nType, nVersion);\
101  } \
102  template<typename Stream> \
103  void Unserialize(Stream& s, int nType, int nVersion) { \
104  SerializationOp(s, CSerActionUnserialize(), nType, nVersion); \
105  }
106 
107 
108 /*
109  * Basic Types
110  */
111 #define WRITEDATA(s, obj) s.write((char*)&(obj), sizeof(obj))
112 #define READDATA(s, obj) s.read((char*)&(obj), sizeof(obj))
113 
114 inline unsigned int GetSerializeSize(char a, int, int=0) { return sizeof(a); }
115 inline unsigned int GetSerializeSize(signed char a, int, int=0) { return sizeof(a); }
116 inline unsigned int GetSerializeSize(unsigned char a, int, int=0) { return sizeof(a); }
117 inline unsigned int GetSerializeSize(signed short a, int, int=0) { return sizeof(a); }
118 inline unsigned int GetSerializeSize(unsigned short a, int, int=0) { return sizeof(a); }
119 inline unsigned int GetSerializeSize(signed int a, int, int=0) { return sizeof(a); }
120 inline unsigned int GetSerializeSize(unsigned int a, int, int=0) { return sizeof(a); }
121 inline unsigned int GetSerializeSize(signed long a, int, int=0) { return sizeof(a); }
122 inline unsigned int GetSerializeSize(unsigned long a, int, int=0) { return sizeof(a); }
123 inline unsigned int GetSerializeSize(signed long long a, int, int=0) { return sizeof(a); }
124 inline unsigned int GetSerializeSize(unsigned long long a, int, int=0) { return sizeof(a); }
125 inline unsigned int GetSerializeSize(float a, int, int=0) { return sizeof(a); }
126 inline unsigned int GetSerializeSize(double a, int, int=0) { return sizeof(a); }
127 
128 template<typename Stream> inline void Serialize(Stream& s, char a, int, int=0) { WRITEDATA(s, a); }
129 template<typename Stream> inline void Serialize(Stream& s, signed char a, int, int=0) { WRITEDATA(s, a); }
130 template<typename Stream> inline void Serialize(Stream& s, unsigned char a, int, int=0) { WRITEDATA(s, a); }
131 template<typename Stream> inline void Serialize(Stream& s, signed short a, int, int=0) { WRITEDATA(s, a); }
132 template<typename Stream> inline void Serialize(Stream& s, unsigned short a, int, int=0) { WRITEDATA(s, a); }
133 template<typename Stream> inline void Serialize(Stream& s, signed int a, int, int=0) { WRITEDATA(s, a); }
134 template<typename Stream> inline void Serialize(Stream& s, unsigned int a, int, int=0) { WRITEDATA(s, a); }
135 template<typename Stream> inline void Serialize(Stream& s, signed long a, int, int=0) { WRITEDATA(s, a); }
136 template<typename Stream> inline void Serialize(Stream& s, unsigned long a, int, int=0) { WRITEDATA(s, a); }
137 template<typename Stream> inline void Serialize(Stream& s, signed long long a, int, int=0) { WRITEDATA(s, a); }
138 template<typename Stream> inline void Serialize(Stream& s, unsigned long long a, int, int=0) { WRITEDATA(s, a); }
139 template<typename Stream> inline void Serialize(Stream& s, float a, int, int=0) { WRITEDATA(s, a); }
140 template<typename Stream> inline void Serialize(Stream& s, double a, int, int=0) { WRITEDATA(s, a); }
141 
142 
143 template<typename Stream> inline void Unserialize(Stream& s, char& a, int, int=0) { READDATA(s, a); }
144 template<typename Stream> inline void Unserialize(Stream& s, signed char& a, int, int=0) { READDATA(s, a); }
145 template<typename Stream> inline void Unserialize(Stream& s, unsigned char& a, int, int=0) { READDATA(s, a); }
146 template<typename Stream> inline void Unserialize(Stream& s, signed short& a, int, int=0) { READDATA(s, a); }
147 template<typename Stream> inline void Unserialize(Stream& s, unsigned short& a, int, int=0) { READDATA(s, a); }
148 template<typename Stream> inline void Unserialize(Stream& s, signed int& a, int, int=0) { READDATA(s, a); }
149 template<typename Stream> inline void Unserialize(Stream& s, unsigned int& a, int, int=0) { READDATA(s, a); }
150 template<typename Stream> inline void Unserialize(Stream& s, signed long& a, int, int=0) { READDATA(s, a); }
151 template<typename Stream> inline void Unserialize(Stream& s, unsigned long& a, int, int=0) { READDATA(s, a); }
152 template<typename Stream> inline void Unserialize(Stream& s, signed long long& a, int, int=0) { READDATA(s, a); }
153 template<typename Stream> inline void Unserialize(Stream& s, unsigned long long& a, int, int=0) { READDATA(s, a); }
154 template<typename Stream> inline void Unserialize(Stream& s, float& a, int, int=0) { READDATA(s, a); }
155 template<typename Stream> inline void Unserialize(Stream& s, double& a, int, int=0) { READDATA(s, a); }
156 
157 
162 template<typename T, typename A> unsigned int GetSerializeSize_impl(const std::vector<T, A>& v, int nType, int nVersion, const unsigned char&);
163 template<typename T, typename A, typename V> unsigned int GetSerializeSize_impl(const std::vector<T, A>& v, int nType, int nVersion, const V&);
164 template<typename T, typename A> inline unsigned int GetSerializeSize(const std::vector<T, A>& v, int nType, int nVersion);
165 template<typename Stream, typename T, typename A> void Serialize_impl(Stream& os, const std::vector<T, A>& v, int nType, int nVersion, const unsigned char&);
166 template<typename Stream, typename T, typename A, typename V> void Serialize_impl(Stream& os, const std::vector<T, A>& v, int nType, int nVersion, const V&);
167 template<typename Stream, typename T, typename A> inline void Serialize(Stream& os, const std::vector<T, A>& v, int nType, int nVersion);
168 template<typename Stream, typename T, typename A> void Unserialize_impl(Stream& is, std::vector<T, A>& v, int nType, int nVersion, const unsigned char&);
169 template<typename Stream, typename T, typename A, typename V> void Unserialize_impl(Stream& is, std::vector<T, A>& v, int nType, int nVersion, const V&);
170 template<typename Stream, typename T, typename A> inline void Unserialize(Stream& is, std::vector<T, A>& v, int nType, int nVersion);
171 
175 extern inline unsigned int GetSerializeSize(const CScript& v, int nType, int nVersion);
176 template<typename Stream> void Serialize(Stream& os, const CScript& v, int nType, int nVersion);
177 template<typename Stream> void Unserialize(Stream& is, CScript& v, int nType, int nVersion);
178 
186 inline unsigned int GetSizeOfCompactSize(uint64_t nSize)
187 {
188  if (nSize < 253) return sizeof(unsigned char);
189  else if (nSize <= std::numeric_limits<unsigned short>::max()) return sizeof(unsigned char) + sizeof(unsigned short);
190  else if (nSize <= std::numeric_limits<unsigned int>::max()) return sizeof(unsigned char) + sizeof(unsigned int);
191  else return sizeof(unsigned char) + sizeof(uint64_t);
192 }
193 
194 template<typename Stream>
195 void WriteCompactSize(Stream& os, uint64_t nSize)
196 {
197  if (nSize < 253)
198  {
199  unsigned char chSize = (unsigned char)nSize;
200  WRITEDATA(os, chSize);
201  }
202  else if (nSize <= std::numeric_limits<unsigned short>::max())
203  {
204  unsigned char chSize = 253;
205  unsigned short xSize = (unsigned short)nSize;
206  WRITEDATA(os, chSize);
207  WRITEDATA(os, xSize);
208  }
209  else if (nSize <= std::numeric_limits<unsigned int>::max())
210  {
211  unsigned char chSize = 254;
212  unsigned int xSize = (unsigned int)nSize;
213  WRITEDATA(os, chSize);
214  WRITEDATA(os, xSize);
215  }
216  else
217  {
218  unsigned char chSize = 255;
219  uint64_t xSize = nSize;
220  WRITEDATA(os, chSize);
221  WRITEDATA(os, xSize);
222  }
223  return;
224 }
225 
226 template<typename Stream>
227 uint64_t ReadCompactSize(Stream& is)
228 {
229  unsigned char chSize;
230  READDATA(is, chSize);
231  uint64_t nSizeRet = 0;
232  if (chSize < 253)
233  {
234  nSizeRet = chSize;
235  }
236  else if (chSize == 253)
237  {
238  unsigned short xSize;
239  READDATA(is, xSize);
240  nSizeRet = xSize;
241  if (nSizeRet < 253)
242  throw std::ios_base::failure("non-canonical ReadCompactSize()");
243  }
244  else if (chSize == 254)
245  {
246  unsigned int xSize;
247  READDATA(is, xSize);
248  nSizeRet = xSize;
249  if (nSizeRet < 0x10000u)
250  throw std::ios_base::failure("non-canonical ReadCompactSize()");
251  }
252  else
253  {
254  uint64_t xSize;
255  READDATA(is, xSize);
256  nSizeRet = xSize;
257  if (nSizeRet < 0x100000000ULL)
258  throw std::ios_base::failure("non-canonical ReadCompactSize()");
259  }
260  if (nSizeRet > (uint64_t)MAX_SIZE)
261  throw std::ios_base::failure("ReadCompactSize() : size too large");
262  return nSizeRet;
263 }
264 
265 #define FLATDATA(obj) REF(CFlatData((char*)&(obj), (char*)&(obj) + sizeof(obj)))
266 #define VARINT(obj) REF(WrapVarInt(REF(obj)))
267 #define LIMITED_STRING(obj,n) REF(LimitedString< n >(REF(obj)))
268 
273 {
274 protected:
275  char* pbegin;
276  char* pend;
277 public:
278  CFlatData(void* pbeginIn, void* pendIn) : pbegin((char*)pbeginIn), pend((char*)pendIn) { }
279  template <class T, class TAl>
280  explicit CFlatData(std::vector<T,TAl> &v)
281  {
282  pbegin = (char*)begin_ptr(v);
283  pend = (char*)end_ptr(v);
284  }
285  char* begin() { return pbegin; }
286  const char* begin() const { return pbegin; }
287  char* end() { return pend; }
288  const char* end() const { return pend; }
289 
290  unsigned int GetSerializeSize(int, int=0) const
291  {
292  return pend - pbegin;
293  }
294 
295  template<typename Stream>
296  void Serialize(Stream& s, int, int=0) const
297  {
298  s.write(pbegin, pend - pbegin);
299  }
300 
301  template<typename Stream>
302  void Unserialize(Stream& s, int, int=0)
303  {
304  s.read(pbegin, pend - pbegin);
305  }
306 };
307 
314 template<typename T>
315 inline unsigned int GetSerializeSize(const T& a, long nType, int nVersion)
316 {
317  return a.GetSerializeSize((int)nType, nVersion);
318 }
319 
320 template<typename Stream, typename T>
321 inline void Serialize(Stream& os, const T& a, long nType, int nVersion)
322 {
323  a.Serialize(os, (int)nType, nVersion);
324 }
325 
326 template<typename Stream, typename T>
327 inline void Unserialize(Stream& is, T& a, long nType, int nVersion)
328 {
329  a.Unserialize(is, (int)nType, nVersion);
330 }
331 
335 template<typename C>
336 unsigned int GetSerializeSize(const std::basic_string<C>& str, int, int)
337 {
338  return GetSizeOfCompactSize(str.size()) + str.size() * sizeof(str[0]);
339 }
340 
341 template<typename Stream, typename C>
342 void Serialize(Stream& os, const std::basic_string<C>& str, int, int)
343 {
344  WriteCompactSize(os, str.size());
345  if (!str.empty())
346  os.write((char*)&str[0], str.size() * sizeof(str[0]));
347 }
348 
349 template<typename Stream, typename C>
350 void Unserialize(Stream& is, std::basic_string<C>& str, int, int)
351 {
352  unsigned int nSize = ReadCompactSize(is);
353  str.resize(nSize);
354  if (nSize != 0)
355  is.read((char*)&str[0], nSize * sizeof(str[0]));
356 }
357 
361 template<typename T, typename A>
362 unsigned int GetSerializeSize_impl(const std::vector<T, A>& v, int nType, int nVersion, const unsigned char&)
363 {
364  return (GetSizeOfCompactSize(v.size()) + v.size() * sizeof(T));
365 }
366 
367 template<typename T, typename A, typename V>
368 unsigned int GetSerializeSize_impl(const std::vector<T, A>& v, int nType, int nVersion, const V&)
369 {
370  unsigned int nSize = GetSizeOfCompactSize(v.size());
371  for (typename std::vector<T, A>::const_iterator vi = v.begin(); vi != v.end(); ++vi)
372  nSize += GetSerializeSize((*vi), nType, nVersion);
373  return nSize;
374 }
375 
376 template<typename T, typename A>
377 inline unsigned int GetSerializeSize(const std::vector<T, A>& v, int nType, int nVersion)
378 {
379  return GetSerializeSize_impl(v, nType, nVersion, T());
380 }
381 
382 
383 template<typename Stream, typename T, typename A>
384 void Serialize_impl(Stream& os, const std::vector<T, A>& v, int nType, int nVersion, const unsigned char&)
385 {
386  WriteCompactSize(os, v.size());
387  if (!v.empty())
388  os.write((char*)&v[0], v.size() * sizeof(T));
389 }
390 
391 template<typename Stream, typename T, typename A, typename V>
392 void Serialize_impl(Stream& os, const std::vector<T, A>& v, int nType, int nVersion, const V&)
393 {
394  WriteCompactSize(os, v.size());
395  for (typename std::vector<T, A>::const_iterator vi = v.begin(); vi != v.end(); ++vi)
396  ::Serialize(os, (*vi), nType, nVersion);
397 }
398 
399 template<typename Stream, typename T, typename A>
400 inline void Serialize(Stream& os, const std::vector<T, A>& v, int nType, int nVersion)
401 {
402  Serialize_impl(os, v, nType, nVersion, T());
403 }
404 
405 
406 template<typename Stream, typename T, typename A>
407 void Unserialize_impl(Stream& is, std::vector<T, A>& v, int nType, int nVersion, const unsigned char&)
408 {
409  // Limit size per read so bogus size value won't cause out of memory
410  v.clear();
411  unsigned int nSize = (unsigned int)ReadCompactSize(is);
412  unsigned int i = 0;
413  while (i < nSize)
414  {
415  unsigned int blk = std::min(nSize - i, (unsigned int)(1 + 4999999 / sizeof(T)));
416  v.resize(i + blk);
417  is.read((char*)&v[i], blk * sizeof(T));
418  i += blk;
419  }
420 }
421 
422 template<typename Stream, typename T, typename A, typename V>
423 void Unserialize_impl(Stream& is, std::vector<T, A>& v, int nType, int nVersion, const V&)
424 {
425  v.clear();
426  unsigned int nSize = (unsigned int)ReadCompactSize(is);
427  unsigned int i = 0;
428  unsigned int nMid = 0;
429  while (nMid < nSize)
430  {
431  nMid += 5000000 / sizeof(T);
432  if (nMid > nSize)
433  nMid = nSize;
434  v.resize(nMid);
435  for (; i < nMid; i++)
436  Unserialize(is, v[i], nType, nVersion);
437  }
438 }
439 
440 template<typename Stream, typename T, typename A>
441 inline void Unserialize(Stream& is, std::vector<T, A>& v, int nType, int nVersion)
442 {
443  Unserialize_impl(is, v, nType, nVersion, T());
444 }
445 
449 inline unsigned int GetSerializeSize(const CScript& v, int nType, int nVersion)
450 {
451  return GetSerializeSize((const std::vector<unsigned char>&)v, nType, nVersion);
452 }
453 
454 template<typename Stream>
455 void Serialize(Stream& os, const CScript& v, int nType, int nVersion)
456 {
457  Serialize(os, (const std::vector<unsigned char>&)v, nType, nVersion);
458 }
459 
460 template<typename Stream>
461 void Unserialize(Stream& is, CScript& v, int nType, int nVersion)
462 {
463  Unserialize(is, (std::vector<unsigned char>&)v, nType, nVersion);
464 }
465 
469 template<typename K, typename Pred, typename A>
470 unsigned int GetSerializeSize(const std::set<K, Pred, A>& m, int nType, int nVersion)
471 {
472  unsigned int nSize = GetSizeOfCompactSize(m.size());
473  for (typename std::set<K, Pred, A>::const_iterator it = m.begin(); it != m.end(); ++it)
474  nSize += GetSerializeSize((*it), nType, nVersion);
475  return nSize;
476 }
477 
478 template<typename Stream, typename K, typename Pred, typename A>
479 void Serialize(Stream& os, const std::set<K, Pred, A>& m, int nType, int nVersion)
480 {
481  WriteCompactSize(os, m.size());
482  for (typename std::set<K, Pred, A>::const_iterator it = m.begin(); it != m.end(); ++it)
483  Serialize(os, (*it), nType, nVersion);
484 }
485 
486 template<typename Stream, typename K, typename Pred, typename A>
487 void Unserialize(Stream& is, std::set<K, Pred, A>& m, int nType, int nVersion)
488 {
489  m.clear();
490  unsigned int nSize = ReadCompactSize(is);
491  typename std::set<K, Pred, A>::iterator it = m.begin();
492  for (unsigned int i = 0; i < nSize; i++)
493  {
494  K key;
495  Unserialize(is, key, nType, nVersion);
496  it = m.insert(it, key);
497  }
498 }
499 
500 
505 {
506  bool ForRead() const { return false; }
507 };
509 {
510  bool ForRead() const { return true; }
511 };
512 
513 template<typename Stream, typename T>
514 inline void SerReadWrite(Stream& s, const T& obj, int nType, int nVersion, CSerActionSerialize ser_action)
515 {
516  ::Serialize(s, obj, nType, nVersion);
517 }
518 
519 template<typename Stream, typename T>
520 inline void SerReadWrite(Stream& s, T& obj, int nType, int nVersion, CSerActionUnserialize ser_action)
521 {
522  ::Unserialize(s, obj, nType, nVersion);
523 }
524 
525 
527 {
528 protected:
529  size_t nSize;
530 
531 public:
532  int nType;
533  int nVersion;
534 
535  CSizeComputer(int nTypeIn, int nVersionIn) : nSize(0), nType(nTypeIn), nVersion(nVersionIn) {}
536 
537  CSizeComputer& write(const char *psz, size_t nSize)
538  {
539  this->nSize += nSize;
540  return *this;
541  }
542 
543  template<typename T>
544  CSizeComputer& operator<<(const T& obj)
545  {
546  ::Serialize(*this, obj, nType, nVersion);
547  return (*this);
548  }
549 
550  size_t size() const {
551  return nSize;
552  }
553 };
554 
555 #endif // SERIALIZE_H
Definition: serialize.h:508
Definition: serialize.h:504
Definition: script.h:336
Definition: serialize.h:526
Definition: serialize.h:272