parse.hpp 26 KB

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