10 #ifndef MSGPACK_V2_PARSE_HPP 11 #define MSGPACK_V2_PARSE_HPP 13 #if MSGPACK_DEFAULT_API_VERSION >= 2 17 #include "msgpack/unpack_define.h" 30 using v1::detail::fix_tag;
31 using v1::detail::value;
34 template <
typename VisitorHolder>
38 :m_trail(0), m_cs(MSGPACK_CS_HEADER)
44 m_cs = MSGPACK_CS_HEADER;
47 holder().visitor().init();
54 static uint32_t next_cs(T p)
56 return static_cast<uint32_t
>(*p) & 0x1f;
59 VisitorHolder& holder() {
60 return static_cast<VisitorHolder&
>(*this);
63 template <
typename T,
typename StartVisitor,
typename EndVisitor>
65 StartVisitor
const& sv,
70 load<T>(
size, load_pos);
74 off = m_current - m_start;
78 off = m_current - m_start;
83 off = m_current - m_start;
89 off = m_current - m_start;
92 parse_return ret = m_stack.push(holder(), sv.type(),
static_cast<uint32_t
>(
size));
94 off = m_current - m_start;
98 m_cs = MSGPACK_CS_HEADER;
102 parse_return after_visit_proc(
bool visit_result, std::size_t& off) {
105 off = m_current - m_start;
110 off = m_current - m_start;
112 m_cs = MSGPACK_CS_HEADER;
117 array_sv(VisitorHolder& visitor_holder):m_visitor_holder(visitor_holder) {}
118 bool operator()(uint32_t size)
const {
119 return m_visitor_holder.visitor().start_array(size);
121 msgpack_container_type type()
const {
return MSGPACK_CT_ARRAY_ITEM; }
123 VisitorHolder& m_visitor_holder;
126 array_ev(VisitorHolder& visitor_holder):m_visitor_holder(visitor_holder) {}
127 bool operator()()
const {
128 return m_visitor_holder.visitor().end_array();
131 VisitorHolder& m_visitor_holder;
134 map_sv(VisitorHolder& visitor_holder):m_visitor_holder(visitor_holder) {}
135 bool operator()(uint32_t size)
const {
136 return m_visitor_holder.visitor().start_map(size);
138 msgpack_container_type type()
const {
return MSGPACK_CT_MAP_KEY; }
140 VisitorHolder& m_visitor_holder;
143 map_ev(VisitorHolder& visitor_holder):m_visitor_holder(visitor_holder) {}
144 bool operator()()
const {
145 return m_visitor_holder.visitor().end_map();
148 VisitorHolder& m_visitor_holder;
151 struct unpack_stack {
153 stack_elem(msgpack_container_type type, uint32_t rest):m_type(type), m_rest(rest) {}
154 msgpack_container_type m_type;
158 m_stack.reserve(MSGPACK_EMBED_STACK_SIZE);
160 parse_return push(VisitorHolder& visitor_holder, msgpack_container_type type, uint32_t rest) {
161 m_stack.push_back(stack_elem(type, rest));
163 case MSGPACK_CT_ARRAY_ITEM:
165 case MSGPACK_CT_MAP_KEY:
167 case MSGPACK_CT_MAP_VALUE:
175 while (!m_stack.empty()) {
176 stack_elem& e = m_stack.back();
178 case MSGPACK_CT_ARRAY_ITEM:
180 if (--e.m_rest == 0) {
189 case MSGPACK_CT_MAP_KEY:
192 e.m_type = MSGPACK_CT_MAP_VALUE;
194 case MSGPACK_CT_MAP_VALUE:
196 if (--e.m_rest == 0) {
201 e.m_type = MSGPACK_CT_MAP_KEY;
210 bool empty()
const {
return m_stack.empty(); }
211 void clear() { m_stack.clear(); }
213 std::vector<stack_elem> m_stack;
217 char const* m_current;
221 uint32_t m_num_elements;
222 unpack_stack m_stack;
225 template <std::
size_t N>
226 inline void check_ext_size(std::size_t ) {
230 inline void check_ext_size<4>(std::size_t
size) {
234 template <
typename VisitorHolder>
240 m_current = data + off;
241 const char*
const pe = data + len;
246 if(m_current == pe) {
247 off = m_current - m_start;
250 bool fixed_trail_again =
false;
252 if (m_cs == MSGPACK_CS_HEADER) {
253 fixed_trail_again =
false;
254 int selector = *
reinterpret_cast<const unsigned char*
>(m_current);
255 if (0x00 <= selector && selector <= 0x7f) {
256 uint8_t tmp = *
reinterpret_cast<const uint8_t*
>(m_current);
257 bool visret = holder().visitor().visit_positive_integer(tmp);
260 }
else if(0xe0 <= selector && selector <= 0xff) {
261 int8_t tmp = *
reinterpret_cast<const int8_t*
>(m_current);
262 bool visret = holder().visitor().visit_negative_integer(tmp);
265 }
else if (0xc4 <= selector && selector <= 0xdf) {
266 const uint32_t trail[] = {
296 m_trail = trail[selector - 0xc4];
297 m_cs = next_cs(m_current);
298 fixed_trail_again =
true;
299 }
else if(0xa0 <= selector && selector <= 0xbf) {
300 m_trail =
static_cast<uint32_t
>(*m_current) & 0x1f;
302 bool visret = holder().visitor().visit_str(n, static_cast<uint32_t>(m_trail));
307 m_cs = MSGPACK_ACS_STR_VALUE;
308 fixed_trail_again =
true;
310 }
else if(0x90 <= selector && selector <= 0x9f) {
311 parse_return ret = start_aggregate<fix_tag>(array_sv(holder()), array_ev(holder()), m_current, off);
313 }
else if(0x80 <= selector && selector <= 0x8f) {
314 parse_return ret = start_aggregate<fix_tag>(map_sv(holder()), map_ev(holder()), m_current, off);
316 }
else if(selector == 0xc2) {
317 bool visret = holder().visitor().visit_boolean(
false);
320 }
else if(selector == 0xc3) {
321 bool visret = holder().visitor().visit_boolean(
true);
324 }
else if(selector == 0xc0) {
325 bool visret = holder().visitor().visit_nil();
329 off = m_current - m_start;
330 holder().visitor().parse_error(off - 1, off);
335 if (m_cs != MSGPACK_CS_HEADER || fixed_trail_again) {
336 if (fixed_trail_again) {
338 fixed_trail_again =
false;
340 if(static_cast<std::size_t>(pe - m_current) < m_trail) {
341 off = m_current - m_start;
345 m_current += m_trail - 1;
349 case MSGPACK_CS_FLOAT: {
350 union { uint32_t i;
float f; } mem;
351 load<uint32_t>(mem.i, n);
352 bool visret = holder().visitor().visit_float32(mem.f);
356 case MSGPACK_CS_DOUBLE: {
357 union { uint64_t i;
double f; } mem;
358 load<uint64_t>(mem.i, n);
359 #if defined(TARGET_OS_IPHONE) 361 #elif defined(__arm__) && !(__ARM_EABI__) // arm-oabi 363 mem.i = (mem.i & 0xFFFFFFFFUL) << 32UL | (mem.i >> 32UL);
365 bool visret = holder().visitor().visit_float64(mem.f);
369 case MSGPACK_CS_UINT_8: {
371 load<uint8_t>(tmp, n);
372 bool visret = holder().visitor().visit_positive_integer(tmp);
376 case MSGPACK_CS_UINT_16: {
378 load<uint16_t>(tmp, n);
379 bool visret = holder().visitor().visit_positive_integer(tmp);
383 case MSGPACK_CS_UINT_32: {
385 load<uint32_t>(tmp, n);
386 bool visret = holder().visitor().visit_positive_integer(tmp);
390 case MSGPACK_CS_UINT_64: {
392 load<uint64_t>(tmp, n);
393 bool visret = holder().visitor().visit_positive_integer(tmp);
397 case MSGPACK_CS_INT_8: {
399 load<int8_t>(tmp, n);
400 bool visret = holder().visitor().visit_negative_integer(tmp);
404 case MSGPACK_CS_INT_16: {
406 load<int16_t>(tmp, n);
407 bool visret = holder().visitor().visit_negative_integer(tmp);
411 case MSGPACK_CS_INT_32: {
413 load<int32_t>(tmp, n);
414 bool visret = holder().visitor().visit_negative_integer(tmp);
418 case MSGPACK_CS_INT_64: {
420 load<int64_t>(tmp, n);
421 bool visret = holder().visitor().visit_negative_integer(tmp);
425 case MSGPACK_CS_FIXEXT_1: {
426 bool visret = holder().visitor().visit_ext(n, 1+1);
430 case MSGPACK_CS_FIXEXT_2: {
431 bool visret = holder().visitor().visit_ext(n, 2+1);
435 case MSGPACK_CS_FIXEXT_4: {
436 bool visret = holder().visitor().visit_ext(n, 4+1);
440 case MSGPACK_CS_FIXEXT_8: {
441 bool visret = holder().visitor().visit_ext(n, 8+1);
445 case MSGPACK_CS_FIXEXT_16: {
446 bool visret = holder().visitor().visit_ext(n, 16+1);
450 case MSGPACK_CS_STR_8: {
452 load<uint8_t>(tmp, n);
455 bool visret = holder().visitor().visit_str(n, static_cast<uint32_t>(m_trail));
460 m_cs = MSGPACK_ACS_STR_VALUE;
461 fixed_trail_again =
true;
464 case MSGPACK_CS_BIN_8: {
466 load<uint8_t>(tmp, n);
469 bool visret = holder().visitor().visit_bin(n, static_cast<uint32_t>(m_trail));
474 m_cs = MSGPACK_ACS_BIN_VALUE;
475 fixed_trail_again =
true;
478 case MSGPACK_CS_EXT_8: {
480 load<uint8_t>(tmp, n);
483 bool visret = holder().visitor().visit_ext(n, static_cast<uint32_t>(m_trail));
488 m_cs = MSGPACK_ACS_EXT_VALUE;
489 fixed_trail_again =
true;
492 case MSGPACK_CS_STR_16: {
494 load<uint16_t>(tmp, n);
497 bool visret = holder().visitor().visit_str(n, static_cast<uint32_t>(m_trail));
502 m_cs = MSGPACK_ACS_STR_VALUE;
503 fixed_trail_again =
true;
506 case MSGPACK_CS_BIN_16: {
508 load<uint16_t>(tmp, n);
511 bool visret = holder().visitor().visit_bin(n, static_cast<uint32_t>(m_trail));
516 m_cs = MSGPACK_ACS_BIN_VALUE;
517 fixed_trail_again =
true;
520 case MSGPACK_CS_EXT_16: {
522 load<uint16_t>(tmp, n);
525 bool visret = holder().visitor().visit_ext(n, static_cast<uint32_t>(m_trail));
530 m_cs = MSGPACK_ACS_EXT_VALUE;
531 fixed_trail_again =
true;
534 case MSGPACK_CS_STR_32: {
536 load<uint32_t>(tmp, n);
539 bool visret = holder().visitor().visit_str(n, static_cast<uint32_t>(m_trail));
544 m_cs = MSGPACK_ACS_STR_VALUE;
545 fixed_trail_again =
true;
548 case MSGPACK_CS_BIN_32: {
550 load<uint32_t>(tmp, n);
553 bool visret = holder().visitor().visit_bin(n, static_cast<uint32_t>(m_trail));
558 m_cs = MSGPACK_ACS_BIN_VALUE;
559 fixed_trail_again =
true;
562 case MSGPACK_CS_EXT_32: {
564 load<uint32_t>(tmp, n);
565 check_ext_size<sizeof(std::size_t)>(tmp);
569 bool visret = holder().visitor().visit_ext(n, static_cast<uint32_t>(m_trail));
574 m_cs = MSGPACK_ACS_EXT_VALUE;
575 fixed_trail_again =
true;
578 case MSGPACK_ACS_STR_VALUE: {
579 bool visret = holder().visitor().visit_str(n, static_cast<uint32_t>(m_trail));
583 case MSGPACK_ACS_BIN_VALUE: {
584 bool visret = holder().visitor().visit_bin(n, static_cast<uint32_t>(m_trail));
588 case MSGPACK_ACS_EXT_VALUE: {
589 bool visret = holder().visitor().visit_ext(n, static_cast<uint32_t>(m_trail));
593 case MSGPACK_CS_ARRAY_16: {
594 parse_return ret = start_aggregate<uint16_t>(array_sv(holder()), array_ev(holder()), n, off);
598 case MSGPACK_CS_ARRAY_32: {
599 parse_return ret = start_aggregate<uint32_t>(array_sv(holder()), array_ev(holder()), n, off);
602 case MSGPACK_CS_MAP_16: {
603 parse_return ret = start_aggregate<uint16_t>(map_sv(holder()), map_ev(holder()), n, off);
606 case MSGPACK_CS_MAP_32: {
607 parse_return ret = start_aggregate<uint32_t>(map_sv(holder()), map_ev(holder()), n, off);
611 off = m_current - m_start;
612 holder().visitor().parse_error(n - m_start - 1, n - m_start);
616 }
while(m_current != pe);
618 off = m_current - m_start;
627 template <
typename VisitorHolder,
typename ReferencedBufferHook>
628 class parser :
public detail::context<VisitorHolder> {
629 typedef parser<VisitorHolder, ReferencedBufferHook> this_type;
630 typedef detail::context<VisitorHolder> context_type;
641 parser(ReferencedBufferHook& hook,
644 #if !defined(MSGPACK_USE_CPP03) 645 parser(this_type&& other);
646 this_type& operator=(this_type&& other);
647 #endif // !defined(MSGPACK_USE_CPP03) 677 std::size_t buffer_capacity()
const;
689 void buffer_consumed(std::size_t size);
708 std::size_t message_size()
const;
718 std::size_t parsed_size()
const;
727 char* nonparsed_buffer();
736 std::size_t nonparsed_size()
const;
746 void skip_nonparsed_buffer(std::size_t size);
753 void remove_nonparsed_buffer();
758 char* get_raw_buffer() {
762 void expand_buffer(std::size_t size);
770 std::size_t m_parsed;
771 std::size_t m_initial_buffer_size;
772 ReferencedBufferHook& m_referenced_buffer_hook;
774 #if defined(MSGPACK_USE_CPP03) 776 parser(
const this_type&);
777 this_type& operator=(
const this_type&);
778 #else // defined(MSGPACK_USE_CPP03) 780 parser(
const this_type&) =
delete;
781 this_type& operator=(
const this_type&) =
delete;
782 #endif // defined(MSGPACK_USE_CPP03) 785 template <
typename VisitorHolder,
typename ReferencedBufferHook>
786 inline parser<VisitorHolder, ReferencedBufferHook>::parser(
787 ReferencedBufferHook& hook,
788 std::size_t initial_buffer_size)
789 :m_referenced_buffer_hook(hook)
795 char* buffer =
static_cast<char*
>(::malloc(initial_buffer_size));
797 throw std::bad_alloc();
802 m_free = initial_buffer_size - m_used;
805 m_initial_buffer_size = initial_buffer_size;
810 #if !defined(MSGPACK_USE_CPP03) 813 template <
typename VisitorHolder,
typename ReferencedBufferHook>
814 inline parser<VisitorHolder, ReferencedBufferHook>::parser(this_type&& other)
815 :context_type(std::
move(other)),
816 m_buffer(other.m_buffer),
817 m_used(other.m_used),
818 m_free(other.m_free),
820 m_parsed(other.m_parsed),
821 m_initial_buffer_size(other.m_initial_buffer_size),
822 m_referenced_buffer_hook(other.m_referenced_buffer_hook) {
830 template <
typename VisitorHolder,
typename ReferencedBufferHook>
831 inline parser<VisitorHolder, ReferencedBufferHook>& parser<VisitorHolder, ReferencedBufferHook>::operator=(this_type&& other) {
837 #endif // !defined(MSGPACK_USE_CPP03) 840 template <
typename VisitorHolder,
typename ReferencedBufferHook>
841 inline parser<VisitorHolder, ReferencedBufferHook>::~parser()
848 template <
typename VisitorHolder,
typename ReferencedBufferHook>
849 inline void parser<VisitorHolder, ReferencedBufferHook>::reserve_buffer(std::size_t size)
851 if(m_free >= size)
return;
855 template <
typename VisitorHolder,
typename ReferencedBufferHook>
856 inline void parser<VisitorHolder, ReferencedBufferHook>::expand_buffer(std::size_t size)
859 && !static_cast<VisitorHolder&>(*this).visitor().referenced()) {
865 if(m_free >= size)
return;
868 if(m_off == COUNTER_SIZE) {
869 std::size_t next_size = (m_used + m_free) * 2;
870 while(next_size < size + m_used) {
871 std::size_t tmp_next_size = next_size * 2;
872 if (tmp_next_size <= next_size) {
873 next_size = size + m_used;
876 next_size = tmp_next_size;
879 char* tmp =
static_cast<char*
>(::realloc(m_buffer, next_size));
881 throw std::bad_alloc();
885 m_free = next_size - m_used;
888 std::size_t next_size = m_initial_buffer_size;
889 std::size_t not_parsed = m_used - m_off;
890 while(next_size < size + not_parsed + COUNTER_SIZE) {
891 std::size_t tmp_next_size = next_size * 2;
892 if (tmp_next_size <= next_size) {
896 next_size = tmp_next_size;
899 char* tmp =
static_cast<char*
>(::malloc(next_size));
901 throw std::bad_alloc();
906 std::memcpy(tmp+COUNTER_SIZE, m_buffer + m_off, not_parsed);
908 if(static_cast<VisitorHolder&>(*this).referenced()) {
910 m_referenced_buffer_hook(m_buffer);
916 static_cast<VisitorHolder&
>(*this).set_referenced(
false);
923 m_free = next_size - m_used;
928 template <
typename VisitorHolder,
typename ReferencedBufferHook>
929 inline char* parser<VisitorHolder, ReferencedBufferHook>::buffer()
931 return m_buffer + m_used;
934 template <
typename VisitorHolder,
typename ReferencedBufferHook>
935 inline std::size_t parser<VisitorHolder, ReferencedBufferHook>::buffer_capacity()
const 940 template <
typename VisitorHolder,
typename ReferencedBufferHook>
941 inline void parser<VisitorHolder, ReferencedBufferHook>::buffer_consumed(std::size_t size)
947 template <
typename VisitorHolder,
typename ReferencedBufferHook>
948 inline bool parser<VisitorHolder, ReferencedBufferHook>::next()
954 template <
typename VisitorHolder,
typename ReferencedBufferHook>
955 inline parse_return parser<VisitorHolder, ReferencedBufferHook>::execute_imp()
957 std::size_t off = m_off;
958 parse_return ret = context_type::execute(m_buffer, m_used, m_off);
960 m_parsed += m_off - off;
965 template <
typename VisitorHolder,
typename ReferencedBufferHook>
966 inline void parser<VisitorHolder, ReferencedBufferHook>::reset()
968 context_type::init();
973 template <
typename VisitorHolder,
typename ReferencedBufferHook>
974 inline std::size_t parser<VisitorHolder, ReferencedBufferHook>::message_size()
const 976 return m_parsed - m_off + m_used;
979 template <
typename VisitorHolder,
typename ReferencedBufferHook>
980 inline std::size_t parser<VisitorHolder, ReferencedBufferHook>::parsed_size()
const 985 template <
typename VisitorHolder,
typename ReferencedBufferHook>
986 inline char* parser<VisitorHolder, ReferencedBufferHook>::nonparsed_buffer()
988 return m_buffer + m_off;
991 template <
typename VisitorHolder,
typename ReferencedBufferHook>
992 inline std::size_t parser<VisitorHolder, ReferencedBufferHook>::nonparsed_size()
const 994 return m_used - m_off;
997 template <
typename VisitorHolder,
typename ReferencedBufferHook>
998 inline void parser<VisitorHolder, ReferencedBufferHook>::skip_nonparsed_buffer(std::size_t size)
1003 template <
typename VisitorHolder,
typename ReferencedBufferHook>
1004 inline void parser<VisitorHolder, ReferencedBufferHook>::remove_nonparsed_buffer()
1009 template <
typename Visitor>
1010 inline bool parse(
const char* data,
size_t len,
size_t& off, Visitor& v) {
1015 template <
typename Visitor>
1016 inline bool parse(
const char* data,
size_t len, Visitor& v) {
1017 std::size_t off = 0;
1023 template <
typename Visitor>
1024 struct parse_helper : detail::context<parse_helper<Visitor> > {
1025 parse_helper(Visitor& v):m_visitor(v) {}
1026 parse_return execute(
const char* data, std::size_t len, std::size_t& off) {
1027 return detail::context<parse_helper<Visitor> >::execute(data, len, off);
1029 Visitor& visitor()
const {
return m_visitor; }
1033 template <
typename Visitor>
1035 parse_imp(
const char* data,
size_t len,
size_t& off, Visitor& v) {
1036 std::size_t noff = off;
1040 v.insufficient_bytes(noff, noff);
1043 detail::parse_helper<Visitor> h(v);
1048 v.insufficient_bytes(noff - 1, noff);
1070 #endif // MSGPACK_DEFAULT_API_VERSION >= 2 1072 #endif // MSGPACK_V2_PARSE_HPP
#define MSGPACK_UNPACKER_INIT_BUFFER_SIZE
Definition: unpack_decl.hpp:43
parse_return
Definition: parse_return.hpp:23
void init()
Definition: unpack.hpp:312
Definition: parse_return.hpp:27
context(unpack_reference_func f, void *user_data, unpack_limit const &limit)
Definition: unpack.hpp:305
T type
Definition: unpack.hpp:271
Definition: adaptor_base.hpp:15
Definition: unpack_exception.hpp:97
void init_count(void *buffer)
Definition: unpack.hpp:226
Definition: parse_return.hpp:26
msgpack::enable_if< sizeof(T)==sizeof(fix_tag)>::type load(uint32_t &dst, const char *n)
Definition: unpack.hpp:279
std::size_t size(T const &t)
Definition: size_equal_only.hpp:24
const size_t COUNTER_SIZE
Definition: unpack_decl.hpp:40
Definition: parse_return.hpp:28
std::atomic< unsigned int > const & get_count(void *buffer)
Definition: unpack.hpp:263
bool parse(const char *data, size_t len, size_t &off, Visitor &v)
Unpack msgpack formatted data via a visitor.
Object class that corresponding to MessagePack format object.
Definition: object_fwd.hpp:75
#define MSGPACK_API_VERSION_NAMESPACE(ns)
Definition: versioning.hpp:58
Definition: parse_return.hpp:24
parse_return parse_imp(const char *data, size_t len, size_t &off, Visitor &v)
Definition: parse_return.hpp:25
msgpack::object const & data() const
Definition: unpack.hpp:320
void decr_count(void *buffer)
Definition: unpack.hpp:235
#define MSGPACK_NULLPTR
Definition: cpp_config_decl.hpp:35
int execute(const char *data, std::size_t len, std::size_t &off)
Definition: unpack.hpp:452
#define MSGPACK_UNPACKER_RESERVE_SIZE
Definition: unpack_decl.hpp:47