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