10 #ifndef MSGPACK_V1_UNPACK_HPP
11 #define MSGPACK_V1_UNPACK_HPP
18 #include "msgpack/unpack_define.h"
20 #include "msgpack/sysdep.h"
24 #if !defined(MSGPACK_USE_CPP03)
34 #endif // defined(_MSC_VER)
126 #if defined(__GNUC__) && !defined(__clang__)
148 #if defined(__GNUC__) && !defined(__clang__)
168 std::memcpy(tmp, p, l);
184 std::memcpy(tmp, p, l);
200 std::memcpy(tmp, p, l);
203 o.
via.
ext.
size =
static_cast<uint32_t
>(l - 1);
212 std::size_t
count()
const {
return m_count; }
222 uint32_t m_container_type;
228 #if defined(MSGPACK_USE_CPP03)
229 *
reinterpret_cast<volatile _msgpack_atomic_counter_t*
>(buffer) = 1;
230 #else // defined(MSGPACK_USE_CPP03)
231 new (buffer) std::atomic<unsigned int>(1);
232 #endif // defined(MSGPACK_USE_CPP03)
237 #if defined(MSGPACK_USE_CPP03)
238 if(_msgpack_sync_decr_and_fetch(
reinterpret_cast<volatile _msgpack_atomic_counter_t*
>(buffer)) == 0) {
241 #else // defined(MSGPACK_USE_CPP03)
242 if (--*
reinterpret_cast<std::atomic<unsigned int>*
>(buffer) == 0) {
245 #endif // defined(MSGPACK_USE_CPP03)
250 #if defined(MSGPACK_USE_CPP03)
251 _msgpack_sync_incr_and_fetch(
reinterpret_cast<volatile _msgpack_atomic_counter_t*
>(buffer));
252 #else // defined(MSGPACK_USE_CPP03)
253 ++*
reinterpret_cast<std::atomic<unsigned int>*
>(buffer);
254 #endif // defined(MSGPACK_USE_CPP03)
257 #if defined(MSGPACK_USE_CPP03)
258 inline _msgpack_atomic_counter_t
get_count(
void* buffer)
260 return *
reinterpret_cast<volatile _msgpack_atomic_counter_t*
>(buffer);
262 #else // defined(MSGPACK_USE_CPP03)
263 inline std::atomic<unsigned int>
const&
get_count(
void* buffer)
265 return *
reinterpret_cast<std::atomic<unsigned int>*
>(buffer);
267 #endif // defined(MSGPACK_USE_CPP03)
269 template <
typename T>
278 template <
typename T>
280 dst =
static_cast<uint32_t
>(*
reinterpret_cast<const uint8_t*
>(n)) & 0x0f;
283 template <
typename T>
285 dst =
static_cast<T
>(*
reinterpret_cast<const uint8_t*
>(n));
288 template <
typename T>
290 _msgpack_load16(T, n, &dst);
293 template <
typename T>
295 _msgpack_load32(T, n, &dst);
298 template <
typename T>
300 _msgpack_load64(T, n, &dst);
306 :m_trail(0), m_user(f, user_data, limit), m_cs(MSGPACK_CS_HEADER)
308 m_stack.reserve(MSGPACK_EMBED_STACK_SIZE);
314 m_cs = MSGPACK_CS_HEADER;
322 return m_stack[0].obj();
335 int execute(
const char*
data, std::size_t len, std::size_t& off);
338 template <
typename T>
339 static uint32_t next_cs(T p)
341 return static_cast<uint32_t
>(*p) & 0x1f;
344 template <
typename T,
typename Func>
347 uint32_t container_type,
349 const char* load_pos,
352 load<T>(tmp, load_pos);
353 f(m_user, tmp, m_stack.back().obj());
355 obj = m_stack.back().obj();
356 int ret = push_proc(obj, off);
357 if (ret != 0)
return ret;
360 m_stack.back().set_container_type(container_type);
361 m_stack.back().set_count(tmp);
362 if (m_stack.size() <= m_user.
limit().
depth()) {
363 m_stack.push_back(unpack_stack());
368 m_cs = MSGPACK_CS_HEADER;
377 if(m_stack.size() == 1) {
380 unpack_stack& sp = *(m_stack.end() - 2);
381 switch(sp.container_type()) {
382 case MSGPACK_CT_ARRAY_ITEM:
384 if(sp.decr_count() == 0) {
392 case MSGPACK_CT_MAP_KEY:
394 sp.set_container_type(MSGPACK_CT_MAP_VALUE);
397 case MSGPACK_CT_MAP_VALUE:
399 if(sp.decr_count() == 0) {
404 sp.set_container_type(MSGPACK_CT_MAP_KEY);
416 int ret = push_item(obj);
418 m_stack[0].set_obj(obj);
421 off = m_current - m_start;
424 off = m_current - m_start;
427 m_cs = MSGPACK_CS_HEADER;
433 template <std::
size_t N>
434 static void check_ext_size(std::size_t ) {
439 char const* m_current;
444 std::vector<unpack_stack> m_stack;
448 inline void context::check_ext_size<4>(std::size_t
size) {
457 m_current =
data + off;
458 const char*
const pe =
data + len;
463 if(m_current == pe) {
464 off = m_current - m_start;
467 bool fixed_trail_again =
false;
469 if (m_cs == MSGPACK_CS_HEADER) {
470 fixed_trail_again =
false;
471 int selector = *
reinterpret_cast<const unsigned char*
>(m_current);
472 if (0x00 <= selector && selector <= 0x7f) {
473 unpack_uint8(*
reinterpret_cast<const uint8_t*
>(m_current), obj);
474 int ret = push_proc(obj, off);
475 if (ret != 0)
return ret;
476 }
else if(0xe0 <= selector && selector <= 0xff) {
477 unpack_int8(*
reinterpret_cast<const int8_t*
>(m_current), obj);
478 int ret = push_proc(obj, off);
479 if (ret != 0)
return ret;
480 }
else if (0xc4 <= selector && selector <= 0xdf) {
481 const uint32_t trail[] = {
511 m_trail = trail[selector - 0xc4];
512 m_cs = next_cs(m_current);
513 fixed_trail_again =
true;
514 }
else if(0xa0 <= selector && selector <= 0xbf) {
515 m_trail =
static_cast<uint32_t
>(*m_current) & 0x1f;
517 unpack_str(m_user, n,
static_cast<uint32_t
>(m_trail), obj);
518 int ret = push_proc(obj, off);
519 if (ret != 0)
return ret;
522 m_cs = MSGPACK_ACS_STR_VALUE;
523 fixed_trail_again =
true;
526 }
else if(0x90 <= selector && selector <= 0x9f) {
527 int ret = push_aggregate<fix_tag>(
528 unpack_array(), MSGPACK_CT_ARRAY_ITEM, obj, m_current, off);
529 if (ret != 0)
return ret;
530 }
else if(0x80 <= selector && selector <= 0x8f) {
531 int ret = push_aggregate<fix_tag>(
532 unpack_map(), MSGPACK_CT_MAP_KEY, obj, m_current, off);
533 if (ret != 0)
return ret;
534 }
else if(selector == 0xc2) {
536 int ret = push_proc(obj, off);
537 if (ret != 0)
return ret;
538 }
else if(selector == 0xc3) {
540 int ret = push_proc(obj, off);
541 if (ret != 0)
return ret;
542 }
else if(selector == 0xc0) {
544 int ret = push_proc(obj, off);
545 if (ret != 0)
return ret;
547 off = m_current - m_start;
552 if (m_cs != MSGPACK_CS_HEADER || fixed_trail_again) {
553 if (fixed_trail_again) {
555 fixed_trail_again =
false;
557 if(
static_cast<std::size_t
>(pe - m_current) < m_trail) {
558 off = m_current - m_start;
562 m_current += m_trail - 1;
566 case MSGPACK_CS_FLOAT: {
567 union { uint32_t i;
float f; } mem;
568 load<uint32_t>(mem.i, n);
570 int ret = push_proc(obj, off);
571 if (ret != 0)
return ret;
573 case MSGPACK_CS_DOUBLE: {
574 union { uint64_t i;
double f; } mem;
575 load<uint64_t>(mem.i, n);
576 #if defined(TARGET_OS_IPHONE)
578 #elif defined(__arm__) && !(__ARM_EABI__) // arm-oabi
580 mem.i = (mem.i & 0xFFFFFFFFUL) << 32UL | (mem.i >> 32UL);
583 int ret = push_proc(obj, off);
584 if (ret != 0)
return ret;
586 case MSGPACK_CS_UINT_8: {
588 load<uint8_t>(tmp, n);
590 int ret = push_proc(obj, off);
591 if (ret != 0)
return ret;
593 case MSGPACK_CS_UINT_16: {
595 load<uint16_t>(tmp, n);
597 int ret = push_proc(obj, off);
598 if (ret != 0)
return ret;
600 case MSGPACK_CS_UINT_32: {
602 load<uint32_t>(tmp, n);
604 int ret = push_proc(obj, off);
605 if (ret != 0)
return ret;
607 case MSGPACK_CS_UINT_64: {
609 load<uint64_t>(tmp, n);
611 int ret = push_proc(obj, off);
612 if (ret != 0)
return ret;
614 case MSGPACK_CS_INT_8: {
616 load<int8_t>(tmp, n);
618 int ret = push_proc(obj, off);
619 if (ret != 0)
return ret;
621 case MSGPACK_CS_INT_16: {
623 load<int16_t>(tmp, n);
625 int ret = push_proc(obj, off);
626 if (ret != 0)
return ret;
628 case MSGPACK_CS_INT_32: {
630 load<int32_t>(tmp, n);
632 int ret = push_proc(obj, off);
633 if (ret != 0)
return ret;
635 case MSGPACK_CS_INT_64: {
637 load<int64_t>(tmp, n);
639 int ret = push_proc(obj, off);
640 if (ret != 0)
return ret;
642 case MSGPACK_CS_FIXEXT_1: {
644 int ret = push_proc(obj, off);
645 if (ret != 0)
return ret;
647 case MSGPACK_CS_FIXEXT_2: {
649 int ret = push_proc(obj, off);
650 if (ret != 0)
return ret;
652 case MSGPACK_CS_FIXEXT_4: {
654 int ret = push_proc(obj, off);
655 if (ret != 0)
return ret;
657 case MSGPACK_CS_FIXEXT_8: {
659 int ret = push_proc(obj, off);
660 if (ret != 0)
return ret;
662 case MSGPACK_CS_FIXEXT_16: {
664 int ret = push_proc(obj, off);
665 if (ret != 0)
return ret;
667 case MSGPACK_CS_STR_8: {
669 load<uint8_t>(tmp, n);
672 unpack_str(m_user, n,
static_cast<uint32_t
>(m_trail), obj);
673 int ret = push_proc(obj, off);
674 if (ret != 0)
return ret;
677 m_cs = MSGPACK_ACS_STR_VALUE;
678 fixed_trail_again =
true;
681 case MSGPACK_CS_BIN_8: {
683 load<uint8_t>(tmp, n);
686 unpack_bin(m_user, n,
static_cast<uint32_t
>(m_trail), obj);
687 int ret = push_proc(obj, off);
688 if (ret != 0)
return ret;
691 m_cs = MSGPACK_ACS_BIN_VALUE;
692 fixed_trail_again =
true;
695 case MSGPACK_CS_EXT_8: {
697 load<uint8_t>(tmp, n);
701 int ret = push_proc(obj, off);
702 if (ret != 0)
return ret;
705 m_cs = MSGPACK_ACS_EXT_VALUE;
706 fixed_trail_again =
true;
709 case MSGPACK_CS_STR_16: {
711 load<uint16_t>(tmp, n);
714 unpack_str(m_user, n,
static_cast<uint32_t
>(m_trail), obj);
715 int ret = push_proc(obj, off);
716 if (ret != 0)
return ret;
719 m_cs = MSGPACK_ACS_STR_VALUE;
720 fixed_trail_again =
true;
723 case MSGPACK_CS_BIN_16: {
725 load<uint16_t>(tmp, n);
728 unpack_bin(m_user, n,
static_cast<uint32_t
>(m_trail), obj);
729 int ret = push_proc(obj, off);
730 if (ret != 0)
return ret;
733 m_cs = MSGPACK_ACS_BIN_VALUE;
734 fixed_trail_again =
true;
737 case MSGPACK_CS_EXT_16: {
739 load<uint16_t>(tmp, n);
743 int ret = push_proc(obj, off);
744 if (ret != 0)
return ret;
747 m_cs = MSGPACK_ACS_EXT_VALUE;
748 fixed_trail_again =
true;
751 case MSGPACK_CS_STR_32: {
753 load<uint32_t>(tmp, n);
756 unpack_str(m_user, n,
static_cast<uint32_t
>(m_trail), obj);
757 int ret = push_proc(obj, off);
758 if (ret != 0)
return ret;
761 m_cs = MSGPACK_ACS_STR_VALUE;
762 fixed_trail_again =
true;
765 case MSGPACK_CS_BIN_32: {
767 load<uint32_t>(tmp, n);
770 unpack_bin(m_user, n,
static_cast<uint32_t
>(m_trail), obj);
771 int ret = push_proc(obj, off);
772 if (ret != 0)
return ret;
775 m_cs = MSGPACK_ACS_BIN_VALUE;
776 fixed_trail_again =
true;
779 case MSGPACK_CS_EXT_32: {
781 load<uint32_t>(tmp, n);
782 check_ext_size<sizeof(std::size_t)>(tmp);
787 int ret = push_proc(obj, off);
788 if (ret != 0)
return ret;
791 m_cs = MSGPACK_ACS_EXT_VALUE;
792 fixed_trail_again =
true;
795 case MSGPACK_ACS_STR_VALUE: {
796 unpack_str(m_user, n,
static_cast<uint32_t
>(m_trail), obj);
797 int ret = push_proc(obj, off);
798 if (ret != 0)
return ret;
800 case MSGPACK_ACS_BIN_VALUE: {
801 unpack_bin(m_user, n,
static_cast<uint32_t
>(m_trail), obj);
802 int ret = push_proc(obj, off);
803 if (ret != 0)
return ret;
805 case MSGPACK_ACS_EXT_VALUE: {
807 int ret = push_proc(obj, off);
808 if (ret != 0)
return ret;
810 case MSGPACK_CS_ARRAY_16: {
811 int ret = push_aggregate<uint16_t>(
813 if (ret != 0)
return ret;
815 case MSGPACK_CS_ARRAY_32: {
817 int ret = push_aggregate<uint32_t>(
819 if (ret != 0)
return ret;
821 case MSGPACK_CS_MAP_16: {
822 int ret = push_aggregate<uint16_t>(
823 unpack_map(), MSGPACK_CT_MAP_KEY, obj, n, off);
824 if (ret != 0)
return ret;
826 case MSGPACK_CS_MAP_32: {
828 int ret = push_aggregate<uint32_t>(
829 unpack_map(), MSGPACK_CT_MAP_KEY, obj, n, off);
830 if (ret != 0)
return ret;
833 off = m_current - m_start;
837 }
while(m_current != pe);
839 off = m_current - m_start;
862 #if !defined(MSGPACK_USE_CPP03)
865 #endif // !defined(MSGPACK_USE_CPP03)
1023 void expand_buffer(std::size_t
size);
1033 std::size_t m_parsed;
1035 std::size_t m_initial_buffer_size;
1038 #if defined(MSGPACK_USE_CPP03)
1042 #else // defined(MSGPACK_USE_CPP03)
1045 #endif // defined(MSGPACK_USE_CPP03)
1050 std::size_t initial_buffer_size,
1052 :m_z(new
msgpack::
zone), m_ctx(f, user_data, limit)
1058 char*
buffer =
static_cast<char*
>(::malloc(initial_buffer_size));
1060 throw std::bad_alloc();
1065 m_free = initial_buffer_size - m_used;
1068 m_initial_buffer_size = initial_buffer_size;
1077 #if !defined(MSGPACK_USE_CPP03)
1081 :m_buffer(other.m_buffer),
1082 m_used(other.m_used),
1083 m_free(other.m_free),
1085 m_parsed(other.m_parsed),
1086 m_z(std::
move(other.m_z)),
1087 m_initial_buffer_size(other.m_initial_buffer_size),
1088 m_ctx(other.m_ctx) {
1098 #endif // !defined(MSGPACK_USE_CPP03)
1110 if(m_free >=
size)
return;
1111 expand_buffer(
size);
1114 inline void unpacker::expand_buffer(std::size_t
size)
1123 if(m_free >=
size)
return;
1127 std::size_t next_size = (m_used + m_free) * 2;
1128 while(next_size <
size + m_used) {
1129 std::size_t tmp_next_size = next_size * 2;
1130 if (tmp_next_size <= next_size) {
1131 next_size =
size + m_used;
1134 next_size = tmp_next_size;
1137 char* tmp =
static_cast<char*
>(::realloc(m_buffer, next_size));
1139 throw std::bad_alloc();
1143 m_free = next_size - m_used;
1146 std::size_t next_size = m_initial_buffer_size;
1147 std::size_t not_parsed = m_used - m_off;
1149 std::size_t tmp_next_size = next_size * 2;
1150 if (tmp_next_size <= next_size) {
1154 next_size = tmp_next_size;
1157 char* tmp =
static_cast<char*
>(::malloc(next_size));
1159 throw std::bad_alloc();
1164 std::memcpy(tmp+
COUNTER_SIZE, m_buffer + m_off, not_parsed);
1181 m_free = next_size - m_used;
1188 return m_buffer + m_used;
1205 int ret = execute_imp();
1211 result.
zone().reset();
1227 return next(result, referenced);
1232 return next(*result);
1238 int ret = execute_imp();
1241 }
else if(ret == 0) {
1248 inline int unpacker::execute_imp()
1250 std::size_t off = m_off;
1251 int ret = m_ctx.
execute(m_buffer, m_used, m_off);
1253 m_parsed += m_off - off;
1260 return m_ctx.
data();
1282 inline bool unpacker::flush_zone()
1307 return m_parsed - m_off + m_used;
1317 return m_buffer + m_off;
1322 return m_used - m_off;
1343 std::size_t noff = off;
1357 int e = ctx.
execute(data, len, noff);
1369 result = ctx.
data();
1383 const char* data, std::size_t len, std::size_t& off,
bool& referenced,
1391 std::size_t noff = off;
1393 data, len, noff, *z, obj, referenced, f, user_data, limit);
1412 const char* data, std::size_t len, std::size_t& off,
1417 return unpack(data, len, off, referenced, f, user_data, limit);
1421 const char* data, std::size_t len,
bool& referenced,
1425 std::size_t off = 0;
1426 return unpack(data, len, off, referenced, f, user_data, limit);
1430 const char* data, std::size_t len,
1435 std::size_t off = 0;
1436 return unpack(data, len, off, referenced, f, user_data, limit);
1441 const char* data, std::size_t len, std::size_t& off,
bool& referenced,
1448 std::size_t noff = off;
1450 data, len, noff, *z, obj, referenced, f, user_data, limit);
1473 const char* data, std::size_t len, std::size_t& off,
1478 unpack(result, data, len, off, referenced, f, user_data, limit);
1483 const char* data, std::size_t len,
bool& referenced,
1487 std::size_t off = 0;
1488 unpack(result, data, len, off, referenced, f, user_data, limit);
1493 const char* data, std::size_t len,
1498 std::size_t off = 0;
1499 unpack(result, data, len, off, referenced, f, user_data, limit);
1505 const char* data, std::size_t len, std::size_t& off,
bool& referenced,
1510 std::size_t noff = off;
1513 data, len, noff, z, obj, referenced, f, user_data, limit);
1533 const char* data, std::size_t len, std::size_t& off,
1538 return unpack(z, data, len, off, referenced, f, user_data, limit);
1543 const char* data, std::size_t len,
bool& referenced,
1547 std::size_t off = 0;
1548 return unpack(z, data, len, off, referenced, f, user_data, limit);
1553 const char* data, std::size_t len,
1558 std::size_t off = 0;
1559 return unpack(z, data, len, off, referenced, f, user_data, limit);
1567 const
char* data, std::
size_t len, std::
size_t* off,
bool* referenced,
1572 if (referenced)
unpack(*result, data, len, *off, *referenced, f, user_data, limit);
1573 else unpack(*result, data, len, *off, f, user_data, limit);
1575 if (referenced)
unpack(*result, data, len, *referenced, f, user_data, limit);
1576 else unpack(*result, data, len, f, user_data, limit);
1591 #endif // MSGPACK_V1_UNPACK_HPP