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 =
static_cast<std::size_t
>(m_current - m_start);
78 off =
static_cast<std::size_t
>(m_current - m_start);
83 off =
static_cast<std::size_t
>(m_current - m_start);
89 off =
static_cast<std::size_t
>(m_current - m_start);
92 parse_return ret = m_stack.push(holder(), sv.type(),
static_cast<uint32_t
>(
size));
94 off =
static_cast<std::size_t
>(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 =
static_cast<std::size_t
>(m_current - m_start);
110 off =
static_cast<std::size_t
>(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;
244 if(m_current == pe) {
245 off =
static_cast<std::size_t
>(m_current - m_start);
248 bool fixed_trail_again =
false;
250 if (m_cs == MSGPACK_CS_HEADER) {
251 fixed_trail_again =
false;
252 int selector = *
reinterpret_cast<const unsigned char*
>(m_current);
253 if (0x00 <= selector && selector <= 0x7f) {
254 uint8_t tmp = *
reinterpret_cast<const uint8_t*
>(m_current);
255 bool visret = holder().visitor().visit_positive_integer(tmp);
258 }
else if(0xe0 <= selector && selector <= 0xff) {
259 int8_t tmp = *
reinterpret_cast<const int8_t*
>(m_current);
260 bool visret = holder().visitor().visit_negative_integer(tmp);
263 }
else if (0xc4 <= selector && selector <= 0xdf) {
264 const uint32_t trail[] = {
294 m_trail = trail[selector - 0xc4];
295 m_cs = next_cs(m_current);
296 fixed_trail_again =
true;
297 }
else if(0xa0 <= selector && selector <= 0xbf) {
298 m_trail =
static_cast<uint32_t
>(*m_current) & 0x1f;
300 bool visret = holder().visitor().visit_str(n,
static_cast<uint32_t
>(m_trail));
305 m_cs = MSGPACK_ACS_STR_VALUE;
306 fixed_trail_again =
true;
308 }
else if(0x90 <= selector && selector <= 0x9f) {
309 parse_return ret = start_aggregate<fix_tag>(array_sv(holder()), array_ev(holder()), m_current, off);
311 }
else if(0x80 <= selector && selector <= 0x8f) {
312 parse_return ret = start_aggregate<fix_tag>(map_sv(holder()), map_ev(holder()), m_current, off);
314 }
else if(selector == 0xc2) {
315 bool visret = holder().visitor().visit_boolean(
false);
318 }
else if(selector == 0xc3) {
319 bool visret = holder().visitor().visit_boolean(
true);
322 }
else if(selector == 0xc0) {
323 bool visret = holder().visitor().visit_nil();
327 off =
static_cast<std::size_t
>(m_current - m_start);
328 holder().visitor().parse_error(off - 1, off);
333 if (m_cs != MSGPACK_CS_HEADER || fixed_trail_again) {
334 if (fixed_trail_again) {
336 fixed_trail_again =
false;
338 if(
static_cast<std::size_t
>(pe - m_current) < m_trail) {
339 off =
static_cast<std::size_t
>(m_current - m_start);
343 m_current += m_trail - 1;
347 case MSGPACK_CS_FLOAT: {
348 union { uint32_t i;
float f; } mem;
349 load<uint32_t>(mem.i, n);
350 bool visret = holder().visitor().visit_float32(mem.f);
354 case MSGPACK_CS_DOUBLE: {
355 union { uint64_t i;
double f; } mem;
356 load<uint64_t>(mem.i, n);
357 #if defined(TARGET_OS_IPHONE)
359 #elif defined(__arm__) && !(__ARM_EABI__) // arm-oabi
361 mem.i = (mem.i & 0xFFFFFFFFUL) << 32UL | (mem.i >> 32UL);
363 bool visret = holder().visitor().visit_float64(mem.f);
367 case MSGPACK_CS_UINT_8: {
369 load<uint8_t>(tmp, n);
370 bool visret = holder().visitor().visit_positive_integer(tmp);
374 case MSGPACK_CS_UINT_16: {
376 load<uint16_t>(tmp, n);
377 bool visret = holder().visitor().visit_positive_integer(tmp);
381 case MSGPACK_CS_UINT_32: {
383 load<uint32_t>(tmp, n);
384 bool visret = holder().visitor().visit_positive_integer(tmp);
388 case MSGPACK_CS_UINT_64: {
390 load<uint64_t>(tmp, n);
391 bool visret = holder().visitor().visit_positive_integer(tmp);
395 case MSGPACK_CS_INT_8: {
397 load<int8_t>(tmp, n);
398 bool visret = holder().visitor().visit_negative_integer(tmp);
402 case MSGPACK_CS_INT_16: {
404 load<int16_t>(tmp, n);
405 bool visret = holder().visitor().visit_negative_integer(tmp);
409 case MSGPACK_CS_INT_32: {
411 load<int32_t>(tmp, n);
412 bool visret = holder().visitor().visit_negative_integer(tmp);
416 case MSGPACK_CS_INT_64: {
418 load<int64_t>(tmp, n);
419 bool visret = holder().visitor().visit_negative_integer(tmp);
423 case MSGPACK_CS_FIXEXT_1: {
424 bool visret = holder().visitor().visit_ext(n, 1+1);
428 case MSGPACK_CS_FIXEXT_2: {
429 bool visret = holder().visitor().visit_ext(n, 2+1);
433 case MSGPACK_CS_FIXEXT_4: {
434 bool visret = holder().visitor().visit_ext(n, 4+1);
438 case MSGPACK_CS_FIXEXT_8: {
439 bool visret = holder().visitor().visit_ext(n, 8+1);
443 case MSGPACK_CS_FIXEXT_16: {
444 bool visret = holder().visitor().visit_ext(n, 16+1);
448 case MSGPACK_CS_STR_8: {
450 load<uint8_t>(tmp, n);
453 bool visret = holder().visitor().visit_str(n,
static_cast<uint32_t
>(m_trail));
458 m_cs = MSGPACK_ACS_STR_VALUE;
459 fixed_trail_again =
true;
462 case MSGPACK_CS_BIN_8: {
464 load<uint8_t>(tmp, n);
467 bool visret = holder().visitor().visit_bin(n,
static_cast<uint32_t
>(m_trail));
472 m_cs = MSGPACK_ACS_BIN_VALUE;
473 fixed_trail_again =
true;
476 case MSGPACK_CS_EXT_8: {
478 load<uint8_t>(tmp, n);
481 bool visret = holder().visitor().visit_ext(n,
static_cast<uint32_t
>(m_trail));
486 m_cs = MSGPACK_ACS_EXT_VALUE;
487 fixed_trail_again =
true;
490 case MSGPACK_CS_STR_16: {
492 load<uint16_t>(tmp, n);
495 bool visret = holder().visitor().visit_str(n,
static_cast<uint32_t
>(m_trail));
500 m_cs = MSGPACK_ACS_STR_VALUE;
501 fixed_trail_again =
true;
504 case MSGPACK_CS_BIN_16: {
506 load<uint16_t>(tmp, n);
509 bool visret = holder().visitor().visit_bin(n,
static_cast<uint32_t
>(m_trail));
514 m_cs = MSGPACK_ACS_BIN_VALUE;
515 fixed_trail_again =
true;
518 case MSGPACK_CS_EXT_16: {
520 load<uint16_t>(tmp, n);
523 bool visret = holder().visitor().visit_ext(n,
static_cast<uint32_t
>(m_trail));
528 m_cs = MSGPACK_ACS_EXT_VALUE;
529 fixed_trail_again =
true;
532 case MSGPACK_CS_STR_32: {
534 load<uint32_t>(tmp, n);
537 bool visret = holder().visitor().visit_str(n,
static_cast<uint32_t
>(m_trail));
542 m_cs = MSGPACK_ACS_STR_VALUE;
543 fixed_trail_again =
true;
546 case MSGPACK_CS_BIN_32: {
548 load<uint32_t>(tmp, n);
551 bool visret = holder().visitor().visit_bin(n,
static_cast<uint32_t
>(m_trail));
556 m_cs = MSGPACK_ACS_BIN_VALUE;
557 fixed_trail_again =
true;
560 case MSGPACK_CS_EXT_32: {
562 load<uint32_t>(tmp, n);
563 check_ext_size<sizeof(std::size_t)>(tmp);
567 bool visret = holder().visitor().visit_ext(n,
static_cast<uint32_t
>(m_trail));
572 m_cs = MSGPACK_ACS_EXT_VALUE;
573 fixed_trail_again =
true;
576 case MSGPACK_ACS_STR_VALUE: {
577 bool visret = holder().visitor().visit_str(n,
static_cast<uint32_t
>(m_trail));
581 case MSGPACK_ACS_BIN_VALUE: {
582 bool visret = holder().visitor().visit_bin(n,
static_cast<uint32_t
>(m_trail));
586 case MSGPACK_ACS_EXT_VALUE: {
587 bool visret = holder().visitor().visit_ext(n,
static_cast<uint32_t
>(m_trail));
591 case MSGPACK_CS_ARRAY_16: {
592 parse_return ret = start_aggregate<uint16_t>(array_sv(holder()), array_ev(holder()), n, off);
596 case MSGPACK_CS_ARRAY_32: {
597 parse_return ret = start_aggregate<uint32_t>(array_sv(holder()), array_ev(holder()), n, off);
600 case MSGPACK_CS_MAP_16: {
601 parse_return ret = start_aggregate<uint16_t>(map_sv(holder()), map_ev(holder()), n, off);
604 case MSGPACK_CS_MAP_32: {
605 parse_return ret = start_aggregate<uint32_t>(map_sv(holder()), map_ev(holder()), n, off);
609 off =
static_cast<std::size_t
>(m_current - m_start);
610 holder().visitor().parse_error(
static_cast<std::size_t
>(n - m_start - 1),
static_cast<std::size_t
>(n - m_start));
614 }
while(m_current != pe);
616 off =
static_cast<std::size_t
>(m_current - m_start);
625 template <
typename VisitorHolder,
typename ReferencedBufferHook>
626 class parser :
public detail::context<VisitorHolder> {
627 typedef parser<VisitorHolder, ReferencedBufferHook> this_type;
628 typedef detail::context<VisitorHolder> context_type;
639 parser(ReferencedBufferHook& hook,
642 #if !defined(MSGPACK_USE_CPP03)
643 parser(this_type&& other);
644 this_type& operator=(this_type&& other);
645 #endif // !defined(MSGPACK_USE_CPP03)
675 std::size_t buffer_capacity()
const;
687 void buffer_consumed(std::size_t
size);
706 std::size_t message_size()
const;
716 std::size_t parsed_size()
const;
725 char* nonparsed_buffer();
734 std::size_t nonparsed_size()
const;
744 void skip_nonparsed_buffer(std::size_t
size);
751 void remove_nonparsed_buffer();
756 char* get_raw_buffer() {
760 void expand_buffer(std::size_t
size);
768 std::size_t m_parsed;
769 std::size_t m_initial_buffer_size;
770 ReferencedBufferHook& m_referenced_buffer_hook;
772 #if defined(MSGPACK_USE_CPP03)
774 parser(
const this_type&);
775 this_type& operator=(
const this_type&);
776 #else // defined(MSGPACK_USE_CPP03)
778 parser(
const this_type&) =
delete;
779 this_type& operator=(
const this_type&) =
delete;
780 #endif // defined(MSGPACK_USE_CPP03)
783 template <
typename VisitorHolder,
typename ReferencedBufferHook>
784 inline parser<VisitorHolder, ReferencedBufferHook>::parser(
785 ReferencedBufferHook& hook,
786 std::size_t initial_buffer_size)
787 :m_referenced_buffer_hook(hook)
793 char* buffer =
static_cast<char*
>(::malloc(initial_buffer_size));
795 throw std::bad_alloc();
800 m_free = initial_buffer_size - m_used;
803 m_initial_buffer_size = initial_buffer_size;
808 #if !defined(MSGPACK_USE_CPP03)
811 template <
typename VisitorHolder,
typename ReferencedBufferHook>
812 inline parser<VisitorHolder, ReferencedBufferHook>::parser(this_type&& other)
813 :context_type(std::
move(other)),
814 m_buffer(other.m_buffer),
815 m_used(other.m_used),
816 m_free(other.m_free),
818 m_parsed(other.m_parsed),
819 m_initial_buffer_size(other.m_initial_buffer_size),
820 m_referenced_buffer_hook(other.m_referenced_buffer_hook) {
828 template <
typename VisitorHolder,
typename ReferencedBufferHook>
829 inline parser<VisitorHolder, ReferencedBufferHook>& parser<VisitorHolder, ReferencedBufferHook>::operator=(this_type&& other) {
835 #endif // !defined(MSGPACK_USE_CPP03)
838 template <
typename VisitorHolder,
typename ReferencedBufferHook>
839 inline parser<VisitorHolder, ReferencedBufferHook>::~parser()
846 template <
typename VisitorHolder,
typename ReferencedBufferHook>
847 inline void parser<VisitorHolder, ReferencedBufferHook>::reserve_buffer(std::size_t
size)
849 if(m_free >=
size)
return;
853 template <
typename VisitorHolder,
typename ReferencedBufferHook>
854 inline void parser<VisitorHolder, ReferencedBufferHook>::expand_buffer(std::size_t
size)
857 && !
static_cast<VisitorHolder&
>(*this).visitor().referenced()) {
863 if(m_free >=
size)
return;
867 std::size_t next_size = (m_used + m_free) * 2;
868 while(next_size <
size + m_used) {
869 std::size_t tmp_next_size = next_size * 2;
870 if (tmp_next_size <= next_size) {
871 next_size =
size + m_used;
874 next_size = tmp_next_size;
877 char* tmp =
static_cast<char*
>(::realloc(m_buffer, next_size));
879 throw std::bad_alloc();
883 m_free = next_size - m_used;
886 std::size_t next_size = m_initial_buffer_size;
887 std::size_t not_parsed = m_used - m_off;
889 std::size_t tmp_next_size = next_size * 2;
890 if (tmp_next_size <= next_size) {
894 next_size = tmp_next_size;
897 char* tmp =
static_cast<char*
>(::malloc(next_size));
899 throw std::bad_alloc();
904 std::memcpy(tmp+
COUNTER_SIZE, m_buffer + m_off, not_parsed);
906 if(
static_cast<VisitorHolder&
>(*this).referenced()) {
908 m_referenced_buffer_hook(m_buffer);
914 static_cast<VisitorHolder&
>(*this).set_referenced(
false);
921 m_free = next_size - m_used;
926 template <
typename VisitorHolder,
typename ReferencedBufferHook>
927 inline char* parser<VisitorHolder, ReferencedBufferHook>::buffer()
929 return m_buffer + m_used;
932 template <
typename VisitorHolder,
typename ReferencedBufferHook>
933 inline std::size_t parser<VisitorHolder, ReferencedBufferHook>::buffer_capacity()
const
938 template <
typename VisitorHolder,
typename ReferencedBufferHook>
939 inline void parser<VisitorHolder, ReferencedBufferHook>::buffer_consumed(std::size_t
size)
945 template <
typename VisitorHolder,
typename ReferencedBufferHook>
946 inline bool parser<VisitorHolder, ReferencedBufferHook>::next()
952 template <
typename VisitorHolder,
typename ReferencedBufferHook>
953 inline parse_return parser<VisitorHolder, ReferencedBufferHook>::execute_imp()
955 std::size_t off = m_off;
956 parse_return ret = context_type::execute(m_buffer, m_used, m_off);
958 m_parsed += m_off - off;
963 template <
typename VisitorHolder,
typename ReferencedBufferHook>
964 inline void parser<VisitorHolder, ReferencedBufferHook>::reset()
966 context_type::init();
971 template <
typename VisitorHolder,
typename ReferencedBufferHook>
972 inline std::size_t parser<VisitorHolder, ReferencedBufferHook>::message_size()
const
974 return m_parsed - m_off + m_used;
977 template <
typename VisitorHolder,
typename ReferencedBufferHook>
978 inline std::size_t parser<VisitorHolder, ReferencedBufferHook>::parsed_size()
const
983 template <
typename VisitorHolder,
typename ReferencedBufferHook>
984 inline char* parser<VisitorHolder, ReferencedBufferHook>::nonparsed_buffer()
986 return m_buffer + m_off;
989 template <
typename VisitorHolder,
typename ReferencedBufferHook>
990 inline std::size_t parser<VisitorHolder, ReferencedBufferHook>::nonparsed_size()
const
992 return m_used - m_off;
995 template <
typename VisitorHolder,
typename ReferencedBufferHook>
996 inline void parser<VisitorHolder, ReferencedBufferHook>::skip_nonparsed_buffer(std::size_t
size)
1001 template <
typename VisitorHolder,
typename ReferencedBufferHook>
1002 inline void parser<VisitorHolder, ReferencedBufferHook>::remove_nonparsed_buffer()
1007 template <
typename Visitor>
1008 inline bool parse(
const char* data,
size_t len,
size_t& off, Visitor& v) {
1013 template <
typename Visitor>
1014 inline bool parse(
const char* data,
size_t len, Visitor& v) {
1015 std::size_t off = 0;
1021 template <
typename Visitor>
1022 struct parse_helper : detail::context<parse_helper<Visitor> > {
1023 parse_helper(Visitor& v):m_visitor(v) {}
1024 parse_return execute(
const char* data, std::size_t len, std::size_t& off) {
1025 return detail::context<parse_helper<Visitor> >::execute(data, len, off);
1027 Visitor& visitor()
const {
return m_visitor; }
1031 template <
typename Visitor>
1033 parse_imp(
const char* data,
size_t len,
size_t& off, Visitor& v) {
1034 std::size_t noff = off;
1038 v.insufficient_bytes(noff, noff);
1041 detail::parse_helper<Visitor> h(v);
1046 v.insufficient_bytes(noff - 1, noff);
1068 #endif // MSGPACK_DEFAULT_API_VERSION >= 2
1070 #endif // MSGPACK_V2_PARSE_HPP