MessagePack for C++
Loading...
Searching...
No Matches
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
15#include "msgpack/object.hpp"
16#include "msgpack/zone.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
37namespace msgpack {
38
42
43namespace detail {
44
46public:
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
61private:
62 msgpack::zone* m_zone;
63 bool m_referenced;
65 void* m_user_data;
66 unpack_limit m_limit;
67};
68
69inline void unpack_uint8(uint8_t d, msgpack::object& o)
70{ o.type = msgpack::type::POSITIVE_INTEGER; o.via.u64 = d; }
71
72inline void unpack_uint16(uint16_t d, msgpack::object& o)
73{ o.type = msgpack::type::POSITIVE_INTEGER; o.via.u64 = d; }
74
75inline void unpack_uint32(uint32_t d, msgpack::object& o)
76{ o.type = msgpack::type::POSITIVE_INTEGER; o.via.u64 = d; }
77
78inline void unpack_uint64(uint64_t d, msgpack::object& o)
79{ o.type = msgpack::type::POSITIVE_INTEGER; o.via.u64 = d; }
80
81inline 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
85inline 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
89inline 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
93inline 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
97inline void unpack_float(float d, msgpack::object& o)
98{ o.type = msgpack::type::FLOAT32; o.via.f64 = d; }
99
100inline 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
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");
115 o.type = msgpack::type::ARRAY;
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
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");
141 o.type = msgpack::type::MAP;
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
166inline void unpack_str(unpack_user& u, const char* p, uint32_t l, msgpack::object& o)
167{
168 o.type = msgpack::type::STR;
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
185inline void unpack_bin(unpack_user& u, const char* p, uint32_t l, msgpack::object& o)
186{
187 o.type = msgpack::type::BIN;
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
204inline void unpack_ext(unpack_user& u, const char* p, std::size_t l, msgpack::object& o)
205{
206 o.type = msgpack::type::EXT;
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
222public:
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; }
233private:
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
240inline 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
249inline 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
262inline 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)
272inline _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)
277inline 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
283template <typename T>
284struct value {
285 typedef T type;
286};
287template <>
288struct value<fix_tag> {
289 typedef uint32_t type;
290};
291
292template <typename T>
293inline 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
297template <typename T>
298inline 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
302template <typename T>
303inline typename msgpack::enable_if<sizeof(T) == 2>::type load(T& dst, const char* n) {
304 _msgpack_load16(T, n, &dst);
305}
306
307template <typename T>
308inline typename msgpack::enable_if<sizeof(T) == 4>::type load(T& dst, const char* n) {
309 _msgpack_load32(T, n, &dst);
310}
311
312template <typename T>
313inline typename msgpack::enable_if<sizeof(T) == 8>::type load(T& dst, const char* n) {
314 _msgpack_load64(T, n, &dst);
315}
316
317class context {
318public:
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
351private:
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;
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
451private:
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
461template <>
462inline void context::check_ext_size<4>(std::size_t size) {
463 if (size == 0xffffffff) throw msgpack::ext_size_overflow("ext size overflow");
464}
465
466inline 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 {
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;
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 {
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 {
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 {
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 {
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 {
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 {
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 {
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 {
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 {
806 fixed_trail_again = true;
807 }
808 } break;
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;
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;
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
861class unpacker {
862public:
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
883public:
885
892 void reserve_buffer(std::size_t size = MSGPACK_UNPACKER_RESERVE_SIZE);
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
991public:
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
1035
1036private:
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
1042private:
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)
1053private:
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
1122inline void unpacker::reserve_buffer(std::size_t size)
1123{
1124 if(m_free >= size) return;
1125 expand_buffer(size);
1126}
1127
1128inline 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
1200inline char* unpacker::buffer()
1201{
1202 return m_buffer + m_used;
1203}
1204
1205inline std::size_t unpacker::buffer_capacity() const
1206{
1207 return m_free;
1208}
1209
1210inline void unpacker::buffer_consumed(std::size_t size)
1211{
1212 m_used += size;
1213 m_free -= size;
1214}
1215
1216inline 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
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
1262inline 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
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
1296inline 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
1312inline void unpacker::reset()
1313{
1314 m_ctx.init();
1315 // don't reset referenced flag
1316 m_parsed = 0;
1317}
1318
1319inline std::size_t unpacker::message_size() const
1320{
1321 return m_parsed - m_off + m_used;
1322}
1323
1324inline std::size_t unpacker::parsed_size() const
1325{
1326 return m_parsed;
1327}
1328
1330{
1331 return m_buffer + m_off;
1332}
1333
1334inline std::size_t unpacker::nonparsed_size() const
1335{
1336 return m_used - m_off;
1337}
1338
1339inline void unpacker::skip_nonparsed_buffer(std::size_t size)
1340{
1341 m_off += size;
1342}
1343
1345{
1346 m_used = m_off;
1347}
1348
1349namespace detail {
1350
1351inline parse_return
1352unpack_imp(const char* data, std::size_t len, std::size_t& off,
1353 msgpack::zone& result_zone, msgpack::object& result, bool& referenced,
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;
1406 parse_return ret = detail::unpack_imp(
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
1453inline 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;
1463 parse_return ret = detail::unpack_imp(
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
1485inline 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
1495inline 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
1505inline 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;
1526 parse_return ret = detail::unpack_imp(
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
1578MSGPACK_DEPRECATED("please use reference version instead")
1579inline 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
1593inline 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
unpack_user & user()
Definition unpack.hpp:339
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 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
msgpack::object const & obj() const
Definition unpack.hpp:223
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
void set_obj(msgpack::object const &obj)
Definition unpack.hpp:225
void set_container_type(uint32_t container_type)
Definition unpack.hpp:230
msgpack::object & obj()
Definition unpack.hpp:224
void set_count(std::size_t count)
Definition unpack.hpp:227
msgpack::object const & map_key() const
Definition unpack.hpp:231
Definition unpack.hpp:45
msgpack::zone const & zone() const
Definition unpack.hpp:51
unpack_reference_func reference_func() const
Definition unpack.hpp:56
unpack_limit & limit()
Definition unpack.hpp:59
msgpack::zone & zone()
Definition unpack.hpp:52
void * user_data() const
Definition unpack.hpp:57
unpack_user(unpack_reference_func f=MSGPACK_NULLPTR, void *user_data=MSGPACK_NULLPTR, unpack_limit const &limit=unpack_limit())
Definition unpack.hpp:47
unpack_limit const & limit() const
Definition unpack.hpp:58
void set_zone(msgpack::zone &zone)
Definition unpack.hpp:53
bool referenced() const
Definition unpack.hpp:54
void set_referenced(bool referenced)
Definition unpack.hpp:55
The class holds object and zone.
Definition object.hpp:44
void set(msgpack::object const &obj)
Definition object.hpp:64
msgpack::unique_ptr< msgpack::zone > & zone()
Get unique_ptr reference of zone.
Definition object.hpp:90
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
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
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.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