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