10#ifndef MSGPACK_V2_PARSE_HPP
11#define MSGPACK_V2_PARSE_HPP
13#if MSGPACK_DEFAULT_API_VERSION >= 2
31using v1::detail::fix_tag;
32using v1::detail::value;
33using v1::detail::load;
35template <
typename VisitorHolder>
48 holder().visitor().init();
55 static uint32_t next_cs(T p)
57 return static_cast<uint32_t
>(*p) & 0x1f;
60 VisitorHolder& holder() {
61 return static_cast<VisitorHolder&
>(*this);
64 template <
typename T,
typename StartVisitor,
typename EndVisitor>
66 StartVisitor
const& sv,
71 load<T>(size, load_pos);
75 off =
static_cast<std::size_t
>(m_current - m_start);
79 off =
static_cast<std::size_t
>(m_current - m_start);
83 if (ret != PARSE_CONTINUE) {
84 off =
static_cast<std::size_t
>(m_current - m_start);
90 off =
static_cast<std::size_t
>(m_current - m_start);
93 parse_return ret = m_stack.push(holder(), sv.type(),
static_cast<uint32_t
>(
size));
94 if (ret != PARSE_CONTINUE) {
95 off =
static_cast<std::size_t
>(m_current - m_start);
103 parse_return after_visit_proc(
bool visit_result, std::size_t& off) {
106 off =
static_cast<std::size_t
>(m_current - m_start);
110 if (ret != PARSE_CONTINUE) {
111 off =
static_cast<std::size_t
>(m_current - m_start);
118 array_sv(VisitorHolder& visitor_holder):m_visitor_holder(visitor_holder) {}
119 bool operator()(uint32_t size)
const {
120 return m_visitor_holder.visitor().start_array(size);
124 VisitorHolder& m_visitor_holder;
127 array_ev(VisitorHolder& visitor_holder):m_visitor_holder(visitor_holder) {}
128 bool operator()()
const {
129 return m_visitor_holder.visitor().end_array();
132 VisitorHolder& m_visitor_holder;
135 map_sv(VisitorHolder& visitor_holder):m_visitor_holder(visitor_holder) {}
136 bool operator()(uint32_t size)
const {
137 return m_visitor_holder.visitor().start_map(size);
141 VisitorHolder& m_visitor_holder;
144 map_ev(VisitorHolder& visitor_holder):m_visitor_holder(visitor_holder) {}
145 bool operator()()
const {
146 return m_visitor_holder.visitor().end_map();
149 VisitorHolder& m_visitor_holder;
152 struct unpack_stack {
162 m_stack.push_back(stack_elem(type, rest));
176 while (!m_stack.empty()) {
177 stack_elem& e = m_stack.back();
181 if (--e.m_rest == 0) {
197 if (--e.m_rest == 0) {
211 bool empty()
const {
return m_stack.empty(); }
212 void clear() { m_stack.clear(); }
214 std::vector<stack_elem> m_stack;
218 char const* m_current;
222 uint32_t m_num_elements;
223 unpack_stack m_stack;
226template <std::
size_t N>
227inline void check_ext_size(std::size_t ) {
231inline void check_ext_size<4>(std::size_t size) {
235template <
typename VisitorHolder>
241 m_current = data + off;
242 const char*
const pe = data + len;
245 if(m_current == pe) {
246 off =
static_cast<std::size_t
>(m_current - m_start);
249 bool fixed_trail_again =
false;
252 fixed_trail_again =
false;
253 int selector = *
reinterpret_cast<const unsigned char*
>(m_current);
254 if (0x00 <= selector && selector <= 0x7f) {
255 uint8_t tmp = *
reinterpret_cast<const uint8_t*
>(m_current);
256 bool visret = holder().visitor().visit_positive_integer(tmp);
258 if (upr != PARSE_CONTINUE)
return upr;
259 }
else if(0xe0 <= selector && selector <= 0xff) {
260 int8_t tmp = *
reinterpret_cast<const int8_t*
>(m_current);
261 bool visret = holder().visitor().visit_negative_integer(tmp);
263 if (upr != PARSE_CONTINUE)
return upr;
264 }
else if (0xc4 <= selector && selector <= 0xdf) {
265 const uint32_t trail[] = {
295 m_trail = trail[selector - 0xc4];
296 m_cs = next_cs(m_current);
297 fixed_trail_again =
true;
298 }
else if(0xa0 <= selector && selector <= 0xbf) {
299 m_trail =
static_cast<uint32_t
>(*m_current) & 0x1f;
301 bool visret = holder().visitor().visit_str(n,
static_cast<uint32_t
>(m_trail));
303 if (upr != PARSE_CONTINUE)
return upr;
307 fixed_trail_again =
true;
309 }
else if(0x90 <= selector && selector <= 0x9f) {
310 parse_return ret = start_aggregate<fix_tag>(array_sv(holder()), array_ev(holder()), m_current, off);
311 if (ret != PARSE_CONTINUE)
return ret;
312 }
else if(0x80 <= selector && selector <= 0x8f) {
313 parse_return ret = start_aggregate<fix_tag>(map_sv(holder()), map_ev(holder()), m_current, off);
314 if (ret != PARSE_CONTINUE)
return ret;
315 }
else if(selector == 0xc2) {
316 bool visret = holder().visitor().visit_boolean(
false);
318 if (upr != PARSE_CONTINUE)
return upr;
319 }
else if(selector == 0xc3) {
320 bool visret = holder().visitor().visit_boolean(
true);
322 if (upr != PARSE_CONTINUE)
return upr;
323 }
else if(selector == 0xc0) {
324 bool visret = holder().visitor().visit_nil();
326 if (upr != PARSE_CONTINUE)
return upr;
328 off =
static_cast<std::size_t
>(m_current - m_start);
329 holder().visitor().parse_error(off - 1, off);
335 if (fixed_trail_again) {
337 fixed_trail_again =
false;
339 if(
static_cast<std::size_t
>(pe - m_current) < m_trail) {
340 off =
static_cast<std::size_t
>(m_current - m_start);
344 m_current += m_trail - 1;
349 union { uint32_t i;
float f; } mem;
350 load<uint32_t>(mem.i, n);
351 bool visret = holder().visitor().visit_float32(mem.f);
353 if (upr != PARSE_CONTINUE)
return upr;
356 union { uint64_t i;
double f; } mem;
357 load<uint64_t>(mem.i, n);
358#if defined(TARGET_OS_IPHONE)
360#elif defined(__arm__) && !(__ARM_EABI__)
362 mem.i = (mem.i & 0xFFFFFFFFUL) << 32UL | (mem.i >> 32UL);
364 bool visret = holder().visitor().visit_float64(mem.f);
366 if (upr != PARSE_CONTINUE)
return upr;
370 load<uint8_t>(tmp, n);
371 bool visret = holder().visitor().visit_positive_integer(tmp);
373 if (upr != PARSE_CONTINUE)
return upr;
377 load<uint16_t>(tmp, n);
378 bool visret = holder().visitor().visit_positive_integer(tmp);
380 if (upr != PARSE_CONTINUE)
return upr;
384 load<uint32_t>(tmp, n);
385 bool visret = holder().visitor().visit_positive_integer(tmp);
387 if (upr != PARSE_CONTINUE)
return upr;
391 load<uint64_t>(tmp, n);
392 bool visret = holder().visitor().visit_positive_integer(tmp);
394 if (upr != PARSE_CONTINUE)
return upr;
398 load<int8_t>(tmp, n);
399 bool visret = holder().visitor().visit_negative_integer(tmp);
401 if (upr != PARSE_CONTINUE)
return upr;
405 load<int16_t>(tmp, n);
406 bool visret = holder().visitor().visit_negative_integer(tmp);
408 if (upr != PARSE_CONTINUE)
return upr;
412 load<int32_t>(tmp, n);
413 bool visret = holder().visitor().visit_negative_integer(tmp);
415 if (upr != PARSE_CONTINUE)
return upr;
419 load<int64_t>(tmp, n);
420 bool visret = holder().visitor().visit_negative_integer(tmp);
422 if (upr != PARSE_CONTINUE)
return upr;
425 bool visret = holder().visitor().visit_ext(n, 1+1);
427 if (upr != PARSE_CONTINUE)
return upr;
430 bool visret = holder().visitor().visit_ext(n, 2+1);
432 if (upr != PARSE_CONTINUE)
return upr;
435 bool visret = holder().visitor().visit_ext(n, 4+1);
437 if (upr != PARSE_CONTINUE)
return upr;
440 bool visret = holder().visitor().visit_ext(n, 8+1);
442 if (upr != PARSE_CONTINUE)
return upr;
445 bool visret = holder().visitor().visit_ext(n, 16+1);
447 if (upr != PARSE_CONTINUE)
return upr;
451 load<uint8_t>(tmp, n);
454 bool visret = holder().visitor().visit_str(n,
static_cast<uint32_t
>(m_trail));
456 if (upr != PARSE_CONTINUE)
return upr;
460 fixed_trail_again =
true;
465 load<uint8_t>(tmp, n);
468 bool visret = holder().visitor().visit_bin(n,
static_cast<uint32_t
>(m_trail));
470 if (upr != PARSE_CONTINUE)
return upr;
474 fixed_trail_again =
true;
479 load<uint8_t>(tmp, n);
482 bool visret = holder().visitor().visit_ext(n,
static_cast<uint32_t
>(m_trail));
484 if (upr != PARSE_CONTINUE)
return upr;
488 fixed_trail_again =
true;
493 load<uint16_t>(tmp, n);
496 bool visret = holder().visitor().visit_str(n,
static_cast<uint32_t
>(m_trail));
498 if (upr != PARSE_CONTINUE)
return upr;
502 fixed_trail_again =
true;
507 load<uint16_t>(tmp, n);
510 bool visret = holder().visitor().visit_bin(n,
static_cast<uint32_t
>(m_trail));
512 if (upr != PARSE_CONTINUE)
return upr;
516 fixed_trail_again =
true;
521 load<uint16_t>(tmp, n);
524 bool visret = holder().visitor().visit_ext(n,
static_cast<uint32_t
>(m_trail));
526 if (upr != PARSE_CONTINUE)
return upr;
530 fixed_trail_again =
true;
535 load<uint32_t>(tmp, n);
538 bool visret = holder().visitor().visit_str(n,
static_cast<uint32_t
>(m_trail));
540 if (upr != PARSE_CONTINUE)
return upr;
544 fixed_trail_again =
true;
549 load<uint32_t>(tmp, n);
552 bool visret = holder().visitor().visit_bin(n,
static_cast<uint32_t
>(m_trail));
554 if (upr != PARSE_CONTINUE)
return upr;
558 fixed_trail_again =
true;
563 load<uint32_t>(tmp, n);
564 check_ext_size<sizeof(std::size_t)>(tmp);
568 bool visret = holder().visitor().visit_ext(n,
static_cast<uint32_t
>(m_trail));
570 if (upr != PARSE_CONTINUE)
return upr;
574 fixed_trail_again =
true;
578 bool visret = holder().visitor().visit_str(n,
static_cast<uint32_t
>(m_trail));
580 if (upr != PARSE_CONTINUE)
return upr;
583 bool visret = holder().visitor().visit_bin(n,
static_cast<uint32_t
>(m_trail));
585 if (upr != PARSE_CONTINUE)
return upr;
588 bool visret = holder().visitor().visit_ext(n,
static_cast<uint32_t
>(m_trail));
590 if (upr != PARSE_CONTINUE)
return upr;
593 parse_return ret = start_aggregate<uint16_t>(array_sv(holder()), array_ev(holder()), n, off);
594 if (ret != PARSE_CONTINUE)
return ret;
598 parse_return ret = start_aggregate<uint32_t>(array_sv(holder()), array_ev(holder()), n, off);
599 if (ret != PARSE_CONTINUE)
return ret;
602 parse_return ret = start_aggregate<uint16_t>(map_sv(holder()), map_ev(holder()), n, off);
603 if (ret != PARSE_CONTINUE)
return ret;
606 parse_return ret = start_aggregate<uint32_t>(map_sv(holder()), map_ev(holder()), n, off);
607 if (ret != PARSE_CONTINUE)
return ret;
610 off =
static_cast<std::size_t
>(m_current - m_start);
611 holder().visitor().parse_error(
static_cast<std::size_t
>(n - m_start - 1),
static_cast<std::size_t
>(n - m_start));
615 }
while(m_current != pe);
617 off =
static_cast<std::size_t
>(m_current - m_start);
626template <
typename VisitorHolder,
typename ReferencedBufferHook>
627class parser :
public detail::context<VisitorHolder> {
628 typedef parser<VisitorHolder, ReferencedBufferHook> this_type;
629 typedef detail::context<VisitorHolder> context_type;
640 parser(ReferencedBufferHook& hook,
643#if !defined(MSGPACK_USE_CPP03)
644 parser(this_type&& other);
645 this_type& operator=(this_type&& other);
676 std::size_t buffer_capacity()
const;
688 void buffer_consumed(std::size_t size);
707 std::size_t message_size()
const;
717 std::size_t parsed_size()
const;
726 char* nonparsed_buffer();
735 std::size_t nonparsed_size()
const;
745 void skip_nonparsed_buffer(std::size_t size);
752 void remove_nonparsed_buffer();
757 char* get_raw_buffer() {
761 void expand_buffer(std::size_t size);
769 std::size_t m_parsed;
770 std::size_t m_initial_buffer_size;
771 ReferencedBufferHook& m_referenced_buffer_hook;
773#if defined(MSGPACK_USE_CPP03)
775 parser(
const this_type&);
776 this_type& operator=(
const this_type&);
779 parser(
const this_type&) =
delete;
780 this_type& operator=(
const this_type&) =
delete;
784template <
typename VisitorHolder,
typename ReferencedBufferHook>
785inline parser<VisitorHolder, ReferencedBufferHook>::parser(
786 ReferencedBufferHook& hook,
787 std::size_t initial_buffer_size)
788 :m_referenced_buffer_hook(hook)
794 char* buffer =
static_cast<char*
>(::malloc(initial_buffer_size));
796 throw std::bad_alloc();
801 m_free = initial_buffer_size - m_used;
804 m_initial_buffer_size = initial_buffer_size;
806 detail::init_count(m_buffer);
809#if !defined(MSGPACK_USE_CPP03)
812template <
typename VisitorHolder,
typename ReferencedBufferHook>
813inline parser<VisitorHolder, ReferencedBufferHook>::parser(this_type&& other)
814 :context_type(std::move(other)),
815 m_buffer(other.m_buffer),
816 m_used(other.m_used),
817 m_free(other.m_free),
819 m_parsed(other.m_parsed),
820 m_initial_buffer_size(other.m_initial_buffer_size),
821 m_referenced_buffer_hook(other.m_referenced_buffer_hook) {
829template <
typename VisitorHolder,
typename ReferencedBufferHook>
830inline parser<VisitorHolder, ReferencedBufferHook>& parser<VisitorHolder, ReferencedBufferHook>::operator=(this_type&& other) {
832 new (
this) this_type(std::move(other));
839template <
typename VisitorHolder,
typename ReferencedBufferHook>
840inline parser<VisitorHolder, ReferencedBufferHook>::~parser()
843 if (m_buffer) detail::decr_count(m_buffer);
847template <
typename VisitorHolder,
typename ReferencedBufferHook>
848inline void parser<VisitorHolder, ReferencedBufferHook>::reserve_buffer(std::size_t size)
850 if(m_free >= size)
return;
854template <
typename VisitorHolder,
typename ReferencedBufferHook>
855inline void parser<VisitorHolder, ReferencedBufferHook>::expand_buffer(std::size_t size)
857 if(m_used == m_off && detail::get_count(m_buffer) == 1
858 && !
static_cast<VisitorHolder&
>(*this).visitor().referenced()) {
864 if(m_free >= size)
return;
868 std::size_t next_size = (m_used + m_free) * 2;
869 while(next_size < size + m_used) {
870 std::size_t tmp_next_size = next_size * 2;
871 if (tmp_next_size <= next_size) {
872 next_size =
size + m_used;
875 next_size = tmp_next_size;
878 char* tmp =
static_cast<char*
>(::realloc(m_buffer, next_size));
880 throw std::bad_alloc();
884 m_free = next_size - m_used;
887 std::size_t next_size = m_initial_buffer_size;
888 std::size_t not_parsed = m_used - m_off;
890 std::size_t tmp_next_size = next_size * 2;
891 if (tmp_next_size <= next_size) {
895 next_size = tmp_next_size;
898 char* tmp =
static_cast<char*
>(::malloc(next_size));
900 throw std::bad_alloc();
903 detail::init_count(tmp);
905 std::memcpy(tmp+
COUNTER_SIZE, m_buffer + m_off, not_parsed);
907 if(
static_cast<VisitorHolder&
>(*this).referenced()) {
909 m_referenced_buffer_hook(m_buffer);
915 static_cast<VisitorHolder&
>(*this).set_referenced(
false);
917 detail::decr_count(m_buffer);
922 m_free = next_size - m_used;
927template <
typename VisitorHolder,
typename ReferencedBufferHook>
928inline char* parser<VisitorHolder, ReferencedBufferHook>::buffer()
930 return m_buffer + m_used;
933template <
typename VisitorHolder,
typename ReferencedBufferHook>
934inline std::size_t parser<VisitorHolder, ReferencedBufferHook>::buffer_capacity()
const
939template <
typename VisitorHolder,
typename ReferencedBufferHook>
940inline void parser<VisitorHolder, ReferencedBufferHook>::buffer_consumed(std::size_t size)
946template <
typename VisitorHolder,
typename ReferencedBufferHook>
947 inline bool parser<VisitorHolder, ReferencedBufferHook>::next()
953template <
typename VisitorHolder,
typename ReferencedBufferHook>
954inline parse_return parser<VisitorHolder, ReferencedBufferHook>::execute_imp()
956 std::size_t off = m_off;
957 parse_return ret = context_type::execute(m_buffer, m_used, m_off);
959 m_parsed += m_off - off;
964template <
typename VisitorHolder,
typename ReferencedBufferHook>
965inline void parser<VisitorHolder, ReferencedBufferHook>::reset()
967 context_type::init();
972template <
typename VisitorHolder,
typename ReferencedBufferHook>
973inline std::size_t parser<VisitorHolder, ReferencedBufferHook>::message_size()
const
975 return m_parsed - m_off + m_used;
978template <
typename VisitorHolder,
typename ReferencedBufferHook>
979inline std::size_t parser<VisitorHolder, ReferencedBufferHook>::parsed_size()
const
984template <
typename VisitorHolder,
typename ReferencedBufferHook>
985inline char* parser<VisitorHolder, ReferencedBufferHook>::nonparsed_buffer()
987 return m_buffer + m_off;
990template <
typename VisitorHolder,
typename ReferencedBufferHook>
991inline std::size_t parser<VisitorHolder, ReferencedBufferHook>::nonparsed_size()
const
993 return m_used - m_off;
996template <
typename VisitorHolder,
typename ReferencedBufferHook>
997inline void parser<VisitorHolder, ReferencedBufferHook>::skip_nonparsed_buffer(std::size_t size)
1002template <
typename VisitorHolder,
typename ReferencedBufferHook>
1003inline void parser<VisitorHolder, ReferencedBufferHook>::remove_nonparsed_buffer()
1008template <
typename Visitor>
1009inline bool parse(
const char* data,
size_t len,
size_t& off, Visitor& v) {
1014template <
typename Visitor>
1015inline bool parse(
const char* data,
size_t len, Visitor& v) {
1016 std::size_t off = 0;
1022template <
typename Visitor>
1023struct parse_helper : detail::context<parse_helper<Visitor> > {
1024 parse_helper(Visitor& v):m_visitor(v) {}
1025 parse_return execute(
const char* data, std::size_t len, std::size_t& off) {
1026 return detail::context<parse_helper<Visitor> >::execute(data, len, off);
1028 Visitor& visitor()
const {
return m_visitor; }
1032template <
typename Visitor>
1034parse_imp(
const char* data,
size_t len,
size_t& off, Visitor& v) {
1035 std::size_t noff = off;
1039 v.insufficient_bytes(noff, noff);
1042 detail::parse_helper<Visitor> h(v);
1047 v.insufficient_bytes(noff - 1, noff);
#define MSGPACK_ASSERT
Definition assert.hpp:22
int execute(const char *data, std::size_t len, std::size_t &off)
Definition unpack.hpp:466
msgpack::object const & data() const
Definition unpack.hpp:334
context(unpack_reference_func f, void *user_data, unpack_limit const &limit)
Definition unpack.hpp:319
void init()
Definition unpack.hpp:326
parse_return parse_imp(const char *data, size_t len, size_t &off, Visitor &v)
std::size_t size(T const &t)
Definition size_equal_only.hpp:24
Definition adaptor_base.hpp:15
parse_return
Definition parse_return.hpp:23
@ PARSE_CONTINUE
Definition parse_return.hpp:26
@ PARSE_EXTRA_BYTES
Definition parse_return.hpp:25
@ PARSE_STOP_VISITOR
Definition parse_return.hpp:28
@ PARSE_SUCCESS
Definition parse_return.hpp:24
@ PARSE_PARSE_ERROR
Definition parse_return.hpp:27
bool parse(const char *data, size_t len, size_t &off, Visitor &v)
Unpack msgpack formatted data via a visitor.
T type
Definition unpack.hpp:285
Definition unpack_exception.hpp:97
msgpack_container_type
Definition unpack_define.hpp:68
@ 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_NULLPTR
Definition cpp_config_decl.hpp:85
#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