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 = m_current - m_start;
67  return PARSE_STOP_VISITOR;
68  }
69  if (!ev()) {
70  off = 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 = m_current - m_start;
77  return ret;
78  }
79  }
80  else {
81  if (!sv(size)) {
82  off = 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 = 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 = 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 = 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  msgpack::object obj;
254 
255  if(m_current == pe) {
256  off = 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 = 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 = 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 = m_current - m_start;
621  holder().visitor().parse_error(n - m_start - 1, n - m_start);
622  return PARSE_PARSE_ERROR;
623  }
624  }
625  } while(m_current != pe);
626 
627  off = 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
msgpack::detail::context::execute
int execute(const char *data, std::size_t len, std::size_t &off)
Definition: unpack.hpp:452
msgpack::detail::context::context
context(unpack_reference_func f, void *user_data, unpack_limit const &limit)
Definition: unpack.hpp:305
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:312
msgpack::detail::context::data
msgpack::object const & data() const
Definition: unpack.hpp:320
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:271
msgpack::ext_size_overflow
Definition: unpack_exception.hpp:97
msgpack::object
Object class that corresponding to MessagePack format object.
Definition: object_fwd.hpp:75
msgpack::PARSE_SUCCESS
@ PARSE_SUCCESS
Definition: parse_return.hpp:24
msgpack::PARSE_EXTRA_BYTES
@ PARSE_EXTRA_BYTES
Definition: parse_return.hpp:25