10#ifndef MSGPACK_V2_PARSE_HPP
11#define MSGPACK_V2_PARSE_HPP
13#if MSGPACK_DEFAULT_API_VERSION >= 2
33using v1::detail::fix_tag;
34using v1::detail::value;
35using v1::detail::load;
37template <
typename VisitorHolder>
50 holder().visitor().init();
57 static uint32_t next_cs(T p)
59 return static_cast<uint32_t
>(*p) & 0x1f;
62 VisitorHolder& holder() {
63 return static_cast<VisitorHolder&
>(*this);
66 template <
typename T,
typename StartVisitor,
typename EndVisitor>
68 StartVisitor
const& sv,
77 off =
static_cast<std::size_t
>(m_current - m_start);
81 off =
static_cast<std::size_t
>(m_current - m_start);
86 off =
static_cast<std::size_t
>(m_current - m_start);
92 off =
static_cast<std::size_t
>(m_current - m_start);
95 parse_return ret = m_stack.push(holder(), sv.type(),
static_cast<uint32_t
>(size));
97 off =
static_cast<std::size_t
>(m_current - m_start);
105 parse_return after_visit_proc(
bool visit_result, std::size_t& off) {
108 off =
static_cast<std::size_t
>(m_current - m_start);
113 off =
static_cast<std::size_t
>(m_current - m_start);
120 array_sv(VisitorHolder& visitor_holder):m_visitor_holder(visitor_holder) {}
121 bool operator()(uint32_t size)
const {
122 return m_visitor_holder.visitor().start_array(size);
126 VisitorHolder& m_visitor_holder;
129 array_ev(VisitorHolder& visitor_holder):m_visitor_holder(visitor_holder) {}
130 bool operator()()
const {
131 return m_visitor_holder.visitor().end_array();
134 VisitorHolder& m_visitor_holder;
137 map_sv(VisitorHolder& visitor_holder):m_visitor_holder(visitor_holder) {}
138 bool operator()(uint32_t size)
const {
139 return m_visitor_holder.visitor().start_map(size);
143 VisitorHolder& m_visitor_holder;
146 map_ev(VisitorHolder& visitor_holder):m_visitor_holder(visitor_holder) {}
147 bool operator()()
const {
148 return m_visitor_holder.visitor().end_map();
151 VisitorHolder& m_visitor_holder;
154 struct unpack_stack {
164 m_stack.push_back(stack_elem(type, rest));
178 while (!m_stack.empty()) {
179 stack_elem& e = m_stack.back();
183 if (--e.m_rest == 0) {
199 if (--e.m_rest == 0) {
213 bool empty()
const {
return m_stack.empty(); }
214 void clear() { m_stack.clear(); }
216 std::vector<stack_elem> m_stack;
220 char const* m_current;
224 uint32_t m_num_elements;
225 unpack_stack m_stack;
228template <std::
size_t N>
229inline void check_ext_size(std::size_t ) {
233inline void check_ext_size<4>(std::size_t size) {
234 if (size == 0xffffffff)
throw msgpack::ext_size_overflow(
"ext size overflow");
237template <
typename VisitorHolder>
243 m_current = data + off;
244 const char*
const pe = data + len;
247 if(m_current == pe) {
248 off =
static_cast<std::size_t
>(m_current - m_start);
251 bool fixed_trail_again =
false;
254 fixed_trail_again =
false;
255 int selector = *
reinterpret_cast<const unsigned char*
>(m_current);
256 if (0x00 <= selector && selector <= 0x7f) {
257 uint8_t tmp = *
reinterpret_cast<const uint8_t*
>(m_current);
258 bool visret = holder().visitor().visit_positive_integer(tmp);
261 }
else if(0xe0 <= selector && selector <= 0xff) {
262 int8_t tmp = *
reinterpret_cast<const int8_t*
>(m_current);
263 bool visret = holder().visitor().visit_negative_integer(tmp);
266 }
else if (0xc4 <= selector && selector <= 0xdf) {
267 const uint32_t trail[] = {
297 m_trail = trail[selector - 0xc4];
298 m_cs = next_cs(m_current);
299 fixed_trail_again =
true;
300 }
else if(0xa0 <= selector && selector <= 0xbf) {
301 m_trail =
static_cast<uint32_t
>(*m_current) & 0x1f;
303 bool visret = holder().visitor().visit_str(n,
static_cast<uint32_t
>(m_trail));
309 fixed_trail_again =
true;
311 }
else if(0x90 <= selector && selector <= 0x9f) {
312 parse_return ret = start_aggregate<fix_tag>(array_sv(holder()), array_ev(holder()), m_current, off);
314 }
else if(0x80 <= selector && selector <= 0x8f) {
315 parse_return ret = start_aggregate<fix_tag>(map_sv(holder()), map_ev(holder()), m_current, off);
317 }
else if(selector == 0xc2) {
318 bool visret = holder().visitor().visit_boolean(
false);
321 }
else if(selector == 0xc3) {
322 bool visret = holder().visitor().visit_boolean(
true);
325 }
else if(selector == 0xc0) {
326 bool visret = holder().visitor().visit_nil();
330 off =
static_cast<std::size_t
>(m_current - m_start);
331 holder().visitor().parse_error(off - 1, off);
337 if (fixed_trail_again) {
339 fixed_trail_again =
false;
341 if(
static_cast<std::size_t
>(pe - m_current) < m_trail) {
342 off =
static_cast<std::size_t
>(m_current - m_start);
346 m_current += m_trail - 1;
351 union { uint32_t i;
float f; } mem;
353 bool visret = holder().visitor().visit_float32(mem.f);
358 union { uint64_t i;
double f; } mem;
360#if defined(TARGET_OS_IPHONE)
362#elif defined(__arm__) && !(__ARM_EABI__)
364 mem.i = (mem.i & 0xFFFFFFFFUL) << 32UL | (mem.i >> 32UL);
366 bool visret = holder().visitor().visit_float64(mem.f);
373 bool visret = holder().visitor().visit_positive_integer(tmp);
380 bool visret = holder().visitor().visit_positive_integer(tmp);
387 bool visret = holder().visitor().visit_positive_integer(tmp);
394 bool visret = holder().visitor().visit_positive_integer(tmp);
401 bool visret = holder().visitor().visit_negative_integer(tmp);
408 bool visret = holder().visitor().visit_negative_integer(tmp);
415 bool visret = holder().visitor().visit_negative_integer(tmp);
422 bool visret = holder().visitor().visit_negative_integer(tmp);
427 bool visret = holder().visitor().visit_ext(n, 1+1);
432 bool visret = holder().visitor().visit_ext(n, 2+1);
437 bool visret = holder().visitor().visit_ext(n, 4+1);
442 bool visret = holder().visitor().visit_ext(n, 8+1);
447 bool visret = holder().visitor().visit_ext(n, 16+1);
456 bool visret = holder().visitor().visit_str(n,
static_cast<uint32_t
>(m_trail));
462 fixed_trail_again =
true;
470 bool visret = holder().visitor().visit_bin(n,
static_cast<uint32_t
>(m_trail));
476 fixed_trail_again =
true;
484 bool visret = holder().visitor().visit_ext(n, m_trail);
490 fixed_trail_again =
true;
498 bool visret = holder().visitor().visit_str(n,
static_cast<uint32_t
>(m_trail));
504 fixed_trail_again =
true;
512 bool visret = holder().visitor().visit_bin(n,
static_cast<uint32_t
>(m_trail));
518 fixed_trail_again =
true;
526 bool visret = holder().visitor().visit_ext(n, m_trail);
532 fixed_trail_again =
true;
540 bool visret = holder().visitor().visit_str(n,
static_cast<uint32_t
>(m_trail));
546 fixed_trail_again =
true;
554 bool visret = holder().visitor().visit_bin(n,
static_cast<uint32_t
>(m_trail));
560 fixed_trail_again =
true;
566 check_ext_size<sizeof(std::size_t)>(tmp);
570 bool visret = holder().visitor().visit_ext(n, m_trail);
576 fixed_trail_again =
true;
580 bool visret = holder().visitor().visit_str(n,
static_cast<uint32_t
>(m_trail));
585 bool visret = holder().visitor().visit_bin(n,
static_cast<uint32_t
>(m_trail));
590 bool visret = holder().visitor().visit_ext(n, m_trail);
595 parse_return ret = start_aggregate<uint16_t>(array_sv(holder()), array_ev(holder()), n, off);
600 parse_return ret = start_aggregate<uint32_t>(array_sv(holder()), array_ev(holder()), n, off);
604 parse_return ret = start_aggregate<uint16_t>(map_sv(holder()), map_ev(holder()), n, off);
608 parse_return ret = start_aggregate<uint32_t>(map_sv(holder()), map_ev(holder()), n, off);
612 off =
static_cast<std::size_t
>(m_current - m_start);
613 holder().visitor().parse_error(
static_cast<std::size_t
>(n - m_start - 1),
static_cast<std::size_t
>(n - m_start));
617 }
while(m_current != pe);
619 off =
static_cast<std::size_t
>(m_current - m_start);
628template <
typename VisitorHolder,
typename ReferencedBufferHook>
630 typedef parser<VisitorHolder, ReferencedBufferHook> this_type;
631 typedef detail::context<VisitorHolder> context_type;
642 parser(ReferencedBufferHook& hook,
645#if !defined(MSGPACK_USE_CPP03)
646 parser(this_type&& other);
647 this_type& operator=(this_type&& other);
678 std::size_t buffer_capacity()
const;
690 void buffer_consumed(std::size_t size);
709 std::size_t message_size()
const;
719 std::size_t parsed_size()
const;
728 char* nonparsed_buffer();
737 std::size_t nonparsed_size()
const;
747 void skip_nonparsed_buffer(std::size_t size);
754 void remove_nonparsed_buffer();
759 char* get_raw_buffer() {
763 void expand_buffer(std::size_t size);
770 void set_referenced_buffer_hook(ReferencedBufferHook& hook) {
771 m_referenced_buffer_hook = &hook;
779 std::size_t m_parsed;
780 std::size_t m_initial_buffer_size;
781 ReferencedBufferHook* m_referenced_buffer_hook;
783#if defined(MSGPACK_USE_CPP03)
785 parser(
const this_type&);
786 this_type& operator=(
const this_type&);
789 parser(
const this_type&) =
delete;
790 this_type& operator=(
const this_type&) =
delete;
794template <
typename VisitorHolder,
typename ReferencedBufferHook>
796 ReferencedBufferHook& hook,
797 std::size_t initial_buffer_size)
798 :m_referenced_buffer_hook(&hook)
804 char* buffer =
static_cast<char*
>(::malloc(initial_buffer_size));
806 throw std::bad_alloc();
811 m_free = initial_buffer_size - m_used;
814 m_initial_buffer_size = initial_buffer_size;
816 detail::init_count(m_buffer);
819#if !defined(MSGPACK_USE_CPP03)
822template <
typename VisitorHolder,
typename ReferencedBufferHook>
823inline parser<VisitorHolder, ReferencedBufferHook>::parser(this_type&& other)
824 :context_type(std::move(other)),
825 m_buffer(other.m_buffer),
826 m_used(other.m_used),
827 m_free(other.m_free),
829 m_parsed(other.m_parsed),
830 m_initial_buffer_size(other.m_initial_buffer_size),
831 m_referenced_buffer_hook(other.m_referenced_buffer_hook) {
839template <
typename VisitorHolder,
typename ReferencedBufferHook>
840inline parser<VisitorHolder, ReferencedBufferHook>& parser<VisitorHolder, ReferencedBufferHook>::operator=(this_type&& other) {
841 if (
this != &other) {
843 new (
this) this_type(std::move(other));
851template <
typename VisitorHolder,
typename ReferencedBufferHook>
852inline parser<VisitorHolder, ReferencedBufferHook>::~parser()
855 if (m_buffer) detail::decr_count(m_buffer);
859template <
typename VisitorHolder,
typename ReferencedBufferHook>
860inline void parser<VisitorHolder, ReferencedBufferHook>::reserve_buffer(std::size_t size)
862 if(m_free >= size)
return;
866template <
typename VisitorHolder,
typename ReferencedBufferHook>
867inline void parser<VisitorHolder, ReferencedBufferHook>::expand_buffer(std::size_t size)
869 if(m_used == m_off && detail::get_count(m_buffer) == 1
870 && !
static_cast<VisitorHolder&
>(*this).visitor().referenced()) {
876 if(m_free >= size)
return;
880 if(size > std::numeric_limits<std::size_t>::max() - m_used) {
881 throw std::bad_alloc();
883 std::size_t next_size = (m_used + m_free) * 2;
884 while(next_size < size + m_used) {
885 std::size_t tmp_next_size = next_size * 2;
886 if (tmp_next_size <= next_size) {
887 next_size =
size + m_used;
890 next_size = tmp_next_size;
893 char* tmp =
static_cast<char*
>(::realloc(m_buffer, next_size));
895 throw std::bad_alloc();
899 m_free = next_size - m_used;
902 std::size_t next_size = m_initial_buffer_size;
903 std::size_t not_parsed = m_used - m_off;
904 if(size > std::numeric_limits<std::size_t>::max() - not_parsed -
COUNTER_SIZE) {
905 throw std::bad_alloc();
908 std::size_t tmp_next_size = next_size * 2;
909 if (tmp_next_size <= next_size) {
913 next_size = tmp_next_size;
916 char* tmp =
static_cast<char*
>(::malloc(next_size));
918 throw std::bad_alloc();
921 detail::init_count(tmp);
923 std::memcpy(tmp+
COUNTER_SIZE, m_buffer + m_off, not_parsed);
925 if(
static_cast<VisitorHolder&
>(*this).referenced()) {
927 (*m_referenced_buffer_hook)(m_buffer);
933 static_cast<VisitorHolder&
>(*this).set_referenced(
false);
935 detail::decr_count(m_buffer);
940 m_free = next_size - m_used;
945template <
typename VisitorHolder,
typename ReferencedBufferHook>
946inline char* parser<VisitorHolder, ReferencedBufferHook>::buffer()
948 return m_buffer + m_used;
951template <
typename VisitorHolder,
typename ReferencedBufferHook>
952inline std::size_t parser<VisitorHolder, ReferencedBufferHook>::buffer_capacity()
const
957template <
typename VisitorHolder,
typename ReferencedBufferHook>
958inline void parser<VisitorHolder, ReferencedBufferHook>::buffer_consumed(std::size_t size)
964template <
typename VisitorHolder,
typename ReferencedBufferHook>
965 inline bool parser<VisitorHolder, ReferencedBufferHook>::next()
971template <
typename VisitorHolder,
typename ReferencedBufferHook>
972inline parse_return parser<VisitorHolder, ReferencedBufferHook>::execute_imp()
974 std::size_t off = m_off;
975 parse_return ret = context_type::execute(m_buffer, m_used, m_off);
977 m_parsed += m_off - off;
982template <
typename VisitorHolder,
typename ReferencedBufferHook>
983inline void parser<VisitorHolder, ReferencedBufferHook>::reset()
985 context_type::init();
990template <
typename VisitorHolder,
typename ReferencedBufferHook>
991inline std::size_t parser<VisitorHolder, ReferencedBufferHook>::message_size()
const
993 return m_parsed - m_off + m_used;
996template <
typename VisitorHolder,
typename ReferencedBufferHook>
997inline std::size_t parser<VisitorHolder, ReferencedBufferHook>::parsed_size()
const
1002template <
typename VisitorHolder,
typename ReferencedBufferHook>
1003inline char* parser<VisitorHolder, ReferencedBufferHook>::nonparsed_buffer()
1005 return m_buffer + m_off;
1008template <
typename VisitorHolder,
typename ReferencedBufferHook>
1009inline std::size_t parser<VisitorHolder, ReferencedBufferHook>::nonparsed_size()
const
1011 return m_used - m_off;
1014template <
typename VisitorHolder,
typename ReferencedBufferHook>
1015inline void parser<VisitorHolder, ReferencedBufferHook>::skip_nonparsed_buffer(std::size_t size)
1020template <
typename VisitorHolder,
typename ReferencedBufferHook>
1021inline void parser<VisitorHolder, ReferencedBufferHook>::remove_nonparsed_buffer()
1026template <
typename Visitor>
1027inline bool parse(
const char* data,
size_t len,
size_t& off, Visitor& v) {
1032template <
typename Visitor>
1033inline bool parse(
const char* data,
size_t len, Visitor& v) {
1034 std::size_t off = 0;
1040template <
typename Visitor>
1041struct parse_helper : detail::context<parse_helper<Visitor> > {
1042 parse_helper(Visitor& v):m_visitor(v) {}
1043 parse_return execute(
const char* data, std::size_t len, std::size_t& off) {
1044 return detail::context<parse_helper<Visitor> >::execute(data, len, off);
1046 Visitor& visitor()
const {
return m_visitor; }
1050template <
typename Visitor>
1052parse_imp(
const char* data,
size_t len,
size_t& off, Visitor& v) {
1053 std::size_t noff = off;
1057 v.insufficient_bytes(noff, noff);
1060 detail::parse_helper<Visitor> h(v);
1065 v.insufficient_bytes(noff - 1, noff);
#define MSGPACK_ASSERT
Definition assert.hpp:22
Definition unpack.hpp:318
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
void init()
Definition unpack.hpp:327
Parsing class for a stream deserialization.
Definition parse_decl.hpp:32
Definition check_container_size.hpp:31
parse_return parse_imp(const char *data, size_t len, size_t &off, Visitor &v)
msgpack::enable_if< sizeof(T)==sizeof(fix_tag)>::type load(uint32_t &dst, const char *n)
Definition unpack.hpp:294
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:286
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