MessagePack for C++
parse.hpp
Go to the documentation of this file.
1 //
2 // MessagePack for C++ deserializing routine
3 //
4 // Copyright (C) 2018 KONDO Takatoshi
5 //
6 // Distributed under the Boost Software License, Version 1.0.
7 // (See accompanying file LICENSE_1_0.txt or copy at
8 // http://www.boost.org/LICENSE_1_0.txt)
9 //
10 #ifndef MSGPACK_V3_PARSE_HPP
11 #define MSGPACK_V3_PARSE_HPP
12 
13 #if MSGPACK_DEFAULT_API_VERSION >= 2
14 
15 #include <cstddef>
16 
17 #include "msgpack/parse_return.hpp"
18 #include "msgpack/assert.hpp"
19 
20 namespace msgpack {
21 
25 
26 namespace detail {
27 
28 template <typename VisitorHolder>
29 class context {
30 public:
31  context()
32  :m_trail(0), m_cs(MSGPACK_CS_HEADER)
33  {
34  }
35 
36  void init()
37  {
38  m_cs = MSGPACK_CS_HEADER;
39  m_trail = 0;
40  m_stack.clear();
41  holder().visitor().init();
42  }
43 
44  parse_return execute(const char* data, std::size_t len, std::size_t& off);
45 
46 private:
47  template <typename T>
48  static uint32_t next_cs(T p)
49  {
50  return static_cast<uint32_t>(*p) & 0x1f;
51  }
52 
53  VisitorHolder& holder() {
54  return static_cast<VisitorHolder&>(*this);
55  }
56 
57  template <typename T, typename StartVisitor, typename EndVisitor>
58  parse_return start_aggregate(
59  StartVisitor const& sv,
60  EndVisitor const& ev,
61  const char* load_pos,
62  std::size_t& off) {
63  typename value<T>::type size;
64  load<T>(size, load_pos);
65  if (size == 0) {
66  if (!sv(size)) {
67  off = static_cast<std::size_t>(m_current - m_start);
68  return PARSE_STOP_VISITOR;
69  }
70  if (!ev()) {
71  off = static_cast<std::size_t>(m_current - m_start);
72  return PARSE_STOP_VISITOR;
73  }
74  parse_return ret = m_stack.consume(holder(), m_current);
75  ++m_current;
76  if (ret != PARSE_CONTINUE) {
77  off = static_cast<std::size_t>(m_current - m_start);
78  return ret;
79  }
80  }
81  else {
82  if (!sv(size)) {
83  off = static_cast<std::size_t>(m_current - m_start);
84  return PARSE_STOP_VISITOR;
85  }
86  parse_return ret = m_stack.push(holder(), sv.type(), static_cast<uint32_t>(size));
87  ++m_current;
88  if (ret != PARSE_CONTINUE) {
89  off = static_cast<std::size_t>(m_current - m_start);
90  return ret;
91  }
92  }
93  m_cs = MSGPACK_CS_HEADER;
94  return PARSE_CONTINUE;
95  }
96 
97  parse_return after_visit_proc(bool visit_result, std::size_t& off) {
98  if (!visit_result) {
99  off = static_cast<std::size_t>(m_current - m_start);
100  return PARSE_STOP_VISITOR;
101  }
102  parse_return ret = m_stack.consume(holder(), m_current);
103  ++m_current;
104  if (ret != PARSE_CONTINUE) {
105  off = static_cast<std::size_t>(m_current - m_start);
106  }
107  m_cs = MSGPACK_CS_HEADER;
108  return ret;
109  }
110 
111  struct array_sv {
112  array_sv(VisitorHolder& visitor_holder):m_visitor_holder(visitor_holder) {}
113  bool operator()(uint32_t size) const {
114  return m_visitor_holder.visitor().start_array(size);
115  }
116  msgpack_container_type type() const { return MSGPACK_CT_ARRAY_ITEM; }
117  private:
118  VisitorHolder& m_visitor_holder;
119  };
120  struct array_ev {
121  array_ev(VisitorHolder& visitor_holder):m_visitor_holder(visitor_holder) {}
122  bool operator()() const {
123  return m_visitor_holder.visitor().end_array();
124  }
125  private:
126  VisitorHolder& m_visitor_holder;
127  };
128  struct map_sv {
129  map_sv(VisitorHolder& visitor_holder):m_visitor_holder(visitor_holder) {}
130  bool operator()(uint32_t size) const {
131  return m_visitor_holder.visitor().start_map(size);
132  }
133  msgpack_container_type type() const { return MSGPACK_CT_MAP_KEY; }
134  private:
135  VisitorHolder& m_visitor_holder;
136  };
137  struct map_ev {
138  map_ev(VisitorHolder& visitor_holder):m_visitor_holder(visitor_holder) {}
139  bool operator()() const {
140  return m_visitor_holder.visitor().end_map();
141  }
142  private:
143  VisitorHolder& m_visitor_holder;
144  };
145 
146  struct unpack_stack {
147  struct stack_elem {
148  stack_elem(msgpack_container_type type, uint32_t rest):m_type(type), m_rest(rest) {}
149  msgpack_container_type m_type;
150  uint32_t m_rest;
151  };
152  unpack_stack() {
153  m_stack.reserve(MSGPACK_EMBED_STACK_SIZE);
154  }
155  parse_return push(VisitorHolder& visitor_holder, msgpack_container_type type, uint32_t rest) {
156  m_stack.push_back(stack_elem(type, rest));
157  switch (type) {
159  return visitor_holder.visitor().start_array_item() ? PARSE_CONTINUE : PARSE_STOP_VISITOR;
160  case MSGPACK_CT_MAP_KEY:
161  return visitor_holder.visitor().start_map_key() ? PARSE_CONTINUE : PARSE_STOP_VISITOR;
163  MSGPACK_ASSERT(0);
164  return PARSE_STOP_VISITOR;
165  }
166  MSGPACK_ASSERT(0);
167  return PARSE_STOP_VISITOR;
168  }
169  parse_return consume(VisitorHolder& visitor_holder, char const*& current) {
170  while (!m_stack.empty()) {
171  stack_elem& e = m_stack.back();
172  switch (e.m_type) {
174  if (!visitor_holder.visitor().end_array_item()) {
175  --current;
176  return PARSE_STOP_VISITOR;
177  }
178  if (--e.m_rest == 0) {
179  m_stack.pop_back();
180  if (!visitor_holder.visitor().end_array()) {
181  --current;
182  return PARSE_STOP_VISITOR;
183  }
184  }
185  else {
186  if (!visitor_holder.visitor().start_array_item()) return PARSE_STOP_VISITOR;
187  return PARSE_CONTINUE;
188  }
189  break;
190  case MSGPACK_CT_MAP_KEY:
191  if (!visitor_holder.visitor().end_map_key()) {
192  --current;
193  return PARSE_STOP_VISITOR;
194  }
195  if (!visitor_holder.visitor().start_map_value()) return PARSE_STOP_VISITOR;
196  e.m_type = MSGPACK_CT_MAP_VALUE;
197  return PARSE_CONTINUE;
199  if (!visitor_holder.visitor().end_map_value()) {
200  --current;
201  return PARSE_STOP_VISITOR;
202  }
203  if (--e.m_rest == 0) {
204  m_stack.pop_back();
205  if (!visitor_holder.visitor().end_map()) {
206  --current;
207  return PARSE_STOP_VISITOR;
208  }
209  }
210  else {
211  e.m_type = MSGPACK_CT_MAP_KEY;
212  if (!visitor_holder.visitor().start_map_key()) return PARSE_STOP_VISITOR;
213  return PARSE_CONTINUE;
214  }
215  break;
216  }
217  }
218  return PARSE_SUCCESS;
219  }
220  bool empty() const { return m_stack.empty(); }
221  void clear() { m_stack.clear(); }
222  private:
223  std::vector<stack_elem> m_stack;
224  };
225 
226  char const* m_start;
227  char const* m_current;
228 
229  std::size_t m_trail;
230  uint32_t m_cs;
231  uint32_t m_num_elements;
232  unpack_stack m_stack;
233 };
234 
235 template <std::size_t N>
236 inline void check_ext_size(std::size_t /*size*/) {
237 }
238 
239 template <>
240 inline void check_ext_size<4>(std::size_t size) {
241  if (size == 0xffffffff) throw msgpack::ext_size_overflow("ext size overflow");
242 }
243 
244 template <typename VisitorHolder>
245 inline parse_return context<VisitorHolder>::execute(const char* data, std::size_t len, std::size_t& off)
246 {
247  MSGPACK_ASSERT(len >= off);
248 
249  m_start = data;
250  m_current = data + off;
251  const char* const pe = data + len;
252  const char* n = MSGPACK_NULLPTR;
253 
254  if(m_current == pe) {
255  off = static_cast<std::size_t>(m_current - m_start);
256  return PARSE_CONTINUE;
257  }
258  bool fixed_trail_again = false;
259  do {
260  if (m_cs == MSGPACK_CS_HEADER) {
261  fixed_trail_again = false;
262  int selector = *reinterpret_cast<const unsigned char*>(m_current);
263  if (0x00 <= selector && selector <= 0x7f) { // Positive Fixnum
264  uint8_t tmp = *reinterpret_cast<const uint8_t*>(m_current);
265  bool visret = holder().visitor().visit_positive_integer(tmp);
266  parse_return upr = after_visit_proc(visret, off);
267  if (upr != PARSE_CONTINUE) return upr;
268  } else if(0xe0 <= selector && selector <= 0xff) { // Negative Fixnum
269  int8_t tmp = *reinterpret_cast<const int8_t*>(m_current);
270  bool visret = holder().visitor().visit_negative_integer(tmp);
271  parse_return upr = after_visit_proc(visret, off);
272  if (upr != PARSE_CONTINUE) return upr;
273  } else if (0xc4 <= selector && selector <= 0xdf) {
274  const uint32_t trail[] = {
275  1, // bin 8 0xc4
276  2, // bin 16 0xc5
277  4, // bin 32 0xc6
278  1, // ext 8 0xc7
279  2, // ext 16 0xc8
280  4, // ext 32 0xc9
281  4, // float 32 0xca
282  8, // float 64 0xcb
283  1, // uint 8 0xcc
284  2, // uint 16 0xcd
285  4, // uint 32 0xce
286  8, // uint 64 0xcf
287  1, // int 8 0xd0
288  2, // int 16 0xd1
289  4, // int 32 0xd2
290  8, // int 64 0xd3
291  2, // fixext 1 0xd4
292  3, // fixext 2 0xd5
293  5, // fixext 4 0xd6
294  9, // fixext 8 0xd7
295  17,// fixext 16 0xd8
296  1, // str 8 0xd9
297  2, // str 16 0xda
298  4, // str 32 0xdb
299  2, // array 16 0xdc
300  4, // array 32 0xdd
301  2, // map 16 0xde
302  4, // map 32 0xdf
303  };
304  m_trail = trail[selector - 0xc4];
305  m_cs = next_cs(m_current);
306  fixed_trail_again = true;
307  } else if(0xa0 <= selector && selector <= 0xbf) { // FixStr
308  m_trail = static_cast<uint32_t>(*m_current) & 0x1f;
309  if(m_trail == 0) {
310  bool visret = holder().visitor().visit_str(n, static_cast<uint32_t>(m_trail));
311  parse_return upr = after_visit_proc(visret, off);
312  if (upr != PARSE_CONTINUE) return upr;
313  }
314  else {
315  m_cs = MSGPACK_ACS_STR_VALUE;
316  fixed_trail_again = true;
317  }
318  } else if(0x90 <= selector && selector <= 0x9f) { // FixArray
319  parse_return ret = start_aggregate<fix_tag>(array_sv(holder()), array_ev(holder()), m_current, off);
320  if (ret != PARSE_CONTINUE) return ret;
321  } else if(0x80 <= selector && selector <= 0x8f) { // FixMap
322  parse_return ret = start_aggregate<fix_tag>(map_sv(holder()), map_ev(holder()), m_current, off);
323  if (ret != PARSE_CONTINUE) return ret;
324  } else if(selector == 0xc2) { // false
325  bool visret = holder().visitor().visit_boolean(false);
326  parse_return upr = after_visit_proc(visret, off);
327  if (upr != PARSE_CONTINUE) return upr;
328  } else if(selector == 0xc3) { // true
329  bool visret = holder().visitor().visit_boolean(true);
330  parse_return upr = after_visit_proc(visret, off);
331  if (upr != PARSE_CONTINUE) return upr;
332  } else if(selector == 0xc0) { // nil
333  bool visret = holder().visitor().visit_nil();
334  parse_return upr = after_visit_proc(visret, off);
335  if (upr != PARSE_CONTINUE) return upr;
336  } else {
337  off = static_cast<std::size_t>(m_current - m_start);
338  holder().visitor().parse_error(off - 1, off);
339  return PARSE_PARSE_ERROR;
340  }
341  // end MSGPACK_CS_HEADER
342  }
343  if (m_cs != MSGPACK_CS_HEADER || fixed_trail_again) {
344  if (fixed_trail_again) {
345  ++m_current;
346  fixed_trail_again = false;
347  }
348  if(static_cast<std::size_t>(pe - m_current) < m_trail) {
349  off = static_cast<std::size_t>(m_current - m_start);
350  return PARSE_CONTINUE;
351  }
352  n = m_current;
353  m_current += m_trail - 1;
354  switch(m_cs) {
355  //case MSGPACK_CS_
356  //case MSGPACK_CS_
357  case MSGPACK_CS_FLOAT: {
358  union { uint32_t i; float f; } mem;
359  load<uint32_t>(mem.i, n);
360  bool visret = holder().visitor().visit_float32(mem.f);
361  parse_return upr = after_visit_proc(visret, off);
362  if (upr != PARSE_CONTINUE) return upr;
363  } break;
364  case MSGPACK_CS_DOUBLE: {
365  union { uint64_t i; double f; } mem;
366  load<uint64_t>(mem.i, n);
367 #if defined(TARGET_OS_IPHONE)
368  // ok
369 #elif defined(__arm__) && !(__ARM_EABI__) // arm-oabi
370  // https://github.com/msgpack/msgpack-perl/pull/1
371  mem.i = (mem.i & 0xFFFFFFFFUL) << 32UL | (mem.i >> 32UL);
372 #endif
373  bool visret = holder().visitor().visit_float64(mem.f);
374  parse_return upr = after_visit_proc(visret, off);
375  if (upr != PARSE_CONTINUE) return upr;
376  } break;
377  case MSGPACK_CS_UINT_8: {
378  uint8_t tmp;
379  load<uint8_t>(tmp, n);
380  bool visret = holder().visitor().visit_positive_integer(tmp);
381  parse_return upr = after_visit_proc(visret, off);
382  if (upr != PARSE_CONTINUE) return upr;
383  } break;
384  case MSGPACK_CS_UINT_16: {
385  uint16_t tmp;
386  load<uint16_t>(tmp, n);
387  bool visret = holder().visitor().visit_positive_integer(tmp);
388  parse_return upr = after_visit_proc(visret, off);
389  if (upr != PARSE_CONTINUE) return upr;
390  } break;
391  case MSGPACK_CS_UINT_32: {
392  uint32_t tmp;
393  load<uint32_t>(tmp, n);
394  bool visret = holder().visitor().visit_positive_integer(tmp);
395  parse_return upr = after_visit_proc(visret, off);
396  if (upr != PARSE_CONTINUE) return upr;
397  } break;
398  case MSGPACK_CS_UINT_64: {
399  uint64_t tmp;
400  load<uint64_t>(tmp, n);
401  bool visret = holder().visitor().visit_positive_integer(tmp);
402  parse_return upr = after_visit_proc(visret, off);
403  if (upr != PARSE_CONTINUE) return upr;
404  } break;
405  case MSGPACK_CS_INT_8: {
406  int8_t tmp;
407  load<int8_t>(tmp, n);
408  bool visret = holder().visitor().visit_negative_integer(tmp);
409  parse_return upr = after_visit_proc(visret, off);
410  if (upr != PARSE_CONTINUE) return upr;
411  } break;
412  case MSGPACK_CS_INT_16: {
413  int16_t tmp;
414  load<int16_t>(tmp, n);
415  bool visret = holder().visitor().visit_negative_integer(tmp);
416  parse_return upr = after_visit_proc(visret, off);
417  if (upr != PARSE_CONTINUE) return upr;
418  } break;
419  case MSGPACK_CS_INT_32: {
420  int32_t tmp;
421  load<int32_t>(tmp, n);
422  bool visret = holder().visitor().visit_negative_integer(tmp);
423  parse_return upr = after_visit_proc(visret, off);
424  if (upr != PARSE_CONTINUE) return upr;
425  } break;
426  case MSGPACK_CS_INT_64: {
427  int64_t tmp;
428  load<int64_t>(tmp, n);
429  bool visret = holder().visitor().visit_negative_integer(tmp);
430  parse_return upr = after_visit_proc(visret, off);
431  if (upr != PARSE_CONTINUE) return upr;
432  } break;
433  case MSGPACK_CS_FIXEXT_1: {
434  bool visret = holder().visitor().visit_ext(n, 1+1);
435  parse_return upr = after_visit_proc(visret, off);
436  if (upr != PARSE_CONTINUE) return upr;
437  } break;
438  case MSGPACK_CS_FIXEXT_2: {
439  bool visret = holder().visitor().visit_ext(n, 2+1);
440  parse_return upr = after_visit_proc(visret, off);
441  if (upr != PARSE_CONTINUE) return upr;
442  } break;
443  case MSGPACK_CS_FIXEXT_4: {
444  bool visret = holder().visitor().visit_ext(n, 4+1);
445  parse_return upr = after_visit_proc(visret, off);
446  if (upr != PARSE_CONTINUE) return upr;
447  } break;
448  case MSGPACK_CS_FIXEXT_8: {
449  bool visret = holder().visitor().visit_ext(n, 8+1);
450  parse_return upr = after_visit_proc(visret, off);
451  if (upr != PARSE_CONTINUE) return upr;
452  } break;
453  case MSGPACK_CS_FIXEXT_16: {
454  bool visret = holder().visitor().visit_ext(n, 16+1);
455  parse_return upr = after_visit_proc(visret, off);
456  if (upr != PARSE_CONTINUE) return upr;
457  } break;
458  case MSGPACK_CS_STR_8: {
459  uint8_t tmp;
460  load<uint8_t>(tmp, n);
461  m_trail = tmp;
462  if(m_trail == 0) {
463  bool visret = holder().visitor().visit_str(n, static_cast<uint32_t>(m_trail));
464  parse_return upr = after_visit_proc(visret, off);
465  if (upr != PARSE_CONTINUE) return upr;
466  }
467  else {
468  m_cs = MSGPACK_ACS_STR_VALUE;
469  fixed_trail_again = true;
470  }
471  } break;
472  case MSGPACK_CS_BIN_8: {
473  uint8_t tmp;
474  load<uint8_t>(tmp, n);
475  m_trail = tmp;
476  if(m_trail == 0) {
477  bool visret = holder().visitor().visit_bin(n, static_cast<uint32_t>(m_trail));
478  parse_return upr = after_visit_proc(visret, off);
479  if (upr != PARSE_CONTINUE) return upr;
480  }
481  else {
482  m_cs = MSGPACK_ACS_BIN_VALUE;
483  fixed_trail_again = true;
484  }
485  } break;
486  case MSGPACK_CS_EXT_8: {
487  uint8_t tmp;
488  load<uint8_t>(tmp, n);
489  m_trail = tmp + 1;
490  if(m_trail == 0) {
491  bool visret = holder().visitor().visit_ext(n, static_cast<uint32_t>(m_trail));
492  parse_return upr = after_visit_proc(visret, off);
493  if (upr != PARSE_CONTINUE) return upr;
494  }
495  else {
496  m_cs = MSGPACK_ACS_EXT_VALUE;
497  fixed_trail_again = true;
498  }
499  } break;
500  case MSGPACK_CS_STR_16: {
501  uint16_t tmp;
502  load<uint16_t>(tmp, n);
503  m_trail = tmp;
504  if(m_trail == 0) {
505  bool visret = holder().visitor().visit_str(n, static_cast<uint32_t>(m_trail));
506  parse_return upr = after_visit_proc(visret, off);
507  if (upr != PARSE_CONTINUE) return upr;
508  }
509  else {
510  m_cs = MSGPACK_ACS_STR_VALUE;
511  fixed_trail_again = true;
512  }
513  } break;
514  case MSGPACK_CS_BIN_16: {
515  uint16_t tmp;
516  load<uint16_t>(tmp, n);
517  m_trail = tmp;
518  if(m_trail == 0) {
519  bool visret = holder().visitor().visit_bin(n, static_cast<uint32_t>(m_trail));
520  parse_return upr = after_visit_proc(visret, off);
521  if (upr != PARSE_CONTINUE) return upr;
522  }
523  else {
524  m_cs = MSGPACK_ACS_BIN_VALUE;
525  fixed_trail_again = true;
526  }
527  } break;
528  case MSGPACK_CS_EXT_16: {
529  uint16_t tmp;
530  load<uint16_t>(tmp, n);
531  m_trail = tmp + 1;
532  if(m_trail == 0) {
533  bool visret = holder().visitor().visit_ext(n, static_cast<uint32_t>(m_trail));
534  parse_return upr = after_visit_proc(visret, off);
535  if (upr != PARSE_CONTINUE) return upr;
536  }
537  else {
538  m_cs = MSGPACK_ACS_EXT_VALUE;
539  fixed_trail_again = true;
540  }
541  } break;
542  case MSGPACK_CS_STR_32: {
543  uint32_t tmp;
544  load<uint32_t>(tmp, n);
545  m_trail = tmp;
546  if(m_trail == 0) {
547  bool visret = holder().visitor().visit_str(n, static_cast<uint32_t>(m_trail));
548  parse_return upr = after_visit_proc(visret, off);
549  if (upr != PARSE_CONTINUE) return upr;
550  }
551  else {
552  m_cs = MSGPACK_ACS_STR_VALUE;
553  fixed_trail_again = true;
554  }
555  } break;
556  case MSGPACK_CS_BIN_32: {
557  uint32_t tmp;
558  load<uint32_t>(tmp, n);
559  m_trail = tmp;
560  if(m_trail == 0) {
561  bool visret = holder().visitor().visit_bin(n, static_cast<uint32_t>(m_trail));
562  parse_return upr = after_visit_proc(visret, off);
563  if (upr != PARSE_CONTINUE) return upr;
564  }
565  else {
566  m_cs = MSGPACK_ACS_BIN_VALUE;
567  fixed_trail_again = true;
568  }
569  } break;
570  case MSGPACK_CS_EXT_32: {
571  uint32_t tmp;
572  load<uint32_t>(tmp, n);
573  check_ext_size<sizeof(std::size_t)>(tmp);
574  m_trail = tmp;
575  ++m_trail;
576  if(m_trail == 0) {
577  bool visret = holder().visitor().visit_ext(n, static_cast<uint32_t>(m_trail));
578  parse_return upr = after_visit_proc(visret, off);
579  if (upr != PARSE_CONTINUE) return upr;
580  }
581  else {
582  m_cs = MSGPACK_ACS_EXT_VALUE;
583  fixed_trail_again = true;
584  }
585  } break;
586  case MSGPACK_ACS_STR_VALUE: {
587  bool visret = holder().visitor().visit_str(n, static_cast<uint32_t>(m_trail));
588  parse_return upr = after_visit_proc(visret, off);
589  if (upr != PARSE_CONTINUE) return upr;
590  } break;
591  case MSGPACK_ACS_BIN_VALUE: {
592  bool visret = holder().visitor().visit_bin(n, static_cast<uint32_t>(m_trail));
593  parse_return upr = after_visit_proc(visret, off);
594  if (upr != PARSE_CONTINUE) return upr;
595  } break;
596  case MSGPACK_ACS_EXT_VALUE: {
597  bool visret = holder().visitor().visit_ext(n, static_cast<uint32_t>(m_trail));
598  parse_return upr = after_visit_proc(visret, off);
599  if (upr != PARSE_CONTINUE) return upr;
600  } break;
601  case MSGPACK_CS_ARRAY_16: {
602  parse_return ret = start_aggregate<uint16_t>(array_sv(holder()), array_ev(holder()), n, off);
603  if (ret != PARSE_CONTINUE) return ret;
604 
605  } break;
606  case MSGPACK_CS_ARRAY_32: {
607  parse_return ret = start_aggregate<uint32_t>(array_sv(holder()), array_ev(holder()), n, off);
608  if (ret != PARSE_CONTINUE) return ret;
609  } break;
610  case MSGPACK_CS_MAP_16: {
611  parse_return ret = start_aggregate<uint16_t>(map_sv(holder()), map_ev(holder()), n, off);
612  if (ret != PARSE_CONTINUE) return ret;
613  } break;
614  case MSGPACK_CS_MAP_32: {
615  parse_return ret = start_aggregate<uint32_t>(map_sv(holder()), map_ev(holder()), n, off);
616  if (ret != PARSE_CONTINUE) return ret;
617  } break;
618  default:
619  off = static_cast<std::size_t>(m_current - m_start);
620  holder().visitor().parse_error(static_cast<std::size_t>(n - m_start - 1), static_cast<std::size_t>(n - m_start));
621  return PARSE_PARSE_ERROR;
622  }
623  }
624  } while(m_current != pe);
625 
626  off = static_cast<std::size_t>(m_current - m_start);
627  return PARSE_CONTINUE;
628 }
629 
630 template <typename Visitor>
631 struct parse_helper : detail::context<parse_helper<Visitor> > {
632  parse_helper(Visitor& v):m_visitor(v) {}
633  parse_return execute(const char* data, std::size_t len, std::size_t& off) {
634  return detail::context<parse_helper<Visitor> >::execute(data, len, off);
635  }
636  Visitor& visitor() const { return m_visitor; }
637  Visitor& m_visitor;
638 };
639 
640 template <typename Visitor>
641 inline parse_return
642 parse_imp(const char* data, size_t len, size_t& off, Visitor& v) {
643  std::size_t noff = off;
644  if(len <= noff) {
645  // FIXME
646  v.insufficient_bytes(noff, noff);
647  return PARSE_CONTINUE;
648  }
649  detail::parse_helper<Visitor> h(v);
650  parse_return ret = h.execute(data, len, noff);
651  off = noff;
652  switch (ret) {
653  case PARSE_CONTINUE:
654  v.insufficient_bytes(noff - 1, noff);
655  return ret;
656  case PARSE_SUCCESS:
657  if(noff < len) {
658  return PARSE_EXTRA_BYTES;
659  }
660  return ret;
661  default:
662  return ret;
663  }
664 }
665 
666 } // detail
667 
669 } // MSGPACK_API_VERSION_NAMESPACE(v3)
671 
672 } // namespace msgpack
673 
674 #endif // MSGPACK_DEFAULT_API_VERSION >= 2
675 
676 #endif // MSGPACK_V3_PARSE_HPP
#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
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_API_VERSION_NAMESPACE(ns)
Definition: versioning.hpp:66