MessagePack for C++
unpack.hpp
Go to the documentation of this file.
1 //
2 // MessagePack for C++ deserializing routine
3 //
4 // Copyright (C) 2008-2016 FURUHASHI Sadayuki and KONDO Takatoshi
5 //
6 // Distributed under the Boost Software License, Version 1.0.
7 // (See accompanying file LICENSE_1_0.txt or copy at
8 // http://www.boost.org/LICENSE_1_0.txt)
9 //
10 #ifndef MSGPACK_V1_UNPACK_HPP
11 #define MSGPACK_V1_UNPACK_HPP
12 
13 #include "msgpack/versioning.hpp"
14 #include "msgpack/unpack_decl.hpp"
15 #include "msgpack/object.hpp"
16 #include "msgpack/zone.hpp"
19 #include "msgpack/cpp_config.hpp"
20 #include "msgpack/sysdep.hpp"
21 #include "msgpack/assert.hpp"
22 
23 #include <memory>
24 
25 
26 #if !defined(MSGPACK_USE_CPP03)
27 #include <atomic>
28 #endif
29 
30 #if defined(_MSC_VER)
31 // avoiding confliction std::max, std::min, and macro in windows.h
32 #ifndef NOMINMAX
33 #define NOMINMAX
34 #endif
35 #endif // defined(_MSC_VER)
36 
37 namespace msgpack {
38 
42 
43 namespace detail {
44 
45 class unpack_user {
46 public:
48  void* user_data = MSGPACK_NULLPTR,
49  unpack_limit const& limit = unpack_limit())
50  :m_func(f), m_user_data(user_data), m_limit(limit) {}
51  msgpack::zone const& zone() const { return *m_zone; }
52  msgpack::zone& zone() { return *m_zone; }
53  void set_zone(msgpack::zone& zone) { m_zone = &zone; }
54  bool referenced() const { return m_referenced; }
55  void set_referenced(bool referenced) { m_referenced = referenced; }
56  unpack_reference_func reference_func() const { return m_func; }
57  void* user_data() const { return m_user_data; }
58  unpack_limit const& limit() const { return m_limit; }
59  unpack_limit& limit() { return m_limit; }
60 
61 private:
62  msgpack::zone* m_zone;
63  bool m_referenced;
64  unpack_reference_func m_func;
65  void* m_user_data;
66  unpack_limit m_limit;
67 };
68 
69 inline void unpack_uint8(uint8_t d, msgpack::object& o)
71 
72 inline void unpack_uint16(uint16_t d, msgpack::object& o)
74 
75 inline void unpack_uint32(uint32_t d, msgpack::object& o)
77 
78 inline void unpack_uint64(uint64_t d, msgpack::object& o)
80 
81 inline void unpack_int8(int8_t d, msgpack::object& o)
82 { if(d >= 0) { o.type = msgpack::type::POSITIVE_INTEGER; o.via.u64 = static_cast<uint64_t>(d); }
83  else { o.type = msgpack::type::NEGATIVE_INTEGER; o.via.i64 = d; } }
84 
85 inline void unpack_int16(int16_t d, msgpack::object& o)
86 { if(d >= 0) { o.type = msgpack::type::POSITIVE_INTEGER; o.via.u64 = static_cast<uint64_t>(d); }
87  else { o.type = msgpack::type::NEGATIVE_INTEGER; o.via.i64 = d; } }
88 
89 inline void unpack_int32(int32_t d, msgpack::object& o)
90 { if(d >= 0) { o.type = msgpack::type::POSITIVE_INTEGER; o.via.u64 = static_cast<uint64_t>(d); }
91  else { o.type = msgpack::type::NEGATIVE_INTEGER; o.via.i64 = d; } }
92 
93 inline void unpack_int64(int64_t d, msgpack::object& o)
94 { if(d >= 0) { o.type = msgpack::type::POSITIVE_INTEGER; o.via.u64 = static_cast<uint64_t>(d); }
95  else { o.type = msgpack::type::NEGATIVE_INTEGER; o.via.i64 = d; } }
96 
97 inline void unpack_float(float d, msgpack::object& o)
98 { o.type = msgpack::type::FLOAT32; o.via.f64 = d; }
99 
100 inline void unpack_double(double d, msgpack::object& o)
101 { o.type = msgpack::type::FLOAT64; o.via.f64 = d; }
102 
104 { o.type = msgpack::type::NIL; }
105 
107 { o.type = msgpack::type::BOOLEAN; o.via.boolean = true; }
108 
110 { o.type = msgpack::type::BOOLEAN; o.via.boolean = false; }
111 
112 struct unpack_array {
113  void operator()(unpack_user& u, uint32_t n, msgpack::object& o) const {
114  if (n > u.limit().array()) throw msgpack::array_size_overflow("array size overflow");
116  o.via.array.size = 0;
117 
118 #if SIZE_MAX == UINT_MAX
119  if (n > SIZE_MAX/sizeof(msgpack::object))
120  throw msgpack::array_size_overflow("array size overflow");
121 #endif // SIZE_MAX == UINT_MAX
122 
123  size_t size = n*sizeof(msgpack::object);
125  }
126 };
127 
129 {
130 #if defined(__GNUC__) && !defined(__clang__)
131  std::memcpy(&c.via.array.ptr[c.via.array.size++], &o, sizeof(msgpack::object));
132 
133 #else /* __GNUC__ && !__clang__ */
134  c.via.array.ptr[c.via.array.size++] = o;
135 #endif /* __GNUC__ && !__clang__ */
136 }
137 
138 struct unpack_map {
139  void operator()(unpack_user& u, uint32_t n, msgpack::object& o) const {
140  if (n > u.limit().map()) throw msgpack::map_size_overflow("map size overflow");
142  o.via.map.size = 0;
143 
144 #if SIZE_MAX == UINT_MAX
145  if (n > SIZE_MAX/sizeof(msgpack::object_kv))
146  throw msgpack::map_size_overflow("map size overflow");
147 #endif // SIZE_MAX == UINT_MAX
148 
149  size_t size = n*sizeof(msgpack::object_kv);
151  }
152 };
153 
155 {
156 #if defined(__GNUC__) && !defined(__clang__)
157  std::memcpy(&c.via.map.ptr[c.via.map.size].key, &k, sizeof(msgpack::object));
158  std::memcpy(&c.via.map.ptr[c.via.map.size].val, &v, sizeof(msgpack::object));
159 #else /* __GNUC__ && !__clang__ */
160  c.via.map.ptr[c.via.map.size].key = k;
161  c.via.map.ptr[c.via.map.size].val = v;
162 #endif /* __GNUC__ && !__clang__ */
163  ++c.via.map.size;
164 }
165 
166 inline void unpack_str(unpack_user& u, const char* p, uint32_t l, msgpack::object& o)
167 {
169  if (u.reference_func() && u.reference_func()(o.type, l, u.user_data())) {
170  o.via.str.ptr = p;
171  u.set_referenced(true);
172  }
173  else if (l > 0) {
174  if (l > u.limit().str()) throw msgpack::str_size_overflow("str size overflow");
175  char* tmp = static_cast<char*>(u.zone().allocate_align(l, MSGPACK_ZONE_ALIGNOF(char)));
176  std::memcpy(tmp, p, l);
177  o.via.str.ptr = tmp;
178  }
179  else {
181  }
182  o.via.str.size = l;
183 }
184 
185 inline void unpack_bin(unpack_user& u, const char* p, uint32_t l, msgpack::object& o)
186 {
188  if (u.reference_func() && u.reference_func()(o.type, l, u.user_data())) {
189  o.via.bin.ptr = p;
190  u.set_referenced(true);
191  }
192  else if (l > 0) {
193  if (l > u.limit().bin()) throw msgpack::bin_size_overflow("bin size overflow");
194  char* tmp = static_cast<char*>(u.zone().allocate_align(l, MSGPACK_ZONE_ALIGNOF(char)));
195  std::memcpy(tmp, p, l);
196  o.via.bin.ptr = tmp;
197  }
198  else {
200  }
201  o.via.bin.size = l;
202 }
203 
204 inline void unpack_ext(unpack_user& u, const char* p, std::size_t l, msgpack::object& o)
205 {
207  if (u.reference_func() && u.reference_func()(o.type, l, u.user_data())) {
208  o.via.ext.ptr = p;
209  u.set_referenced(true);
210  }
211  else {
212  if (l > u.limit().ext()) throw msgpack::ext_size_overflow("ext size overflow");
213  char* tmp = static_cast<char*>(u.zone().allocate_align(l, MSGPACK_ZONE_ALIGNOF(char)));
214  std::memcpy(tmp, p, l);
215  o.via.ext.ptr = tmp;
216  }
217  o.via.ext.size = static_cast<uint32_t>(l - 1);
218 }
219 
220 
222 public:
223  msgpack::object const& obj() const { return m_obj; }
224  msgpack::object& obj() { return m_obj; }
225  void set_obj(msgpack::object const& obj) { m_obj = obj; }
226  std::size_t count() const { return m_count; }
227  void set_count(std::size_t count) { m_count = count; }
228  std::size_t decr_count() { return --m_count; }
229  uint32_t container_type() const { return m_container_type; }
230  void set_container_type(uint32_t container_type) { m_container_type = container_type; }
231  msgpack::object const& map_key() const { return m_map_key; }
232  void set_map_key(msgpack::object const& map_key) { m_map_key = map_key; }
233 private:
234  msgpack::object m_obj;
235  std::size_t m_count;
236  uint32_t m_container_type;
237  msgpack::object m_map_key;
238 };
239 
240 inline void init_count(void* buffer)
241 {
242 #if defined(MSGPACK_USE_CPP03)
243  *reinterpret_cast<volatile _msgpack_atomic_counter_t*>(buffer) = 1;
244 #else // defined(MSGPACK_USE_CPP03)
245  new (buffer) std::atomic<unsigned int>(1);
246 #endif // defined(MSGPACK_USE_CPP03)
247 }
248 
249 inline void decr_count(void* buffer)
250 {
251 #if defined(MSGPACK_USE_CPP03)
252  if(_msgpack_sync_decr_and_fetch(reinterpret_cast<volatile _msgpack_atomic_counter_t*>(buffer)) == 0) {
253  free(buffer);
254  }
255 #else // defined(MSGPACK_USE_CPP03)
256  if (--*reinterpret_cast<std::atomic<unsigned int>*>(buffer) == 0) {
257  free(buffer);
258  }
259 #endif // defined(MSGPACK_USE_CPP03)
260 }
261 
262 inline void incr_count(void* buffer)
263 {
264 #if defined(MSGPACK_USE_CPP03)
265  _msgpack_sync_incr_and_fetch(reinterpret_cast<volatile _msgpack_atomic_counter_t*>(buffer));
266 #else // defined(MSGPACK_USE_CPP03)
267  ++*reinterpret_cast<std::atomic<unsigned int>*>(buffer);
268 #endif // defined(MSGPACK_USE_CPP03)
269 }
270 
271 #if defined(MSGPACK_USE_CPP03)
272 inline _msgpack_atomic_counter_t get_count(void* buffer)
273 {
274  return *reinterpret_cast<volatile _msgpack_atomic_counter_t*>(buffer);
275 }
276 #else // defined(MSGPACK_USE_CPP03)
277 inline std::atomic<unsigned int> const& get_count(void* buffer)
278 {
279  return *reinterpret_cast<std::atomic<unsigned int>*>(buffer);
280 }
281 #endif // defined(MSGPACK_USE_CPP03)
282 
283 template <typename T>
284 struct value {
285  typedef T type;
286 };
287 template <>
288 struct value<fix_tag> {
289  typedef uint32_t type;
290 };
291 
292 template <typename T>
293 inline typename msgpack::enable_if<sizeof(T) == sizeof(fix_tag)>::type load(uint32_t& dst, const char* n) {
294  dst = static_cast<uint32_t>(*reinterpret_cast<const uint8_t*>(n)) & 0x0f;
295 }
296 
297 template <typename T>
298 inline typename msgpack::enable_if<sizeof(T) == 1>::type load(T& dst, const char* n) {
299  dst = static_cast<T>(*reinterpret_cast<const uint8_t*>(n));
300 }
301 
302 template <typename T>
303 inline typename msgpack::enable_if<sizeof(T) == 2>::type load(T& dst, const char* n) {
304  _msgpack_load16(T, n, &dst);
305 }
306 
307 template <typename T>
308 inline typename msgpack::enable_if<sizeof(T) == 4>::type load(T& dst, const char* n) {
309  _msgpack_load32(T, n, &dst);
310 }
311 
312 template <typename T>
313 inline typename msgpack::enable_if<sizeof(T) == 8>::type load(T& dst, const char* n) {
314  _msgpack_load64(T, n, &dst);
315 }
316 
317 class context {
318 public:
319  context(unpack_reference_func f, void* user_data, unpack_limit const& limit)
320  :m_trail(0), m_user(f, user_data, limit), m_cs(MSGPACK_CS_HEADER)
321  {
322  m_stack.reserve(MSGPACK_EMBED_STACK_SIZE);
323  m_stack.push_back(unpack_stack());
324  }
325 
326  void init()
327  {
328  m_cs = MSGPACK_CS_HEADER;
329  m_trail = 0;
330  m_stack.resize(1);
331  m_stack[0].set_obj(msgpack::object());
332  }
333 
334  msgpack::object const& data() const
335  {
336  return m_stack[0].obj();
337  }
338 
340  {
341  return m_user;
342  }
343 
344  unpack_user const& user() const
345  {
346  return m_user;
347  }
348 
349  int execute(const char* data, std::size_t len, std::size_t& off);
350 
351 private:
352  template <typename T>
353  static uint32_t next_cs(T p)
354  {
355  return static_cast<uint32_t>(*p) & 0x1f;
356  }
357 
358  template <typename T, typename Func>
359  int push_aggregate(
360  Func const& f,
361  uint32_t container_type,
362  msgpack::object& obj,
363  const char* load_pos,
364  std::size_t& off) {
365  typename value<T>::type tmp;
366  load<T>(tmp, load_pos);
367  f(m_user, tmp, m_stack.back().obj());
368  if(tmp == 0) {
369  obj = m_stack.back().obj();
370  int ret = push_proc(obj, off);
371  if (ret != 0) return ret;
372  }
373  else {
374  m_stack.back().set_container_type(container_type);
375  m_stack.back().set_count(tmp);
376  if (m_stack.size() <= m_user.limit().depth()) {
377  m_stack.push_back(unpack_stack());
378  }
379  else {
380  throw msgpack::depth_size_overflow("depth size overflow");
381  }
382  m_cs = MSGPACK_CS_HEADER;
383  ++m_current;
384  }
385  return 0;
386  }
387 
388  int push_item(msgpack::object& obj) {
389  bool finish = false;
390  while (!finish) {
391  if(m_stack.size() == 1) {
392  return 1;
393  }
394  unpack_stack& sp = *(m_stack.end() - 2);
395  switch(sp.container_type()) {
397  unpack_array_item(sp.obj(), obj);
398  if(sp.decr_count() == 0) {
399  obj = sp.obj();
400  m_stack.pop_back();
401  }
402  else {
403  finish = true;
404  }
405  break;
406  case MSGPACK_CT_MAP_KEY:
407  sp.set_map_key(obj);
408  sp.set_container_type(MSGPACK_CT_MAP_VALUE);
409  finish = true;
410  break;
412  unpack_map_item(sp.obj(), sp.map_key(), obj);
413  if(sp.decr_count() == 0) {
414  obj = sp.obj();
415  m_stack.pop_back();
416  }
417  else {
418  sp.set_container_type(MSGPACK_CT_MAP_KEY);
419  finish = true;
420  }
421  break;
422  default:
423  return -1;
424  }
425  }
426  return 0;
427  }
428 
429  int push_proc(msgpack::object& obj, std::size_t& off) {
430  int ret = push_item(obj);
431  if (ret > 0) {
432  m_stack[0].set_obj(obj);
433  ++m_current;
434  /*printf("-- finish --\n"); */
435  off = static_cast<std::size_t>(m_current - m_start);
436  }
437  else if (ret < 0) {
438  off = static_cast<std::size_t>(m_current - m_start);
439  }
440  else {
441  m_cs = MSGPACK_CS_HEADER;
442  ++m_current;
443  }
444  return ret;
445  }
446 
447  template <std::size_t N>
448  static void check_ext_size(std::size_t /*size*/) {
449  }
450 
451 private:
452  char const* m_start;
453  char const* m_current;
454 
455  std::size_t m_trail;
456  unpack_user m_user;
457  uint32_t m_cs;
458  std::vector<unpack_stack> m_stack;
459 };
460 
461 template <>
462 inline void context::check_ext_size<4>(std::size_t size) {
463  if (size == 0xffffffff) throw msgpack::ext_size_overflow("ext size overflow");
464 }
465 
466 inline int context::execute(const char* data, std::size_t len, std::size_t& off)
467 {
468  MSGPACK_ASSERT(len >= off);
469 
470  m_start = data;
471  m_current = data + off;
472  const char* const pe = data + len;
473  const char* n = MSGPACK_NULLPTR;
474 
475  msgpack::object obj;
476 
477  if(m_current == pe) {
478  off = static_cast<std::size_t>(m_current - m_start);
479  return 0;
480  }
481  bool fixed_trail_again = false;
482  do {
483  if (m_cs == MSGPACK_CS_HEADER) {
484  fixed_trail_again = false;
485  int selector = *reinterpret_cast<const unsigned char*>(m_current);
486  if (0x00 <= selector && selector <= 0x7f) { // Positive Fixnum
487  unpack_uint8(*reinterpret_cast<const uint8_t*>(m_current), obj);
488  int ret = push_proc(obj, off);
489  if (ret != 0) return ret;
490  } else if(0xe0 <= selector && selector <= 0xff) { // Negative Fixnum
491  unpack_int8(*reinterpret_cast<const int8_t*>(m_current), obj);
492  int ret = push_proc(obj, off);
493  if (ret != 0) return ret;
494  } else if (0xc4 <= selector && selector <= 0xdf) {
495  const uint32_t trail[] = {
496  1, // bin 8 0xc4
497  2, // bin 16 0xc5
498  4, // bin 32 0xc6
499  1, // ext 8 0xc7
500  2, // ext 16 0xc8
501  4, // ext 32 0xc9
502  4, // float 32 0xca
503  8, // float 64 0xcb
504  1, // uint 8 0xcc
505  2, // uint 16 0xcd
506  4, // uint 32 0xce
507  8, // uint 64 0xcf
508  1, // int 8 0xd0
509  2, // int 16 0xd1
510  4, // int 32 0xd2
511  8, // int 64 0xd3
512  2, // fixext 1 0xd4
513  3, // fixext 2 0xd5
514  5, // fixext 4 0xd6
515  9, // fixext 8 0xd7
516  17,// fixext 16 0xd8
517  1, // str 8 0xd9
518  2, // str 16 0xda
519  4, // str 32 0xdb
520  2, // array 16 0xdc
521  4, // array 32 0xdd
522  2, // map 16 0xde
523  4, // map 32 0xdf
524  };
525  m_trail = trail[selector - 0xc4];
526  m_cs = next_cs(m_current);
527  fixed_trail_again = true;
528  } else if(0xa0 <= selector && selector <= 0xbf) { // FixStr
529  m_trail = static_cast<uint32_t>(*m_current) & 0x1f;
530  if(m_trail == 0) {
531  unpack_str(m_user, n, static_cast<uint32_t>(m_trail), obj);
532  int ret = push_proc(obj, off);
533  if (ret != 0) return ret;
534  }
535  else {
536  m_cs = MSGPACK_ACS_STR_VALUE;
537  fixed_trail_again = true;
538  }
539 
540  } else if(0x90 <= selector && selector <= 0x9f) { // FixArray
541  int ret = push_aggregate<fix_tag>(
542  unpack_array(), MSGPACK_CT_ARRAY_ITEM, obj, m_current, off);
543  if (ret != 0) return ret;
544  } else if(0x80 <= selector && selector <= 0x8f) { // FixMap
545  int ret = push_aggregate<fix_tag>(
546  unpack_map(), MSGPACK_CT_MAP_KEY, obj, m_current, off);
547  if (ret != 0) return ret;
548  } else if(selector == 0xc2) { // false
549  unpack_false(obj);
550  int ret = push_proc(obj, off);
551  if (ret != 0) return ret;
552  } else if(selector == 0xc3) { // true
553  unpack_true(obj);
554  int ret = push_proc(obj, off);
555  if (ret != 0) return ret;
556  } else if(selector == 0xc0) { // nil
557  unpack_nil(obj);
558  int ret = push_proc(obj, off);
559  if (ret != 0) return ret;
560  } else {
561  off = static_cast<std::size_t>(m_current - m_start);
562  return -1;
563  }
564  // end MSGPACK_CS_HEADER
565  }
566  if (m_cs != MSGPACK_CS_HEADER || fixed_trail_again) {
567  if (fixed_trail_again) {
568  ++m_current;
569  fixed_trail_again = false;
570  }
571  if(static_cast<std::size_t>(pe - m_current) < m_trail) {
572  off = static_cast<std::size_t>(m_current - m_start);
573  return 0;
574  }
575  n = m_current;
576  m_current += m_trail - 1;
577  switch(m_cs) {
578  //case MSGPACK_CS_
579  //case MSGPACK_CS_
580  case MSGPACK_CS_FLOAT: {
581  union { uint32_t i; float f; } mem;
582  load<uint32_t>(mem.i, n);
583  unpack_float(mem.f, obj);
584  int ret = push_proc(obj, off);
585  if (ret != 0) return ret;
586  } break;
587  case MSGPACK_CS_DOUBLE: {
588  union { uint64_t i; double f; } mem;
589  load<uint64_t>(mem.i, n);
590 #if defined(TARGET_OS_IPHONE)
591  // ok
592 #elif defined(__arm__) && !(__ARM_EABI__) // arm-oabi
593  // https://github.com/msgpack/msgpack-perl/pull/1
594  mem.i = (mem.i & 0xFFFFFFFFUL) << 32UL | (mem.i >> 32UL);
595 #endif
596  unpack_double(mem.f, obj);
597  int ret = push_proc(obj, off);
598  if (ret != 0) return ret;
599  } break;
600  case MSGPACK_CS_UINT_8: {
601  uint8_t tmp;
602  load<uint8_t>(tmp, n);
603  unpack_uint8(tmp, obj);
604  int ret = push_proc(obj, off);
605  if (ret != 0) return ret;
606  } break;
607  case MSGPACK_CS_UINT_16: {
608  uint16_t tmp;
609  load<uint16_t>(tmp, n);
610  unpack_uint16(tmp, obj);
611  int ret = push_proc(obj, off);
612  if (ret != 0) return ret;
613  } break;
614  case MSGPACK_CS_UINT_32: {
615  uint32_t tmp;
616  load<uint32_t>(tmp, n);
617  unpack_uint32(tmp, obj);
618  int ret = push_proc(obj, off);
619  if (ret != 0) return ret;
620  } break;
621  case MSGPACK_CS_UINT_64: {
622  uint64_t tmp;
623  load<uint64_t>(tmp, n);
624  unpack_uint64(tmp, obj);
625  int ret = push_proc(obj, off);
626  if (ret != 0) return ret;
627  } break;
628  case MSGPACK_CS_INT_8: {
629  int8_t tmp;
630  load<int8_t>(tmp, n);
631  unpack_int8(tmp, obj);
632  int ret = push_proc(obj, off);
633  if (ret != 0) return ret;
634  } break;
635  case MSGPACK_CS_INT_16: {
636  int16_t tmp;
637  load<int16_t>(tmp, n);
638  unpack_int16(tmp, obj);
639  int ret = push_proc(obj, off);
640  if (ret != 0) return ret;
641  } break;
642  case MSGPACK_CS_INT_32: {
643  int32_t tmp;
644  load<int32_t>(tmp, n);
645  unpack_int32(tmp, obj);
646  int ret = push_proc(obj, off);
647  if (ret != 0) return ret;
648  } break;
649  case MSGPACK_CS_INT_64: {
650  int64_t tmp;
651  load<int64_t>(tmp, n);
652  unpack_int64(tmp, obj);
653  int ret = push_proc(obj, off);
654  if (ret != 0) return ret;
655  } break;
656  case MSGPACK_CS_FIXEXT_1: {
657  unpack_ext(m_user, n, 1+1, obj);
658  int ret = push_proc(obj, off);
659  if (ret != 0) return ret;
660  } break;
661  case MSGPACK_CS_FIXEXT_2: {
662  unpack_ext(m_user, n, 2+1, obj);
663  int ret = push_proc(obj, off);
664  if (ret != 0) return ret;
665  } break;
666  case MSGPACK_CS_FIXEXT_4: {
667  unpack_ext(m_user, n, 4+1, obj);
668  int ret = push_proc(obj, off);
669  if (ret != 0) return ret;
670  } break;
671  case MSGPACK_CS_FIXEXT_8: {
672  unpack_ext(m_user, n, 8+1, obj);
673  int ret = push_proc(obj, off);
674  if (ret != 0) return ret;
675  } break;
676  case MSGPACK_CS_FIXEXT_16: {
677  unpack_ext(m_user, n, 16+1, obj);
678  int ret = push_proc(obj, off);
679  if (ret != 0) return ret;
680  } break;
681  case MSGPACK_CS_STR_8: {
682  uint8_t tmp;
683  load<uint8_t>(tmp, n);
684  m_trail = tmp;
685  if(m_trail == 0) {
686  unpack_str(m_user, n, static_cast<uint32_t>(m_trail), obj);
687  int ret = push_proc(obj, off);
688  if (ret != 0) return ret;
689  }
690  else {
691  m_cs = MSGPACK_ACS_STR_VALUE;
692  fixed_trail_again = true;
693  }
694  } break;
695  case MSGPACK_CS_BIN_8: {
696  uint8_t tmp;
697  load<uint8_t>(tmp, n);
698  m_trail = tmp;
699  if(m_trail == 0) {
700  unpack_bin(m_user, n, static_cast<uint32_t>(m_trail), obj);
701  int ret = push_proc(obj, off);
702  if (ret != 0) return ret;
703  }
704  else {
705  m_cs = MSGPACK_ACS_BIN_VALUE;
706  fixed_trail_again = true;
707  }
708  } break;
709  case MSGPACK_CS_EXT_8: {
710  uint8_t tmp;
711  load<uint8_t>(tmp, n);
712  m_trail = tmp + 1;
713  if(m_trail == 0) {
714  unpack_ext(m_user, n, m_trail, obj);
715  int ret = push_proc(obj, off);
716  if (ret != 0) return ret;
717  }
718  else {
719  m_cs = MSGPACK_ACS_EXT_VALUE;
720  fixed_trail_again = true;
721  }
722  } break;
723  case MSGPACK_CS_STR_16: {
724  uint16_t tmp;
725  load<uint16_t>(tmp, n);
726  m_trail = tmp;
727  if(m_trail == 0) {
728  unpack_str(m_user, n, static_cast<uint32_t>(m_trail), obj);
729  int ret = push_proc(obj, off);
730  if (ret != 0) return ret;
731  }
732  else {
733  m_cs = MSGPACK_ACS_STR_VALUE;
734  fixed_trail_again = true;
735  }
736  } break;
737  case MSGPACK_CS_BIN_16: {
738  uint16_t tmp;
739  load<uint16_t>(tmp, n);
740  m_trail = tmp;
741  if(m_trail == 0) {
742  unpack_bin(m_user, n, static_cast<uint32_t>(m_trail), obj);
743  int ret = push_proc(obj, off);
744  if (ret != 0) return ret;
745  }
746  else {
747  m_cs = MSGPACK_ACS_BIN_VALUE;
748  fixed_trail_again = true;
749  }
750  } break;
751  case MSGPACK_CS_EXT_16: {
752  uint16_t tmp;
753  load<uint16_t>(tmp, n);
754  m_trail = tmp + 1;
755  if(m_trail == 0) {
756  unpack_ext(m_user, n, m_trail, obj);
757  int ret = push_proc(obj, off);
758  if (ret != 0) return ret;
759  }
760  else {
761  m_cs = MSGPACK_ACS_EXT_VALUE;
762  fixed_trail_again = true;
763  }
764  } break;
765  case MSGPACK_CS_STR_32: {
766  uint32_t tmp;
767  load<uint32_t>(tmp, n);
768  m_trail = tmp;
769  if(m_trail == 0) {
770  unpack_str(m_user, n, static_cast<uint32_t>(m_trail), obj);
771  int ret = push_proc(obj, off);
772  if (ret != 0) return ret;
773  }
774  else {
775  m_cs = MSGPACK_ACS_STR_VALUE;
776  fixed_trail_again = true;
777  }
778  } break;
779  case MSGPACK_CS_BIN_32: {
780  uint32_t tmp;
781  load<uint32_t>(tmp, n);
782  m_trail = tmp;
783  if(m_trail == 0) {
784  unpack_bin(m_user, n, static_cast<uint32_t>(m_trail), obj);
785  int ret = push_proc(obj, off);
786  if (ret != 0) return ret;
787  }
788  else {
789  m_cs = MSGPACK_ACS_BIN_VALUE;
790  fixed_trail_again = true;
791  }
792  } break;
793  case MSGPACK_CS_EXT_32: {
794  uint32_t tmp;
795  load<uint32_t>(tmp, n);
796  check_ext_size<sizeof(std::size_t)>(tmp);
797  m_trail = tmp;
798  ++m_trail;
799  if(m_trail == 0) {
800  unpack_ext(m_user, n, m_trail, obj);
801  int ret = push_proc(obj, off);
802  if (ret != 0) return ret;
803  }
804  else {
805  m_cs = MSGPACK_ACS_EXT_VALUE;
806  fixed_trail_again = true;
807  }
808  } break;
809  case MSGPACK_ACS_STR_VALUE: {
810  unpack_str(m_user, n, static_cast<uint32_t>(m_trail), obj);
811  int ret = push_proc(obj, off);
812  if (ret != 0) return ret;
813  } break;
814  case MSGPACK_ACS_BIN_VALUE: {
815  unpack_bin(m_user, n, static_cast<uint32_t>(m_trail), obj);
816  int ret = push_proc(obj, off);
817  if (ret != 0) return ret;
818  } break;
819  case MSGPACK_ACS_EXT_VALUE: {
820  unpack_ext(m_user, n, m_trail, obj);
821  int ret = push_proc(obj, off);
822  if (ret != 0) return ret;
823  } break;
824  case MSGPACK_CS_ARRAY_16: {
825  int ret = push_aggregate<uint16_t>(
826  unpack_array(), MSGPACK_CT_ARRAY_ITEM, obj, n, off);
827  if (ret != 0) return ret;
828  } break;
829  case MSGPACK_CS_ARRAY_32: {
830  /* FIXME security guard */
831  int ret = push_aggregate<uint32_t>(
832  unpack_array(), MSGPACK_CT_ARRAY_ITEM, obj, n, off);
833  if (ret != 0) return ret;
834  } break;
835  case MSGPACK_CS_MAP_16: {
836  int ret = push_aggregate<uint16_t>(
837  unpack_map(), MSGPACK_CT_MAP_KEY, obj, n, off);
838  if (ret != 0) return ret;
839  } break;
840  case MSGPACK_CS_MAP_32: {
841  /* FIXME security guard */
842  int ret = push_aggregate<uint32_t>(
843  unpack_map(), MSGPACK_CT_MAP_KEY, obj, n, off);
844  if (ret != 0) return ret;
845  } break;
846  default:
847  off = static_cast<std::size_t>(m_current - m_start);
848  return -1;
849  }
850  }
851  } while(m_current != pe);
852 
853  off = static_cast<std::size_t>(m_current - m_start);
854  return 0;
855 }
856 
857 } // detail
858 
859 
861 class unpacker {
862 public:
864 
871  unpacker(unpack_reference_func f = &unpacker::default_reference_func,
872  void* user_data = MSGPACK_NULLPTR,
873  std::size_t initial_buffer_size = MSGPACK_UNPACKER_INIT_BUFFER_SIZE,
874  unpack_limit const& limit = unpack_limit());
875 
876 #if !defined(MSGPACK_USE_CPP03)
877  unpacker(unpacker&& other);
878  unpacker& operator=(unpacker&& other);
879 #endif // !defined(MSGPACK_USE_CPP03)
880 
881  ~unpacker();
882 
883 public:
885 
893 
895 
900  char* buffer();
901 
903 
909  std::size_t buffer_capacity() const;
910 
912 
921  void buffer_consumed(std::size_t size);
922 
924 
937  MSGPACK_DEPRECATED("please use reference version instead")
938  bool next(msgpack::object_handle* result);
939 
941 
954  bool next(msgpack::object_handle& result, bool& referenced);
955 
957 
968  bool next(msgpack::object_handle& result);
969 
971 
974  std::size_t message_size() const;
975 
977  bool execute();
978 
980  msgpack::object const& data();
981 
984 
986  void reset_zone();
987 
989  void reset();
990 
991 public:
993 
999  std::size_t parsed_size() const;
1000 
1002 
1008  char* nonparsed_buffer();
1009 
1011 
1017  std::size_t nonparsed_size() const;
1018 
1020 
1027  void skip_nonparsed_buffer(std::size_t size);
1028 
1030 
1034  void remove_nonparsed_buffer();
1035 
1036 private:
1037  void expand_buffer(std::size_t size);
1038  int execute_imp();
1039  bool flush_zone();
1040  static bool default_reference_func(msgpack::type::object_type type, std::size_t len, void*);
1041 
1042 private:
1043  char* m_buffer;
1044  std::size_t m_used;
1045  std::size_t m_free;
1046  std::size_t m_off;
1047  std::size_t m_parsed;
1048  msgpack::unique_ptr<msgpack::zone> m_z;
1049  std::size_t m_initial_buffer_size;
1050  detail::context m_ctx;
1051 
1052 #if defined(MSGPACK_USE_CPP03)
1053 private:
1054  unpacker(const unpacker&);
1055  unpacker& operator=(const unpacker&);
1056 #else // defined(MSGPACK_USE_CPP03)
1057  unpacker(const unpacker&) = delete;
1058  unpacker& operator=(const unpacker&) = delete;
1059 #endif // defined(MSGPACK_USE_CPP03)
1060 };
1061 
1063  void* user_data,
1064  std::size_t initial_buffer_size,
1065  unpack_limit const& limit)
1066  :m_z(new msgpack::zone), m_ctx(f, user_data, limit)
1067 {
1068  if(initial_buffer_size < COUNTER_SIZE) {
1069  initial_buffer_size = COUNTER_SIZE;
1070  }
1071 
1072  char* buffer = static_cast<char*>(::malloc(initial_buffer_size));
1073  if(!buffer) {
1074  throw std::bad_alloc();
1075  }
1076 
1077  m_buffer = buffer;
1078  m_used = COUNTER_SIZE;
1079  m_free = initial_buffer_size - m_used;
1080  m_off = COUNTER_SIZE;
1081  m_parsed = 0;
1082  m_initial_buffer_size = initial_buffer_size;
1083 
1084  detail::init_count(m_buffer);
1085 
1086  m_ctx.init();
1087  m_ctx.user().set_zone(*m_z);
1088  m_ctx.user().set_referenced(false);
1089 }
1090 
1091 #if !defined(MSGPACK_USE_CPP03)
1092 // Move constructor and move assignment operator
1093 
1095  :m_buffer(other.m_buffer),
1096  m_used(other.m_used),
1097  m_free(other.m_free),
1098  m_off(other.m_off),
1099  m_parsed(other.m_parsed),
1100  m_z(std::move(other.m_z)),
1101  m_initial_buffer_size(other.m_initial_buffer_size),
1102  m_ctx(other.m_ctx) {
1103  other.m_buffer = MSGPACK_NULLPTR;
1104 }
1105 
1107  this->~unpacker();
1108  new (this) unpacker(std::move(other));
1109  return *this;
1110 }
1111 
1112 #endif // !defined(MSGPACK_USE_CPP03)
1113 
1114 
1116 {
1117  // These checks are required for move operations.
1118  if (m_buffer) detail::decr_count(m_buffer);
1119 }
1120 
1121 
1122 inline void unpacker::reserve_buffer(std::size_t size)
1123 {
1124  if(m_free >= size) return;
1125  expand_buffer(size);
1126 }
1127 
1128 inline void unpacker::expand_buffer(std::size_t size)
1129 {
1130  if(m_used == m_off && detail::get_count(m_buffer) == 1
1131  && !m_ctx.user().referenced()) {
1132  // rewind buffer
1133  m_free += m_used - COUNTER_SIZE;
1134  m_used = COUNTER_SIZE;
1135  m_off = COUNTER_SIZE;
1136 
1137  if(m_free >= size) return;
1138  }
1139 
1140  if(m_off == COUNTER_SIZE) {
1141  std::size_t next_size = (m_used + m_free) * 2; // include COUNTER_SIZE
1142  while(next_size < size + m_used) {
1143  std::size_t tmp_next_size = next_size * 2;
1144  if (tmp_next_size <= next_size) {
1145  next_size = size + m_used;
1146  break;
1147  }
1148  next_size = tmp_next_size;
1149  }
1150 
1151  char* tmp = static_cast<char*>(::realloc(m_buffer, next_size));
1152  if(!tmp) {
1153  throw std::bad_alloc();
1154  }
1155 
1156  m_buffer = tmp;
1157  m_free = next_size - m_used;
1158 
1159  } else {
1160  std::size_t next_size = m_initial_buffer_size; // include COUNTER_SIZE
1161  std::size_t not_parsed = m_used - m_off;
1162  while(next_size < size + not_parsed + COUNTER_SIZE) {
1163  std::size_t tmp_next_size = next_size * 2;
1164  if (tmp_next_size <= next_size) {
1165  next_size = size + not_parsed + COUNTER_SIZE;
1166  break;
1167  }
1168  next_size = tmp_next_size;
1169  }
1170 
1171  char* tmp = static_cast<char*>(::malloc(next_size));
1172  if(!tmp) {
1173  throw std::bad_alloc();
1174  }
1175 
1176  detail::init_count(tmp);
1177 
1178  std::memcpy(tmp+COUNTER_SIZE, m_buffer + m_off, not_parsed);
1179 
1180  if(m_ctx.user().referenced()) {
1181  try {
1182  m_z->push_finalizer(&detail::decr_count, m_buffer);
1183  }
1184  catch (...) {
1185  ::free(tmp);
1186  throw;
1187  }
1188  m_ctx.user().set_referenced(false);
1189  } else {
1190  detail::decr_count(m_buffer);
1191  }
1192 
1193  m_buffer = tmp;
1194  m_used = not_parsed + COUNTER_SIZE;
1195  m_free = next_size - m_used;
1196  m_off = COUNTER_SIZE;
1197  }
1198 }
1199 
1200 inline char* unpacker::buffer()
1201 {
1202  return m_buffer + m_used;
1203 }
1204 
1205 inline std::size_t unpacker::buffer_capacity() const
1206 {
1207  return m_free;
1208 }
1209 
1210 inline void unpacker::buffer_consumed(std::size_t size)
1211 {
1212  m_used += size;
1213  m_free -= size;
1214 }
1215 
1216 inline bool unpacker::next(msgpack::object_handle& result, bool& referenced)
1217 {
1218  referenced = false;
1219  int ret = execute_imp();
1220  if(ret < 0) {
1221  throw msgpack::parse_error("parse error");
1222  }
1223 
1224  if(ret == 0) {
1225  result.zone().reset();
1226  result.set(msgpack::object());
1227  return false;
1228 
1229  } else {
1230  referenced = m_ctx.user().referenced();
1231  result.zone().reset( release_zone() );
1232  result.set(data());
1233  reset();
1234  return true;
1235  }
1236 }
1237 
1239 {
1240  bool referenced;
1241  return next(result, referenced);
1242 }
1243 
1245 {
1246  return next(*result);
1247 }
1248 
1249 
1250 inline bool unpacker::execute()
1251 {
1252  int ret = execute_imp();
1253  if(ret < 0) {
1254  throw msgpack::parse_error("parse error");
1255  } else if(ret == 0) {
1256  return false;
1257  } else {
1258  return true;
1259  }
1260 }
1261 
1262 inline int unpacker::execute_imp()
1263 {
1264  std::size_t off = m_off;
1265  int ret = m_ctx.execute(m_buffer, m_used, m_off);
1266  if(m_off > off) {
1267  m_parsed += m_off - off;
1268  }
1269  return ret;
1270 }
1271 
1273 {
1274  return m_ctx.data();
1275 }
1276 
1278 {
1279  if(!flush_zone()) {
1280  return MSGPACK_NULLPTR;
1281  }
1282 
1283  msgpack::zone* r = new msgpack::zone;
1284  msgpack::zone* old = m_z.release();
1285  m_z.reset(r);
1286  m_ctx.user().set_zone(*m_z);
1287 
1288  return old;
1289 }
1290 
1292 {
1293  m_z->clear();
1294 }
1295 
1296 inline bool unpacker::flush_zone()
1297 {
1298  if(m_ctx.user().referenced()) {
1299  try {
1300  m_z->push_finalizer(&detail::decr_count, m_buffer);
1301  } catch (...) {
1302  return false;
1303  }
1304  m_ctx.user().set_referenced(false);
1305 
1306  detail::incr_count(m_buffer);
1307  }
1308 
1309  return true;
1310 }
1311 
1312 inline void unpacker::reset()
1313 {
1314  m_ctx.init();
1315  // don't reset referenced flag
1316  m_parsed = 0;
1317 }
1318 
1319 inline std::size_t unpacker::message_size() const
1320 {
1321  return m_parsed - m_off + m_used;
1322 }
1323 
1324 inline std::size_t unpacker::parsed_size() const
1325 {
1326  return m_parsed;
1327 }
1328 
1330 {
1331  return m_buffer + m_off;
1332 }
1333 
1334 inline std::size_t unpacker::nonparsed_size() const
1335 {
1336  return m_used - m_off;
1337 }
1338 
1339 inline void unpacker::skip_nonparsed_buffer(std::size_t size)
1340 {
1341  m_off += size;
1342 }
1343 
1345 {
1346  m_used = m_off;
1347 }
1348 
1349 namespace detail {
1350 
1351 inline parse_return
1352 unpack_imp(const char* data, std::size_t len, std::size_t& off,
1353  msgpack::zone& result_zone, msgpack::object& result, bool& referenced,
1354  unpack_reference_func f = MSGPACK_NULLPTR, void* user_data = MSGPACK_NULLPTR,
1355  unpack_limit const& limit = unpack_limit())
1356 {
1357  std::size_t noff = off;
1358 
1359  if(len <= noff) {
1360  // FIXME
1361  return PARSE_CONTINUE;
1362  }
1363 
1364  detail::context ctx(f, user_data, limit);
1365  ctx.init();
1366 
1367  ctx.user().set_zone(result_zone);
1368  ctx.user().set_referenced(false);
1369  referenced = false;
1370 
1371  int e = ctx.execute(data, len, noff);
1372  if(e < 0) {
1373  return PARSE_PARSE_ERROR;
1374  }
1375 
1376  referenced = ctx.user().referenced();
1377  off = noff;
1378 
1379  if(e == 0) {
1380  return PARSE_CONTINUE;
1381  }
1382 
1383  result = ctx.data();
1384 
1385  if(noff < len) {
1386  return PARSE_EXTRA_BYTES;
1387  }
1388 
1389  return PARSE_SUCCESS;
1390 }
1391 
1392 } // detail
1393 
1394 // reference version
1395 
1397  const char* data, std::size_t len, std::size_t& off, bool& referenced,
1398  unpack_reference_func f, void* user_data,
1399  unpack_limit const& limit
1400 )
1401 {
1402  msgpack::object obj;
1403  msgpack::unique_ptr<msgpack::zone> z(new msgpack::zone);
1404  referenced = false;
1405  std::size_t noff = off;
1407  data, len, noff, *z, obj, referenced, f, user_data, limit);
1408 
1409  switch(ret) {
1410  case PARSE_SUCCESS:
1411  off = noff;
1412  return msgpack::object_handle(obj, msgpack::move(z));
1413  case PARSE_EXTRA_BYTES:
1414  off = noff;
1415  return msgpack::object_handle(obj, msgpack::move(z));
1416  case PARSE_CONTINUE:
1417  throw msgpack::insufficient_bytes("insufficient bytes");
1418  case PARSE_PARSE_ERROR:
1419  default:
1420  throw msgpack::parse_error("parse error");
1421  }
1422  return msgpack::object_handle();
1423 }
1424 
1426  const char* data, std::size_t len, std::size_t& off,
1427  unpack_reference_func f, void* user_data,
1428  unpack_limit const& limit)
1429 {
1430  bool referenced;
1431  return unpack(data, len, off, referenced, f, user_data, limit);
1432 }
1433 
1435  const char* data, std::size_t len, bool& referenced,
1436  unpack_reference_func f, void* user_data,
1437  unpack_limit const& limit)
1438 {
1439  std::size_t off = 0;
1440  return unpack(data, len, off, referenced, f, user_data, limit);
1441 }
1442 
1444  const char* data, std::size_t len,
1445  unpack_reference_func f, void* user_data,
1446  unpack_limit const& limit)
1447 {
1448  bool referenced;
1449  std::size_t off = 0;
1450  return unpack(data, len, off, referenced, f, user_data, limit);
1451 }
1452 
1453 inline void unpack(
1454  msgpack::object_handle& result,
1455  const char* data, std::size_t len, std::size_t& off, bool& referenced,
1456  unpack_reference_func f, void* user_data,
1457  unpack_limit const& limit)
1458 {
1459  msgpack::object obj;
1460  msgpack::unique_ptr<msgpack::zone> z(new msgpack::zone);
1461  referenced = false;
1462  std::size_t noff = off;
1464  data, len, noff, *z, obj, referenced, f, user_data, limit);
1465 
1466  switch(ret) {
1467  case PARSE_SUCCESS:
1468  off = noff;
1469  result.set(obj);
1470  result.zone() = msgpack::move(z);
1471  return;
1472  case PARSE_EXTRA_BYTES:
1473  off = noff;
1474  result.set(obj);
1475  result.zone() = msgpack::move(z);
1476  return;
1477  case PARSE_CONTINUE:
1478  throw msgpack::insufficient_bytes("insufficient bytes");
1479  case PARSE_PARSE_ERROR:
1480  default:
1481  throw msgpack::parse_error("parse error");
1482  }
1483 }
1484 
1485 inline void unpack(
1486  msgpack::object_handle& result,
1487  const char* data, std::size_t len, std::size_t& off,
1488  unpack_reference_func f, void* user_data,
1489  unpack_limit const& limit)
1490 {
1491  bool referenced;
1492  unpack(result, data, len, off, referenced, f, user_data, limit);
1493 }
1494 
1495 inline void unpack(
1496  msgpack::object_handle& result,
1497  const char* data, std::size_t len, bool& referenced,
1498  unpack_reference_func f, void* user_data,
1499  unpack_limit const& limit)
1500 {
1501  std::size_t off = 0;
1502  unpack(result, data, len, off, referenced, f, user_data, limit);
1503 }
1504 
1505 inline void unpack(
1506  msgpack::object_handle& result,
1507  const char* data, std::size_t len,
1508  unpack_reference_func f, void* user_data,
1509  unpack_limit const& limit)
1510 {
1511  bool referenced;
1512  std::size_t off = 0;
1513  unpack(result, data, len, off, referenced, f, user_data, limit);
1514 }
1515 
1516 
1518  msgpack::zone& z,
1519  const char* data, std::size_t len, std::size_t& off, bool& referenced,
1520  unpack_reference_func f, void* user_data,
1521  unpack_limit const& limit)
1522 {
1523  msgpack::object obj;
1524  std::size_t noff = off;
1525  referenced = false;
1527  data, len, noff, z, obj, referenced, f, user_data, limit);
1528 
1529  switch(ret) {
1530  case PARSE_SUCCESS:
1531  off = noff;
1532  return obj;
1533  case PARSE_EXTRA_BYTES:
1534  off = noff;
1535  return obj;
1536  case PARSE_CONTINUE:
1537  throw msgpack::insufficient_bytes("insufficient bytes");
1538  case PARSE_PARSE_ERROR:
1539  default:
1540  throw msgpack::parse_error("parse error");
1541  }
1542  return obj;
1543 }
1544 
1546  msgpack::zone& z,
1547  const char* data, std::size_t len, std::size_t& off,
1548  unpack_reference_func f, void* user_data,
1549  unpack_limit const& limit)
1550 {
1551  bool referenced;
1552  return unpack(z, data, len, off, referenced, f, user_data, limit);
1553 }
1554 
1556  msgpack::zone& z,
1557  const char* data, std::size_t len, bool& referenced,
1558  unpack_reference_func f, void* user_data,
1559  unpack_limit const& limit)
1560 {
1561  std::size_t off = 0;
1562  return unpack(z, data, len, off, referenced, f, user_data, limit);
1563 }
1564 
1566  msgpack::zone& z,
1567  const char* data, std::size_t len,
1568  unpack_reference_func f, void* user_data,
1569  unpack_limit const& limit)
1570 {
1571  bool referenced;
1572  std::size_t off = 0;
1573  return unpack(z, data, len, off, referenced, f, user_data, limit);
1574 }
1575 
1576 // obsolete
1577 // pointer version
1578 MSGPACK_DEPRECATED("please use reference version instead")
1579 inline void unpack(
1580  msgpack::object_handle* result,
1581  const char* data, std::size_t len, std::size_t* off, bool* referenced,
1582  unpack_reference_func f, void* user_data,
1583  unpack_limit const& limit)
1584 {
1585  if (off)
1586  if (referenced) unpack(*result, data, len, *off, *referenced, f, user_data, limit);
1587  else unpack(*result, data, len, *off, f, user_data, limit);
1588  else
1589  if (referenced) unpack(*result, data, len, *referenced, f, user_data, limit);
1590  else unpack(*result, data, len, f, user_data, limit);
1591 }
1592 
1593 inline bool unpacker::default_reference_func(msgpack::type::object_type /*type*/, std::size_t /*len*/, void*)
1594 {
1595  return true;
1596 }
1597 
1599 } // MSGPACK_API_VERSION_NAMESPACE(v1)
1601 
1602 } // namespace msgpack
1603 
1604 
1605 #endif // MSGPACK_V1_UNPACK_HPP
#define MSGPACK_ASSERT
Definition: assert.hpp:22
Definition: unpack.hpp:317
int execute(const char *data, std::size_t len, std::size_t &off)
Definition: unpack.hpp:466
msgpack::object const & data() const
Definition: unpack.hpp:334
context(unpack_reference_func f, void *user_data, unpack_limit const &limit)
Definition: unpack.hpp:319
unpack_user & user()
Definition: unpack.hpp:339
unpack_user const & user() const
Definition: unpack.hpp:344
void init()
Definition: unpack.hpp:326
Definition: unpack.hpp:221
std::size_t decr_count()
Definition: unpack.hpp:228
std::size_t count() const
Definition: unpack.hpp:226
void set_map_key(msgpack::object const &map_key)
Definition: unpack.hpp:232
uint32_t container_type() const
Definition: unpack.hpp:229
msgpack::object const & obj() const
Definition: unpack.hpp:223
msgpack::object const & map_key() const
Definition: unpack.hpp:231
void set_obj(msgpack::object const &obj)
Definition: unpack.hpp:225
void set_container_type(uint32_t container_type)
Definition: unpack.hpp:230
void set_count(std::size_t count)
Definition: unpack.hpp:227
msgpack::object & obj()
Definition: unpack.hpp:224
Definition: unpack.hpp:45
unpack_limit const & limit() const
Definition: unpack.hpp:58
unpack_reference_func reference_func() const
Definition: unpack.hpp:56
unpack_limit & limit()
Definition: unpack.hpp:59
msgpack::zone const & zone() const
Definition: unpack.hpp:51
unpack_user(unpack_reference_func f=MSGPACK_NULLPTR, void *user_data=MSGPACK_NULLPTR, unpack_limit const &limit=unpack_limit())
Definition: unpack.hpp:47
void set_zone(msgpack::zone &zone)
Definition: unpack.hpp:53
void * user_data() const
Definition: unpack.hpp:57
bool referenced() const
Definition: unpack.hpp:54
void set_referenced(bool referenced)
Definition: unpack.hpp:55
msgpack::zone & zone()
Definition: unpack.hpp:52
The class holds object and zone.
Definition: object.hpp:44
msgpack::unique_ptr< msgpack::zone > & zone()
Get unique_ptr reference of zone.
Definition: object.hpp:90
void set(msgpack::object const &obj)
Definition: object.hpp:64
Definition: unpack_decl.hpp:87
std::size_t bin() const
Definition: unpack_decl.hpp:105
std::size_t str() const
Definition: unpack_decl.hpp:104
std::size_t map() const
Definition: unpack_decl.hpp:103
std::size_t depth() const
Definition: unpack_decl.hpp:107
std::size_t array() const
Definition: unpack_decl.hpp:102
std::size_t ext() const
Definition: unpack_decl.hpp:106
Unpacking class for a stream deserialization.
Definition: unpack.hpp:861
msgpack::zone * release_zone()
Definition: unpack.hpp:1277
void reserve_buffer(std::size_t size=MSGPACK_UNPACKER_RESERVE_SIZE)
Reserve a buffer memory.
Definition: unpack.hpp:1122
void reset_zone()
Definition: unpack.hpp:1291
void remove_nonparsed_buffer()
Remove nonparsed buffer and reset the current position as a new start point.
Definition: unpack.hpp:1344
~unpacker()
Definition: unpack.hpp:1115
msgpack::object const & data()
Definition: unpack.hpp:1272
std::size_t nonparsed_size() const
Get the size of the buffer that is not parsed.
Definition: unpack.hpp:1334
void buffer_consumed(std::size_t size)
Notify a buffer consumed information to msgpack::unpacker.
Definition: unpack.hpp:1210
unpacker(unpack_reference_func f=&unpacker::default_reference_func, void *user_data=MSGPACK_NULLPTR, std::size_t initial_buffer_size=MSGPACK_UNPACKER_INIT_BUFFER_SIZE, unpack_limit const &limit=unpack_limit())
Constructor.
Definition: unpack.hpp:1062
std::size_t parsed_size() const
Get parsed message size.
Definition: unpack.hpp:1324
std::size_t message_size() const
Get message size.
Definition: unpack.hpp:1319
char * buffer()
Get buffer pointer.
Definition: unpack.hpp:1200
char * nonparsed_buffer()
Get the address that is not parsed in the buffer.
Definition: unpack.hpp:1329
bool execute()
Definition: unpack.hpp:1250
void reset()
Definition: unpack.hpp:1312
std::size_t buffer_capacity() const
Get buffer capacity.
Definition: unpack.hpp:1205
void skip_nonparsed_buffer(std::size_t size)
Skip the specified size of non-parsed buffer.
Definition: unpack.hpp:1339
unpacker & operator=(unpacker &&other)
Definition: unpack.hpp:1106
bool next(msgpack::object_handle *result)
Unpack one msgpack::object. [obsolete].
Definition: unpack.hpp:1244
Definition: cpp03_zone.hpp:30
void * allocate_align(size_t size, size_t align=MSGPACK_ZONE_ALIGN)
Definition: cpp03_zone.hpp:255
void unpack_int32(int32_t d, msgpack::object &o)
Definition: unpack.hpp:89
void unpack_ext(unpack_user &u, const char *p, std::size_t l, msgpack::object &o)
Definition: unpack.hpp:204
void unpack_float(float d, msgpack::object &o)
Definition: unpack.hpp:97
void unpack_false(msgpack::object &o)
Definition: unpack.hpp:109
void unpack_int16(int16_t d, msgpack::object &o)
Definition: unpack.hpp:85
void unpack_str(unpack_user &u, const char *p, uint32_t l, msgpack::object &o)
Definition: unpack.hpp:166
void unpack_nil(msgpack::object &o)
Definition: unpack.hpp:103
void init_count(void *buffer)
Definition: unpack.hpp:240
parse_return unpack_imp(const char *data, std::size_t len, std::size_t &off, msgpack::zone &result_zone, msgpack::object &result, bool &referenced, unpack_reference_func f=MSGPACK_NULLPTR, void *user_data=MSGPACK_NULLPTR, unpack_limit const &limit=unpack_limit())
Definition: unpack.hpp:1352
void unpack_uint64(uint64_t d, msgpack::object &o)
Definition: unpack.hpp:78
std::atomic< unsigned int > const & get_count(void *buffer)
Definition: unpack.hpp:277
void unpack_array_item(msgpack::object &c, msgpack::object const &o)
Definition: unpack.hpp:128
void decr_count(void *buffer)
Definition: unpack.hpp:249
void unpack_int64(int64_t d, msgpack::object &o)
Definition: unpack.hpp:93
void unpack_uint8(uint8_t d, msgpack::object &o)
Definition: unpack.hpp:69
void unpack_bin(unpack_user &u, const char *p, uint32_t l, msgpack::object &o)
Definition: unpack.hpp:185
void unpack_int8(int8_t d, msgpack::object &o)
Definition: unpack.hpp:81
void incr_count(void *buffer)
Definition: unpack.hpp:262
void unpack_true(msgpack::object &o)
Definition: unpack.hpp:106
void unpack_map_item(msgpack::object &c, msgpack::object const &k, msgpack::object const &v)
Definition: unpack.hpp:154
void unpack_uint16(uint16_t d, msgpack::object &o)
Definition: unpack.hpp:72
void unpack_double(double d, msgpack::object &o)
Definition: unpack.hpp:100
void unpack_uint32(uint32_t d, msgpack::object &o)
Definition: unpack.hpp:75
msgpack::enable_if< sizeof(T)==sizeof(fix_tag)>::type load(uint32_t &dst, const char *n)
Definition: unpack.hpp:293
std::size_t size(T const &t)
Definition: size_equal_only.hpp:24
object_type
Definition: object_fwd_decl.hpp:27
@ EXT
Definition: object_fwd_decl.hpp:42
@ FLOAT64
Definition: object_fwd_decl.hpp:33
@ BOOLEAN
Definition: object_fwd_decl.hpp:29
@ MAP
Definition: object_fwd_decl.hpp:41
@ NIL
Definition: object_fwd_decl.hpp:28
@ STR
Definition: object_fwd_decl.hpp:38
@ ARRAY
Definition: object_fwd_decl.hpp:40
@ BIN
Definition: object_fwd_decl.hpp:39
@ POSITIVE_INTEGER
Definition: object_fwd_decl.hpp:30
@ NEGATIVE_INTEGER
Definition: object_fwd_decl.hpp:31
@ FLOAT32
Definition: object_fwd_decl.hpp:32
Definition: adaptor_base.hpp:15
bool(* unpack_reference_func)(msgpack::type::object_type type, std::size_t size, void *user_data)
The type of reference or copy judging function.
Definition: unpack_decl.hpp:74
parse_return
Definition: parse_return.hpp:23
@ PARSE_CONTINUE
Definition: parse_return.hpp:26
@ PARSE_EXTRA_BYTES
Definition: parse_return.hpp:25
@ PARSE_SUCCESS
Definition: parse_return.hpp:24
@ PARSE_PARSE_ERROR
Definition: parse_return.hpp:27
msgpack::object_handle unpack(const char *data, std::size_t len, std::size_t &off, bool &referenced, unpack_reference_func f, void *user_data, unpack_limit const &limit)
Unpack msgpack::object from a buffer.
Definition: unpack.hpp:1396
Definition: unpack_exception.hpp:61
Definition: unpack_exception.hpp:88
Definition: unpack_exception.hpp:106
Definition: unpack_decl.hpp:180
Definition: unpack.hpp:112
void operator()(unpack_user &u, uint32_t n, msgpack::object &o) const
Definition: unpack.hpp:113
Definition: unpack.hpp:138
void operator()(unpack_user &u, uint32_t n, msgpack::object &o) const
Definition: unpack.hpp:139
uint32_t type
Definition: unpack.hpp:289
Definition: unpack.hpp:284
T type
Definition: unpack.hpp:285
Definition: unpack_exception.hpp:97
Definition: unpack_exception.hpp:43
Definition: unpack_exception.hpp:70
uint32_t size
Definition: object_fwd.hpp:23
msgpack::object * ptr
Definition: object_fwd.hpp:24
uint32_t size
Definition: object_fwd.hpp:38
const char * ptr
Definition: object_fwd.hpp:39
const char * ptr
Definition: object_fwd.hpp:46
uint32_t size
Definition: object_fwd.hpp:45
Definition: object.hpp:30
msgpack::object val
Definition: object.hpp:32
msgpack::object key
Definition: object.hpp:31
uint32_t size
Definition: object_fwd.hpp:28
msgpack::object_kv * ptr
Definition: object_fwd.hpp:29
const char * ptr
Definition: object_fwd.hpp:34
uint32_t size
Definition: object_fwd.hpp:33
Object class that corresponding to MessagePack format object.
Definition: object_fwd.hpp:75
union_type via
Definition: object_fwd.hpp:93
msgpack::type::object_type type
Definition: object_fwd.hpp:92
Definition: unpack_exception.hpp:34
Definition: unpack_exception.hpp:79
unsigned int _msgpack_atomic_counter_t
Definition: sysdep.hpp:73
#define _msgpack_load64(cast, from, to)
Definition: sysdep.hpp:180
#define _msgpack_sync_incr_and_fetch(ptr)
Definition: sysdep.hpp:75
#define _msgpack_load16(cast, from, to)
Definition: sysdep.hpp:171
#define _msgpack_sync_decr_and_fetch(ptr)
Definition: sysdep.hpp:74
#define _msgpack_load32(cast, from, to)
Definition: sysdep.hpp:176
bool boolean
Definition: object_fwd.hpp:77
msgpack::object_array array
Definition: object_fwd.hpp:85
msgpack::object_ext ext
Definition: object_fwd.hpp:89
msgpack::object_str str
Definition: object_fwd.hpp:87
uint64_t u64
Definition: object_fwd.hpp:78
int64_t i64
Definition: object_fwd.hpp:79
msgpack::object_bin bin
Definition: object_fwd.hpp:88
double f64
Definition: object_fwd.hpp:84
msgpack::object_map map
Definition: object_fwd.hpp:86
@ MSGPACK_CT_ARRAY_ITEM
Definition: unpack_define.hpp:69
@ MSGPACK_CT_MAP_VALUE
Definition: unpack_define.hpp:71
@ MSGPACK_CT_MAP_KEY
Definition: unpack_define.hpp:70
#define MSGPACK_EMBED_STACK_SIZE
Definition: unpack_define.hpp:16
@ MSGPACK_CS_EXT_32
Definition: unpack_define.hpp:33
@ MSGPACK_CS_EXT_16
Definition: unpack_define.hpp:32
@ MSGPACK_CS_STR_8
Definition: unpack_define.hpp:52
@ MSGPACK_CS_STR_32
Definition: unpack_define.hpp:54
@ MSGPACK_CS_DOUBLE
Definition: unpack_define.hpp:36
@ MSGPACK_CS_FIXEXT_4
Definition: unpack_define.hpp:48
@ MSGPACK_CS_UINT_32
Definition: unpack_define.hpp:39
@ MSGPACK_CS_MAP_16
Definition: unpack_define.hpp:57
@ MSGPACK_CS_BIN_32
Definition: unpack_define.hpp:29
@ MSGPACK_CS_BIN_16
Definition: unpack_define.hpp:28
@ MSGPACK_CS_UINT_64
Definition: unpack_define.hpp:40
@ MSGPACK_CS_FLOAT
Definition: unpack_define.hpp:35
@ MSGPACK_CS_ARRAY_32
Definition: unpack_define.hpp:56
@ MSGPACK_CS_FIXEXT_1
Definition: unpack_define.hpp:46
@ MSGPACK_CS_INT_8
Definition: unpack_define.hpp:41
@ MSGPACK_CS_INT_32
Definition: unpack_define.hpp:43
@ MSGPACK_ACS_BIN_VALUE
Definition: unpack_define.hpp:63
@ MSGPACK_CS_ARRAY_16
Definition: unpack_define.hpp:55
@ MSGPACK_CS_FIXEXT_16
Definition: unpack_define.hpp:50
@ MSGPACK_CS_STR_16
Definition: unpack_define.hpp:53
@ MSGPACK_ACS_STR_VALUE
Definition: unpack_define.hpp:62
@ MSGPACK_CS_BIN_8
Definition: unpack_define.hpp:27
@ MSGPACK_CS_INT_64
Definition: unpack_define.hpp:44
@ MSGPACK_CS_FIXEXT_2
Definition: unpack_define.hpp:47
@ MSGPACK_CS_HEADER
Definition: unpack_define.hpp:21
@ MSGPACK_CS_FIXEXT_8
Definition: unpack_define.hpp:49
@ MSGPACK_CS_MAP_32
Definition: unpack_define.hpp:58
@ MSGPACK_ACS_EXT_VALUE
Definition: unpack_define.hpp:64
@ MSGPACK_CS_EXT_8
Definition: unpack_define.hpp:31
@ MSGPACK_CS_INT_16
Definition: unpack_define.hpp:42
@ MSGPACK_CS_UINT_16
Definition: unpack_define.hpp:38
@ MSGPACK_CS_UINT_8
Definition: unpack_define.hpp:37
#define MSGPACK_DEPRECATED(msg)
Definition: cpp_config.hpp:138
#define MSGPACK_NULLPTR
Definition: cpp_config_decl.hpp:85
#define MSGPACK_ZONE_ALIGNOF(type)
Definition: cpp03_zone_decl.hpp:30
#define MSGPACK_UNPACKER_INIT_BUFFER_SIZE
Definition: unpack_decl.hpp:43
#define MSGPACK_UNPACKER_RESERVE_SIZE
Definition: unpack_decl.hpp:47
const size_t COUNTER_SIZE
Definition: unpack_decl.hpp:40
#define MSGPACK_API_VERSION_NAMESPACE(ns)
Definition: versioning.hpp:66