BitShares-Core  5.0.0
BitShares blockchain implementation and command-line interface software
raw.hpp
Go to the documentation of this file.
1 #pragma once
2 #include <boost/endian/buffers.hpp>
3 
4 #include <fc/io/raw_variant.hpp>
5 #include <fc/reflect/reflect.hpp>
6 #include <fc/io/datastream.hpp>
7 #include <fc/optional.hpp>
8 #include <fc/fwd.hpp>
9 #include <fc/time.hpp>
10 #include <fc/filesystem.hpp>
12 #include <fc/io/raw_fwd.hpp>
13 #include <algorithm>
14 #include <map>
15 #include <deque>
16 
17 namespace fc {
18  namespace raw {
19 
20  template<typename Stream, typename Arg0, typename... Args>
21  inline void pack( Stream& s, const Arg0& a0, Args... args, uint32_t _max_depth ) {
22  FC_ASSERT( _max_depth > 0 );
23  --_max_depth;
24  pack( s, a0, _max_depth );
25  pack( s, args..., _max_depth );
26  }
27 
28  template<typename Stream>
29  inline void pack( Stream& s, const uint128_t& v, uint32_t _max_depth )
30  {
31  boost::endian::little_uint64_buf_at hilo[2];
32  hilo[0] = uint128_hi64( v );
33  hilo[1] = uint128_lo64( v );
34  s.write( (char*)hilo[0].data(), sizeof(hilo) );
35  }
36  template<typename Stream>
37  inline void unpack( Stream& s, uint128_t& v, uint32_t _max_depth )
38  {
39  boost::endian::little_uint64_buf_at hilo[2];
40  s.read( (char*) hilo, sizeof(hilo) );
41  v = uint128( hilo[0].value(), hilo[1].value() );
42  }
43 
44  template<typename Stream>
45  inline void pack( Stream& s, const fc::exception& e, uint32_t _max_depth )
46  {
47  FC_ASSERT( _max_depth > 0 );
48  --_max_depth;
49  fc::raw::pack( s, e.code(), _max_depth );
50  fc::raw::pack( s, std::string(e.name()), _max_depth );
51  fc::raw::pack( s, std::string(e.what()), _max_depth );
52  fc::raw::pack( s, e.get_log(), _max_depth );
53  }
54  template<typename Stream>
55  inline void unpack( Stream& s, fc::exception& e, uint32_t _max_depth )
56  {
57  FC_ASSERT( _max_depth > 0 );
58  --_max_depth;
59  int64_t code;
60  std::string name, what;
61  log_messages msgs;
62 
63  fc::raw::unpack( s, code, _max_depth );
64  fc::raw::unpack( s, name, _max_depth );
65  fc::raw::unpack( s, what, _max_depth );
66  fc::raw::unpack( s, msgs, _max_depth );
67 
68  e = fc::exception( std::move(msgs), code, name, what );
69  }
70 
71  template<typename Stream>
72  inline void pack( Stream& s, const fc::log_message& msg, uint32_t _max_depth )
73  {
74  FC_ASSERT( _max_depth > 0 );
75  --_max_depth;
76  fc::raw::pack( s, variant( msg, std::min( _max_depth, uint32_t(FC_MAX_LOG_OBJECT_DEPTH) ) ), _max_depth );
77  }
78  template<typename Stream>
79  inline void unpack( Stream& s, fc::log_message& msg, uint32_t _max_depth )
80  {
81  FC_ASSERT( _max_depth > 0 );
82  fc::variant vmsg;
83  --_max_depth;
84  fc::raw::unpack( s, vmsg, _max_depth );
85  msg = vmsg.as<log_message>( std::min( _max_depth, uint32_t(FC_MAX_LOG_OBJECT_DEPTH) ) );
86  }
87 
88  template<typename Stream>
89  inline void pack( Stream& s, const fc::path& tp, uint32_t _max_depth )
90  {
91  FC_ASSERT( _max_depth > 0 );
92  fc::raw::pack( s, tp.generic_string(), _max_depth - 1 );
93  }
94 
95  template<typename Stream>
96  inline void unpack( Stream& s, fc::path& tp, uint32_t _max_depth )
97  {
98  FC_ASSERT( _max_depth > 0 );
99  std::string p;
100  fc::raw::unpack( s, p, _max_depth - 1 );
101  tp = p;
102  }
103 
104  template<typename Stream>
105  inline void pack( Stream& s, const fc::time_point_sec& tp, uint32_t _max_depth )
106  {
107  pack( s, tp.sec_since_epoch(), _max_depth );
108  }
109 
110  template<typename Stream>
111  inline void unpack( Stream& s, fc::time_point_sec& tp, uint32_t _max_depth )
112  { try {
113  uint32_t sec;
114  unpack( s, sec, _max_depth );
115  tp = fc::time_point() + fc::seconds(sec);
116  } FC_RETHROW_EXCEPTIONS( warn, "" ) }
117 
118  template<typename Stream>
119  inline void pack( Stream& s, const fc::time_point& tp, uint32_t _max_depth )
120  {
121  pack( s, tp.time_since_epoch().count(), _max_depth );
122  }
123 
124  template<typename Stream>
125  inline void unpack( Stream& s, fc::time_point& tp, uint32_t _max_depth )
126  { try {
127  uint64_t usec;
128  unpack( s, usec, _max_depth );
129  tp = fc::time_point() + fc::microseconds(usec);
130  } FC_RETHROW_EXCEPTIONS( warn, "" ) }
131 
132  template<typename Stream>
133  inline void pack( Stream& s, const fc::microseconds& usec, uint32_t _max_depth )
134  {
135  pack( s, usec.count(), _max_depth );
136  }
137 
138  template<typename Stream>
139  inline void unpack( Stream& s, fc::microseconds& usec, uint32_t _max_depth )
140  { try {
141  uint64_t usec_as_int64;
142  unpack( s, usec_as_int64, _max_depth );
143  usec = fc::microseconds(usec_as_int64);
144  } FC_RETHROW_EXCEPTIONS( warn, "" ) }
145 
146  template<typename Stream, size_t N>
147  inline void pack( Stream& s, const std::array<char,N>& v, uint32_t _max_depth ) {
148  s.write( v.data(), N );
149  }
150  template<typename Stream, size_t N>
151  inline void pack( Stream& s, const std::array<unsigned char,N>& v, uint32_t _max_depth ) {
152  s.write( (char*)v.data(), N );
153  }
154 
155  template<typename Stream, size_t N>
156  inline void unpack( Stream& s, std::array<char,N>& v, uint32_t _max_depth ) { try {
157  s.read( v.data(), N );
158  } FC_RETHROW_EXCEPTIONS( warn, "std::array<char,${length}>", ("length",N) ) }
159  template<typename Stream, size_t N>
160  inline void unpack( Stream& s, std::array<unsigned char,N>& v, uint32_t _max_depth ) { try {
161  s.read( (char*)v.data(), N );
162  } FC_RETHROW_EXCEPTIONS( warn, "std::array<unsigned char,${length}>", ("length",N) ) }
163 
164  template<typename Stream, typename T>
165  inline void pack( Stream& s, const std::shared_ptr<T>& v, uint32_t _max_depth )
166  {
167  FC_ASSERT( _max_depth > 0 );
168  fc::raw::pack( s, *v, _max_depth - 1 );
169  }
170 
171  template<typename Stream, typename T>
172  inline void unpack( Stream& s, std::shared_ptr<T>& v, uint32_t _max_depth )
173  { try {
174  FC_ASSERT( _max_depth > 0 );
175  v = std::make_shared<T>();
176  fc::raw::unpack( s, *v, _max_depth - 1 );
177  } FC_RETHROW_EXCEPTIONS( warn, "std::shared_ptr<${type}>", ("type",fc::get_typename<T>::name()) ) }
178 
179  template<typename Stream, typename T>
180  inline void pack( Stream& s, const std::shared_ptr<const T>& v, uint32_t _max_depth )
181  {
182  FC_ASSERT( _max_depth > 0 );
183  fc::raw::pack( s, *v, _max_depth - 1 );
184  }
185 
186  template<typename Stream, typename T>
187  inline void unpack( Stream& s, std::shared_ptr<const T>& v, uint32_t _max_depth )
188  { try {
189  FC_ASSERT( _max_depth > 0 );
190  T tmp;
191  fc::raw::unpack( s, tmp, _max_depth - 1 );
192  v = std::make_shared<const T>(std::move(tmp));
193  } FC_RETHROW_EXCEPTIONS( warn, "std::shared_ptr<const T>", ("type",fc::get_typename<T>::name()) ) }
194 
195  template<typename Stream> inline void pack( Stream& s, const unsigned_int& v, uint32_t _max_depth ) {
196  uint64_t val = v.value;
197  do {
198  uint8_t b = uint8_t(val) & 0x7f;
199  val >>= 7;
200  b |= ((val > 0) << 7);
201  s.write((char*)&b,1);//.put(b);
202  }while( val );
203  }
204 
205  template<typename Stream> inline void unpack( Stream& s, unsigned_int& vi, uint32_t _max_depth ) {
206  uint64_t v = 0; char b = 0; uint8_t by = 0;
207  do {
208  s.get(b);
209  if( by >= 64 || (by == 63 && uint8_t(b) > 1) )
210  FC_THROW_EXCEPTION( overflow_exception, "Invalid packed unsigned_int!" );
211  v |= uint64_t(uint8_t(b) & 0x7f) << by;
212  by += 7;
213  } while( uint8_t(b) & 0x80 );
214  vi.value = static_cast<uint64_t>(v);
215  }
216 
217  template<typename Stream, typename T> inline void unpack( Stream& s, const T& vi, uint32_t _max_depth )
218  {
219  FC_ASSERT( _max_depth > 0 );
220  T tmp;
221  fc::raw::unpack( s, tmp, _max_depth - 1 );
222  FC_ASSERT( vi == tmp );
223  }
224 
225  template<typename Stream> inline void pack( Stream& s, const char* v, uint32_t _max_depth )
226  {
227  FC_ASSERT( _max_depth > 0 );
228  fc::raw::pack( s, std::string(v), _max_depth - 1 );
229  }
230 
231  template<typename Stream, typename T>
232  void pack( Stream& s, const safe<T>& v, uint32_t _max_depth )
233  {
234  FC_ASSERT( _max_depth > 0 );
235  fc::raw::pack( s, v.value, _max_depth - 1 );
236  }
237 
238  template<typename Stream, typename T>
239  void unpack( Stream& s, fc::safe<T>& v, uint32_t _max_depth )
240  {
241  FC_ASSERT( _max_depth > 0 );
242  fc::raw::unpack( s, v.value, _max_depth - 1 );
243  }
244 
245  template<typename Stream, typename T, unsigned int S, typename Align>
246  void pack( Stream& s, const fc::fwd<T,S,Align>& v, uint32_t _max_depth ) {
247  FC_ASSERT( _max_depth > 0 );
248  fc::raw::pack( *v, _max_depth - 1 ); // TODO not sure about this
249  }
250 
251  template<typename Stream, typename T, unsigned int S, typename Align>
252  void unpack( Stream& s, fc::fwd<T,S,Align>& v, uint32_t _max_depth ) {
253  FC_ASSERT( _max_depth > 0 );
254  fc::raw::unpack( *v, _max_depth - 1 ); // TODO not sure about this
255  }
256 
257  // optional
258  template<typename Stream, typename T>
259  void pack( Stream& s, const fc::optional<T>& v, uint32_t _max_depth ) {
260  FC_ASSERT( _max_depth > 0 );
261  --_max_depth;
262  fc::raw::pack( s, bool(!!v), _max_depth );
263  if( !!v ) fc::raw::pack( s, *v, _max_depth );
264  }
265 
266  template<typename Stream, typename T>
267  void unpack( Stream& s, fc::optional<T>& v, uint32_t _max_depth )
268  { try {
269  FC_ASSERT( _max_depth > 0 );
270  --_max_depth;
271  bool b; fc::raw::unpack( s, b, _max_depth );
272  if( b ) { v = T(); fc::raw::unpack( s, *v, _max_depth ); }
273  } FC_RETHROW_EXCEPTIONS( warn, "optional<${type}>", ("type",fc::get_typename<T>::name() ) ) }
274 
275  // std::vector<char>
276  template<typename Stream> inline void pack( Stream& s, const std::vector<char>& value, uint32_t _max_depth ) {
277  FC_ASSERT( _max_depth > 0 );
278  fc::raw::pack( s, unsigned_int(value.size()), _max_depth - 1 );
279  if( value.size() )
280  s.write( &value.front(), value.size() );
281  }
282  template<typename Stream> inline void unpack( Stream& s, std::vector<char>& value, uint32_t _max_depth ) {
283  FC_ASSERT( _max_depth > 0 );
284  unsigned_int size; fc::raw::unpack( s, size, _max_depth - 1 );
286  value.resize(size.value);
287  if( value.size() )
288  s.read( value.data(), value.size() );
289  }
290 
291  // fc::string
292  template<typename Stream> inline void pack( Stream& s, const std::string& v, uint32_t _max_depth ) {
293  FC_ASSERT( _max_depth > 0 );
294  fc::raw::pack( s, unsigned_int(v.size()), _max_depth - 1 );
295  if( v.size() ) s.write( v.c_str(), v.size() );
296  }
297 
298  template<typename Stream> inline void unpack( Stream& s, std::string& v, uint32_t _max_depth ) {
299  FC_ASSERT( _max_depth > 0 );
300  std::vector<char> tmp; fc::raw::unpack( s, tmp, _max_depth - 1 );
301  if( tmp.size() )
302  v = std::string( tmp.data(), tmp.data()+tmp.size() );
303  else v = std::string();
304  }
305 
306  // bool
307  template<typename Stream> inline void pack( Stream& s, const bool& v, uint32_t _max_depth )
308  {
309  FC_ASSERT( _max_depth > 0 );
310  fc::raw::pack( s, v ? uint8_t(1) : uint8_t(0), _max_depth - 1 );
311  }
312  template<typename Stream> inline void unpack( Stream& s, bool& v, uint32_t _max_depth )
313  {
314  FC_ASSERT( _max_depth > 0 );
315  uint8_t b;
316  fc::raw::unpack( s, b, _max_depth - 1 );
317  FC_ASSERT( (b & ~1) == 0 );
318  v=(b!=0);
319  }
320 
321  namespace detail {
322 
323  template<typename Stream, typename Class>
325  pack_object_visitor( const Class& _c, Stream& _s, uint32_t _max_depth )
326  :c(_c),s(_s),max_depth(_max_depth - 1)
327  {
328  FC_ASSERT( _max_depth > 0 );
329  }
330 
331  template<typename T, typename C, T(C::*p)>
332  void operator()( const char* name )const {
333  fc::raw::pack( s, c.*p, max_depth );
334  }
335  private:
336  const Class& c;
337  Stream& s;
338  const uint32_t max_depth;
339  };
340 
341  template<typename Stream, typename Class>
343  unpack_object_visitor( Class& _c, Stream& _s, uint32_t _max_depth ) : c(_c),s(_s),max_depth(_max_depth - 1)
344  {
345  FC_ASSERT( _max_depth > 0 );
346  }
347 
348  template<typename T, typename C, T(C::*p)>
349  inline void operator()( const char* name )const
350  { try {
351  fc::raw::unpack( s, c.*p, max_depth );
352  } FC_RETHROW_EXCEPTIONS( warn, "Error unpacking field ${field}", ("field",name) ) }
353  private:
354  Class& c;
355  Stream& s;
356  const uint32_t max_depth;
357  };
358 
359  // Default pack/unpack functions for classes are removed due to recursion issue.
360  // Classes should implement pack/unpack functions explicitly.
361  template<typename T, typename Dummy = void>
362  struct if_class;
363 
364  template<typename T>
365  struct if_class<T, std::enable_if_t<!std::is_class<T>::value>> {
366  template<typename Stream>
367  static inline void pack( Stream& s, const T v, uint32_t _max_depth ) = delete;
368  template<typename Stream>
369  static inline void unpack( Stream& s, T& v, uint32_t _max_depth ) = delete;
370  };
371 
372  template<>
373  struct if_class<int64_t, void> {
374  template<typename Stream>
375  static inline void pack( Stream& s, const int64_t v, uint32_t _max_depth ) {
376  boost::endian::little_int64_buf_t tmp;
377  tmp = v;
378  s.write( (char*)&tmp, sizeof(tmp) );
379  }
380  template<typename Stream>
381  static inline void unpack( Stream& s, int64_t& v, uint32_t _max_depth ) {
382  boost::endian::little_int64_buf_t tmp;
383  s.read( (char*)&tmp, sizeof(tmp) );
384  v = tmp.value();
385  }
386  };
387 
388  template<>
389  struct if_class<uint64_t, void> {
390  template<typename Stream>
391  static inline void pack( Stream& s, const uint64_t v, uint32_t _max_depth ) {
392  boost::endian::little_uint64_buf_t tmp;
393  tmp = v;
394  s.write( (char*)&tmp, sizeof(tmp) );
395  }
396  template<typename Stream>
397  static inline void unpack( Stream& s, uint64_t& v, uint32_t _max_depth ) {
398  boost::endian::little_uint64_buf_t tmp;
399  s.read( (char*)&tmp, sizeof(tmp) );
400  v = tmp.value();
401  }
402  };
403 
404  template<>
405  struct if_class<int32_t, void> {
406  template<typename Stream>
407  static inline void pack( Stream& s, const int32_t v, uint32_t _max_depth ) {
408  boost::endian::little_int32_buf_t tmp;
409  tmp = v;
410  s.write( (char*)&tmp, sizeof(tmp) );
411  }
412  template<typename Stream>
413  static inline void unpack( Stream& s, int32_t& v, uint32_t _max_depth ) {
414  boost::endian::little_int32_buf_t tmp;
415  s.read( (char*)&tmp, sizeof(tmp) );
416  v = tmp.value();
417  }
418  };
419 
420  template<>
421  struct if_class<uint32_t, void> {
422  template<typename Stream>
423  static inline void pack( Stream& s, const uint32_t v, uint32_t _max_depth ) {
424  boost::endian::little_uint32_buf_t tmp;
425  tmp = v;
426  s.write( (char*)&tmp, sizeof(tmp) );
427  }
428  template<typename Stream>
429  static inline void unpack( Stream& s, uint32_t& v, uint32_t _max_depth ) {
430  boost::endian::little_uint32_buf_t tmp;
431  s.read( (char*)&tmp, sizeof(tmp) );
432  v = tmp.value();
433  }
434  };
435 
436  template<>
437  struct if_class<int16_t, void> {
438  template<typename Stream>
439  static inline void pack( Stream& s, const int16_t v, uint32_t _max_depth ) {
440  boost::endian::little_int16_buf_t tmp;
441  tmp = v;
442  s.write( (char*)&tmp, sizeof(tmp) );
443  }
444  template<typename Stream>
445  static inline void unpack( Stream& s, int16_t& v, uint32_t _max_depth ) {
446  boost::endian::little_int16_buf_t tmp;
447  s.read( (char*)&tmp, sizeof(tmp) );
448  v = tmp.value();
449  }
450  };
451 
452  template<>
453  struct if_class<uint16_t, void> {
454  template<typename Stream>
455  static inline void pack( Stream& s, const uint16_t v, uint32_t _max_depth ) {
456  boost::endian::little_uint16_buf_t tmp;
457  tmp = v;
458  s.write( (char*)&tmp, sizeof(tmp) );
459  }
460  template<typename Stream>
461  static inline void unpack( Stream& s, uint16_t& v, uint32_t _max_depth ) {
462  boost::endian::little_uint16_buf_t tmp;
463  s.read( (char*)&tmp, sizeof(tmp) );
464  v = tmp.value();
465  }
466  };
467 
468  template<>
469  struct if_class<int8_t, void> {
470  template<typename Stream>
471  static inline void pack( Stream& s, const int8_t v, uint32_t _max_depth ) {
472  s.write( (char*)&v, 1 );
473  }
474  template<typename Stream>
475  static inline void unpack( Stream& s, int8_t& v, uint32_t _max_depth ) {
476  s.read( (char*)&v, 1 );
477  }
478  };
479 
480  template<>
481  struct if_class<uint8_t, void> {
482  template<typename Stream>
483  static inline void pack( Stream& s, const uint8_t v, uint32_t _max_depth ) {
484  s.write( (char*)&v, 1 );
485  }
486  template<typename Stream>
487  static inline void unpack( Stream& s, uint8_t& v, uint32_t _max_depth ) {
488  s.read( (char*)&v, 1 );
489  }
490  };
491 
492  template<typename T, typename Dummy=void>
493  struct if_enum;
494  template<typename T>
495  struct if_enum<T, std::enable_if_t<!std::is_enum<T>::value>> {
496  template<typename Stream>
497  static inline void pack( Stream& s, const T& v, uint32_t _max_depth ) {
498  FC_ASSERT( _max_depth > 0 );
499  fc::reflector<T>::visit( pack_object_visitor<Stream,T>( v, s, _max_depth - 1 ) );
500  }
501  template<typename Stream>
502  static inline void unpack( Stream& s, T& v, uint32_t _max_depth ) {
503  FC_ASSERT( _max_depth > 0 );
504  fc::reflector<T>::visit( unpack_object_visitor<Stream,T>( v, s, _max_depth - 1 ) );
505  }
506  };
507  template<typename T>
508  struct if_enum<T, std::enable_if_t<std::is_enum<T>::value>> {
509  template<typename Stream>
510  static inline void pack( Stream& s, const T& v, uint32_t _max_depth ) {
511  FC_ASSERT( _max_depth > 0 );
512  fc::raw::pack( s, (int64_t)v, _max_depth - 1 );
513  }
514  template<typename Stream>
515  static inline void unpack( Stream& s, T& v, uint32_t _max_depth ) {
516  FC_ASSERT( _max_depth > 0 );
517  int64_t temp;
518  fc::raw::unpack( s, temp, _max_depth - 1 );
519  v = (T)temp;
520  }
521  };
522 
523  template<typename IsReflected=std::false_type>
524  struct if_reflected {
525  template<typename Stream, typename T>
526  static inline void pack( Stream& s, const T& v, uint32_t _max_depth ) {
527  FC_ASSERT( _max_depth > 0 );
528  if_class<T>::pack( s, v, _max_depth - 1 );
529  }
530  template<typename Stream, typename T>
531  static inline void unpack( Stream& s, T& v, uint32_t _max_depth ) {
532  FC_ASSERT( _max_depth > 0 );
533  if_class<T>::unpack( s, v, _max_depth - 1 );
534  }
535  };
536  template<>
537  struct if_reflected<std::true_type> {
538  template<typename Stream, typename T>
539  static inline void pack( Stream& s, const T& v, uint32_t _max_depth ) {
540  FC_ASSERT( _max_depth > 0 );
541  if_enum<T>::pack( s, v, _max_depth - 1 );
542  }
543  template<typename Stream, typename T>
544  static inline void unpack( Stream& s, T& v, uint32_t _max_depth ) {
545  FC_ASSERT( _max_depth > 0 );
546  if_enum<T>::unpack( s, v, _max_depth - 1 );
547  }
548  };
549 
550  } // namesapce detail
551 
552  template<typename Stream, typename T>
553  inline void pack( Stream& s, const std::unordered_set<T>& value, uint32_t _max_depth ) {
554  FC_ASSERT( _max_depth > 0 );
555  --_max_depth;
556  fc::raw::pack( s, unsigned_int(value.size()), _max_depth );
557  auto itr = value.begin();
558  auto end = value.end();
559  while( itr != end ) {
560  fc::raw::pack( s, *itr, _max_depth );
561  ++itr;
562  }
563  }
564  template<typename Stream, typename T>
565  inline void unpack( Stream& s, std::unordered_set<T>& value, uint32_t _max_depth ) {
566  FC_ASSERT( _max_depth > 0 );
567  --_max_depth;
568  unsigned_int size; fc::raw::unpack( s, size, _max_depth );
569  value.clear();
570  value.reserve( std::min( size.value, static_cast<uint64_t>(FC_MAX_PREALLOC_SIZE) ) );
571  for( uint32_t i = 0; i < size.value; ++i )
572  {
573  T tmp;
574  fc::raw::unpack( s, tmp, _max_depth );
575  value.insert( std::move(tmp) );
576  }
577  }
578 
579 
580  template<typename Stream, typename K, typename V>
581  inline void pack( Stream& s, const std::pair<K,V>& value, uint32_t _max_depth ) {
582  FC_ASSERT( _max_depth > 0 );
583  --_max_depth;
584  fc::raw::pack( s, value.first, _max_depth );
585  fc::raw::pack( s, value.second, _max_depth );
586  }
587  template<typename Stream, typename K, typename V>
588  inline void unpack( Stream& s, std::pair<K,V>& value, uint32_t _max_depth )
589  {
590  FC_ASSERT( _max_depth > 0 );
591  --_max_depth;
592  fc::raw::unpack( s, value.first, _max_depth );
593  fc::raw::unpack( s, value.second, _max_depth );
594  }
595 
596  template<typename Stream, typename K, typename V>
597  inline void pack( Stream& s, const std::unordered_map<K,V>& value, uint32_t _max_depth ) {
598  FC_ASSERT( _max_depth > 0 );
599  --_max_depth;
600  fc::raw::pack( s, unsigned_int(value.size()), _max_depth );
601  auto itr = value.begin();
602  auto end = value.end();
603  while( itr != end ) {
604  fc::raw::pack( s, *itr, _max_depth );
605  ++itr;
606  }
607  }
608  template<typename Stream, typename K, typename V>
609  inline void unpack( Stream& s, std::unordered_map<K,V>& value, uint32_t _max_depth )
610  {
611  FC_ASSERT( _max_depth > 0 );
612  --_max_depth;
613  unsigned_int size; fc::raw::unpack( s, size, _max_depth );
614  value.clear();
615  value.reserve( std::min( size.value, static_cast<uint64_t>(FC_MAX_PREALLOC_SIZE) ) );
616  for( uint32_t i = 0; i < size.value; ++i )
617  {
618  std::pair<K,V> tmp;
619  fc::raw::unpack( s, tmp, _max_depth );
620  value.insert( std::move(tmp) );
621  }
622  }
623  template<typename Stream, typename K, typename V>
624  inline void pack( Stream& s, const std::map<K,V>& value, uint32_t _max_depth ) {
625  FC_ASSERT( _max_depth > 0 );
626  --_max_depth;
627  fc::raw::pack( s, unsigned_int(value.size()), _max_depth );
628  auto itr = value.begin();
629  auto end = value.end();
630  while( itr != end ) {
631  fc::raw::pack( s, *itr, _max_depth );
632  ++itr;
633  }
634  }
635  template<typename Stream, typename K, typename V>
636  inline void unpack( Stream& s, std::map<K,V>& value, uint32_t _max_depth )
637  {
638  FC_ASSERT( _max_depth > 0 );
639  --_max_depth;
640  unsigned_int size; fc::raw::unpack( s, size, _max_depth );
641  value.clear();
642  for( uint32_t i = 0; i < size.value; ++i )
643  {
644  std::pair<K,V> tmp;
645  fc::raw::unpack( s, tmp, _max_depth );
646  value.insert( std::move(tmp) );
647  }
648  }
649 
650  template<typename Stream, typename T>
651  inline void pack( Stream& s, const std::deque<T>& value, uint32_t _max_depth ) {
652  FC_ASSERT( _max_depth > 0 );
653  --_max_depth;
654  fc::raw::pack( s, unsigned_int(value.size()), _max_depth );
655  auto itr = value.begin();
656  auto end = value.end();
657  while( itr != end ) {
658  fc::raw::pack( s, *itr, _max_depth );
659  ++itr;
660  }
661  }
662 
663  template<typename Stream, typename T>
664  inline void unpack( Stream& s, std::deque<T>& value, uint32_t _max_depth ) {
665  FC_ASSERT( _max_depth > 0 );
666  --_max_depth;
667  unsigned_int size; fc::raw::unpack( s, size, _max_depth );
668  value.resize( std::min( size.value, static_cast<uint64_t>(FC_MAX_PREALLOC_SIZE) ) );
669  for( uint64_t i = 0; i < size; i++ )
670  {
671  if( i >= value.size() )
672  value.resize( std::min( static_cast<uint64_t>(2*value.size()), size.value ) );
673  unpack( s, value[i], _max_depth );
674  }
675  }
676 
677  template<typename Stream, typename T>
678  inline void pack( Stream& s, const std::vector<T>& value, uint32_t _max_depth ) {
679  FC_ASSERT( _max_depth > 0 );
680  --_max_depth;
681  fc::raw::pack( s, unsigned_int(value.size()), _max_depth );
682  auto itr = value.begin();
683  auto end = value.end();
684  while( itr != end ) {
685  fc::raw::pack( s, *itr, _max_depth );
686  ++itr;
687  }
688  }
689 
690  template<typename Stream, typename T>
691  inline void unpack( Stream& s, std::vector<T>& value, uint32_t _max_depth ) {
692  FC_ASSERT( _max_depth > 0 );
693  --_max_depth;
694  unsigned_int size; fc::raw::unpack( s, size, _max_depth );
695  value.resize( std::min( size.value, static_cast<uint64_t>(FC_MAX_PREALLOC_SIZE) ) );
696  for( uint64_t i = 0; i < size; i++ )
697  {
698  if( i >= value.size() )
699  value.resize( std::min( static_cast<uint64_t>(2*value.size()), size.value ) );
700  unpack( s, value[i], _max_depth );
701  }
702  }
703 
704  template<typename Stream, typename T>
705  inline void pack( Stream& s, const std::set<T>& value, uint32_t _max_depth ) {
706  FC_ASSERT( _max_depth > 0 );
707  --_max_depth;
708  fc::raw::pack( s, unsigned_int(value.size()), _max_depth );
709  auto itr = value.begin();
710  auto end = value.end();
711  while( itr != end ) {
712  fc::raw::pack( s, *itr, _max_depth );
713  ++itr;
714  }
715  }
716 
717  template<typename Stream, typename T>
718  inline void unpack( Stream& s, std::set<T>& value, uint32_t _max_depth ) {
719  FC_ASSERT( _max_depth > 0 );
720  --_max_depth;
721  unsigned_int size; fc::raw::unpack( s, size, _max_depth );
722  for( uint64_t i = 0; i < size.value; ++i )
723  {
724  T tmp;
725  fc::raw::unpack( s, tmp, _max_depth );
726  value.insert( std::move(tmp) );
727  }
728  }
729 
730  template<typename Stream, boost::endian::order O, class T, std::size_t N, boost::endian::align A>
731  void pack( Stream& s, const boost::endian::endian_buffer<O,T,N,A>& v, uint32_t _max_depth )
732  {
733  FC_ASSERT( _max_depth > 0 );
734  s.write( (char*)v.data(), sizeof(v) );
735  }
736  template<typename Stream, boost::endian::order O, class T, std::size_t N, boost::endian::align A>
737  void unpack( Stream& s, boost::endian::endian_buffer<O,T,N,A>& v, uint32_t _max_depth )
738  {
739  FC_ASSERT( _max_depth > 0 );
740  s.read( (char*)&v, sizeof(v) );
741  }
742 
743 
744  template<typename Stream, typename T>
745  void pack( Stream& s, const T& v, uint32_t _max_depth ) {
746  FC_ASSERT( _max_depth > 0 );
748  }
749  template<typename Stream, typename T>
750  void unpack( Stream& s, T& v, uint32_t _max_depth )
751  { try {
752  FC_ASSERT( _max_depth > 0 );
754  } FC_RETHROW_EXCEPTIONS( warn, "error unpacking ${type}", ("type",fc::get_typename<T>::name() ) ) }
755 
756  template<typename T>
757  inline size_t pack_size( const T& v )
758  {
760  fc::raw::pack( ps, v );
761  return ps.tellp();
762  }
763 
764  template<typename T>
765  inline std::vector<char> pack( const T& v, uint32_t _max_depth ) {
766  FC_ASSERT( _max_depth > 0 );
767  --_max_depth;
769  fc::raw::pack( ps, v, _max_depth );
770  std::vector<char> vec(ps.tellp());
771 
772  if( vec.size() ) {
773  datastream<char*> ds( vec.data(), size_t(vec.size()) );
774  fc::raw::pack( ds, v, _max_depth );
775  }
776  return vec;
777  }
778 
779  template<typename T, typename... Next>
780  inline std::vector<char> pack( const T& v, Next... next, uint32_t _max_depth ) {
781  FC_ASSERT( _max_depth > 0 );
782  --_max_depth;
784  fc::raw::pack( ps, v, next..., _max_depth );
785  std::vector<char> vec(ps.tellp());
786 
787  if( vec.size() ) {
788  datastream<char*> ds( vec.data(), size_t(vec.size()) );
789  fc::raw::pack( ds, v, next..., _max_depth );
790  }
791  return vec;
792  }
793 
794 
795  template<typename T>
796  inline T unpack( const std::vector<char>& s, uint32_t _max_depth )
797  { try {
798  FC_ASSERT( _max_depth > 0 );
799  T tmp;
800  if( s.size() ) {
801  datastream<const char*> ds( s.data(), size_t(s.size()) );
802  fc::raw::unpack( ds, tmp, _max_depth - 1 );
803  }
804  return tmp;
805  } FC_RETHROW_EXCEPTIONS( warn, "error unpacking ${type}", ("type",fc::get_typename<T>::name() ) ) }
806 
807  template<typename T>
808  inline void unpack( const std::vector<char>& s, T& tmp, uint32_t _max_depth )
809  { try {
810  FC_ASSERT( _max_depth > 0 );
811  if( s.size() ) {
812  datastream<const char*> ds( s.data(), size_t(s.size()) );
813  fc::raw::unpack( ds, tmp, _max_depth - 1 );
814  }
815  } FC_RETHROW_EXCEPTIONS( warn, "error unpacking ${type}", ("type",fc::get_typename<T>::name() ) ) }
816 
817  template<typename T>
818  inline void pack( char* d, uint32_t s, const T& v, uint32_t _max_depth ) {
819  FC_ASSERT( _max_depth > 0 );
820  datastream<char*> ds(d,s);
821  fc::raw::pack( ds, v, _max_depth - 1 );
822  }
823 
824  template<typename T>
825  inline T unpack( const char* d, uint32_t s, uint32_t _max_depth )
826  { try {
827  FC_ASSERT( _max_depth > 0 );
828  T v;
829  datastream<const char*> ds( d, s );
830  fc::raw::unpack( ds, v, _max_depth - 1 );
831  return v;
832  } FC_RETHROW_EXCEPTIONS( warn, "error unpacking ${type}", ("type",fc::get_typename<T>::name() ) ) }
833 
834  template<typename T>
835  inline void unpack( const char* d, uint32_t s, T& v, uint32_t _max_depth )
836  { try {
837  FC_ASSERT( _max_depth > 0 );
838  datastream<const char*> ds( d, s );
839  fc::raw::unpack( ds, v, _max_depth - 1 );
840  } FC_RETHROW_EXCEPTIONS( warn, "error unpacking ${type}", ("type",fc::get_typename<T>::name() ) ) }
841 
842  template<typename Stream>
844  {
845  Stream& stream;
846  const uint32_t max_depth;
847  pack_static_variant( Stream& s, uint32_t _max_depth ):stream(s),max_depth(_max_depth - 1)
848  {
849  FC_ASSERT( _max_depth > 0 );
850  }
851 
852  typedef void result_type;
853  template<typename T> void operator()( const T& v )const
854  {
855  fc::raw::pack( stream, v, max_depth );
856  }
857  };
858 
859  template<typename Stream>
861  {
862  Stream& stream;
863  const uint32_t max_depth;
864  unpack_static_variant( Stream& s, uint32_t _max_depth ) : stream(s),max_depth(_max_depth - 1)
865  {
866  FC_ASSERT( _max_depth > 0 );
867  }
868 
869  typedef void result_type;
870  template<typename T> void operator()( T& v )const
871  {
872  fc::raw::unpack( stream, v, max_depth );
873  }
874  };
875 
876 
877  template<typename Stream, typename... T>
878  void pack( Stream& s, const static_variant<T...>& sv, uint32_t _max_depth )
879  {
880  FC_ASSERT( _max_depth > 0 );
881  --_max_depth;
882  fc::raw::pack( s, unsigned_int(sv.which()), _max_depth );
883  sv.visit( pack_static_variant<Stream>( s, _max_depth ) );
884  }
885 
886  template<typename Stream, typename... T> void unpack( Stream& s, static_variant<T...>& sv, uint32_t _max_depth )
887  {
888  FC_ASSERT( _max_depth > 0 );
889  --_max_depth;
890  unsigned_int w;
891  fc::raw::unpack( s, w, _max_depth );
892  sv.set_which(w.value);
893  sv.visit( unpack_static_variant<Stream>( s, _max_depth ) );
894  }
895 
896 } } // namespace fc::raw
897 
Used to forward declare value types.
Definition: fwd.hpp:10
static void unpack(Stream &s, uint64_t &v, uint32_t _max_depth)
Definition: raw.hpp:397
static void unpack(Stream &s, T &v, uint32_t _max_depth)
Definition: raw.hpp:531
void unpack(Stream &s, static_variant< T... > &sv, uint32_t _max_depth)
Definition: raw.hpp:886
void operator()(const char *name) const
Definition: raw.hpp:349
void operator()(T &v) const
Definition: raw.hpp:870
T as(uint32_t max_depth) const
Definition: variant.hpp:336
void pack(Stream &s, const flat_set< T, A... > &value, uint32_t _max_depth)
Definition: flat.hpp:11
uint32_t sec_since_epoch() const
Definition: time.hpp:90
static void pack(Stream &s, const T &v, uint32_t _max_depth)
Definition: raw.hpp:497
Defines types and macros used to provide reflection.
pack_static_variant(Stream &s, uint32_t _max_depth)
Definition: raw.hpp:847
unpack_object_visitor(Class &_c, Stream &_s, uint32_t _max_depth)
Definition: raw.hpp:343
const uint32_t max_depth
Definition: raw.hpp:863
static void unpack(Stream &s, uint8_t &v, uint32_t _max_depth)
Definition: raw.hpp:487
static void unpack(Stream &s, int8_t &v, uint32_t _max_depth)
Definition: raw.hpp:475
Used to generate a useful error report when an exception is thrown.At each level in the stack where t...
Definition: exception.hpp:56
size_t tellp() const
Definition: datastream.hpp:85
static void pack(Stream &s, const int8_t v, uint32_t _max_depth)
Definition: raw.hpp:471
void unpack(Stream &s, flat_set< T, A... > &value, uint32_t _max_depth)
Definition: flat.hpp:23
#define FC_RETHROW_EXCEPTIONS(LOG_LEVEL, FORMAT,...)
Catchs all exception&#39;s, std::exceptions, and ... and rethrows them after appending the provided log m...
Definition: exception.hpp:463
const uint32_t max_depth
Definition: raw.hpp:846
visitor::result_type visit(visitor &v)
uint64_t uint128_hi64(const uint128_t &x)
Definition: uint128.hpp:57
std::string generic_string() const
Definition: filesystem.cpp:95
int64_t code() const
Definition: exception.cpp:141
tag_type which() const
static void unpack(Stream &s, T &v, uint32_t _max_depth)
Definition: raw.hpp:502
#define FC_MAX_LOG_OBJECT_DEPTH
Definition: config.hpp:8
provides stack-based nullable value similar to boost::optional
Definition: optional.hpp:20
static void pack(Stream &s, const uint32_t v, uint32_t _max_depth)
Definition: raw.hpp:423
uint128_t uint128(const uint64_t hi, const uint64_t lo)
Definition: uint128.hpp:67
static void unpack(Stream &s, uint32_t &v, uint32_t _max_depth)
Definition: raw.hpp:429
unpack_static_variant(Stream &s, uint32_t _max_depth)
Definition: raw.hpp:864
static void pack(Stream &s, const int16_t v, uint32_t _max_depth)
Definition: raw.hpp:439
size_t pack_size(const T &v)
Definition: raw.hpp:757
static void unpack(Stream &s, int32_t &v, uint32_t _max_depth)
Definition: raw.hpp:413
static void pack(Stream &s, const T &v, uint32_t _max_depth)
Definition: raw.hpp:539
static void pack(Stream &s, const uint8_t v, uint32_t _max_depth)
Definition: raw.hpp:483
static void pack(Stream &s, const uint16_t v, uint32_t _max_depth)
Definition: raw.hpp:455
void operator()(const T &v) const
Definition: raw.hpp:853
defines visit functions for T Unless this is specialized, visit() will not be defined for T...
Definition: reflect.hpp:25
microseconds seconds(int64_t s)
Definition: time.hpp:34
int64_t count() const
Definition: time.hpp:28
static void unpack(Stream &s, uint16_t &v, uint32_t _max_depth)
Definition: raw.hpp:461
const char * name() const
Definition: exception.cpp:139
std::vector< log_message > log_messages
static void pack(Stream &s, const uint64_t v, uint32_t _max_depth)
Definition: raw.hpp:391
#define FC_ASSERT(TEST,...)
Checks a condition and throws an assert_exception if the test is FALSE.
Definition: exception.hpp:345
virtual const char * what() const
Definition: exception.cpp:140
stores null, int64, uint64, double, bool, string, std::vector<variant>, and variant_object&#39;s.
Definition: variant.hpp:198
#define FC_THROW_EXCEPTION(EXCEPTION, FORMAT,...)
Definition: exception.hpp:378
const log_messages & get_log() const
Definition: exception.cpp:172
Defines exception&#39;s used by fc.
void pack(Stream &s, const static_variant< T... > &sv, uint32_t _max_depth)
Definition: raw.hpp:878
static void unpack(Stream &s, T &v, uint32_t _max_depth)
Definition: raw.hpp:515
const microseconds & time_since_epoch() const
Definition: time.hpp:54
static void unpack(Stream &s, int64_t &v, uint32_t _max_depth)
Definition: raw.hpp:381
aggregates a message along with the context and associated meta-information.
#define FC_MAX_PREALLOC_SIZE
Definition: config.hpp:13
#define MAX_ARRAY_ALLOC_SIZE
Definition: raw_fwd.hpp:19
uint64_t uint128_lo64(const uint128_t &x)
Definition: uint128.hpp:54
Definition: api.hpp:15
void set_which(tag_type tag)
uint64_t value
Definition: varint.hpp:17
pack_object_visitor(const Class &_c, Stream &_s, uint32_t _max_depth)
Definition: raw.hpp:325
static void pack(Stream &s, const int64_t v, uint32_t _max_depth)
Definition: raw.hpp:375
static void pack(Stream &s, const int32_t v, uint32_t _max_depth)
Definition: raw.hpp:407
static void unpack(Stream &s, int16_t &v, uint32_t _max_depth)
Definition: raw.hpp:445
void operator()(const char *name) const
Definition: raw.hpp:332
wraps boost::filesystem::path to provide platform independent path manipulation.
Definition: filesystem.hpp:28
static void pack(Stream &s, const T &v, uint32_t _max_depth)
Definition: raw.hpp:526
static void unpack(Stream &s, T &v, uint32_t _max_depth)
Definition: raw.hpp:544
static void pack(Stream &s, const T &v, uint32_t _max_depth)
Definition: raw.hpp:510
T value
Definition: safe.hpp:22