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