parse.hpp 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676
  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. #include "msgpack/assert.hpp"
  16. namespace msgpack {
  17. /// @cond
  18. MSGPACK_API_VERSION_NAMESPACE(v3) {
  19. /// @endcond
  20. namespace detail {
  21. template <typename VisitorHolder>
  22. class context {
  23. public:
  24. context()
  25. :m_trail(0), m_cs(MSGPACK_CS_HEADER)
  26. {
  27. }
  28. void init()
  29. {
  30. m_cs = MSGPACK_CS_HEADER;
  31. m_trail = 0;
  32. m_stack.clear();
  33. holder().visitor().init();
  34. }
  35. parse_return execute(const char* data, std::size_t len, std::size_t& off);
  36. private:
  37. template <typename T>
  38. static uint32_t next_cs(T p)
  39. {
  40. return static_cast<uint32_t>(*p) & 0x1f;
  41. }
  42. VisitorHolder& holder() {
  43. return static_cast<VisitorHolder&>(*this);
  44. }
  45. template <typename T, typename StartVisitor, typename EndVisitor>
  46. parse_return start_aggregate(
  47. StartVisitor const& sv,
  48. EndVisitor const& ev,
  49. const char* load_pos,
  50. std::size_t& off) {
  51. typename value<T>::type size;
  52. load<T>(size, load_pos);
  53. if (size == 0) {
  54. if (!sv(size)) {
  55. off = static_cast<std::size_t>(m_current - m_start);
  56. return PARSE_STOP_VISITOR;
  57. }
  58. if (!ev()) {
  59. off = static_cast<std::size_t>(m_current - m_start);
  60. return PARSE_STOP_VISITOR;
  61. }
  62. parse_return ret = m_stack.consume(holder(), m_current);
  63. ++m_current;
  64. if (ret != PARSE_CONTINUE) {
  65. off = static_cast<std::size_t>(m_current - m_start);
  66. return ret;
  67. }
  68. }
  69. else {
  70. if (!sv(size)) {
  71. off = static_cast<std::size_t>(m_current - m_start);
  72. return PARSE_STOP_VISITOR;
  73. }
  74. parse_return ret = m_stack.push(holder(), sv.type(), static_cast<uint32_t>(size));
  75. ++m_current;
  76. if (ret != PARSE_CONTINUE) {
  77. off = static_cast<std::size_t>(m_current - m_start);
  78. return ret;
  79. }
  80. }
  81. m_cs = MSGPACK_CS_HEADER;
  82. return PARSE_CONTINUE;
  83. }
  84. parse_return after_visit_proc(bool visit_result, std::size_t& off) {
  85. if (!visit_result) {
  86. off = static_cast<std::size_t>(m_current - m_start);
  87. return PARSE_STOP_VISITOR;
  88. }
  89. parse_return ret = m_stack.consume(holder(), m_current);
  90. ++m_current;
  91. if (ret != PARSE_CONTINUE) {
  92. off = static_cast<std::size_t>(m_current - m_start);
  93. }
  94. m_cs = MSGPACK_CS_HEADER;
  95. return ret;
  96. }
  97. struct array_sv {
  98. array_sv(VisitorHolder& visitor_holder):m_visitor_holder(visitor_holder) {}
  99. bool operator()(uint32_t size) const {
  100. return m_visitor_holder.visitor().start_array(size);
  101. }
  102. msgpack_container_type type() const { return MSGPACK_CT_ARRAY_ITEM; }
  103. private:
  104. VisitorHolder& m_visitor_holder;
  105. };
  106. struct array_ev {
  107. array_ev(VisitorHolder& visitor_holder):m_visitor_holder(visitor_holder) {}
  108. bool operator()() const {
  109. return m_visitor_holder.visitor().end_array();
  110. }
  111. private:
  112. VisitorHolder& m_visitor_holder;
  113. };
  114. struct map_sv {
  115. map_sv(VisitorHolder& visitor_holder):m_visitor_holder(visitor_holder) {}
  116. bool operator()(uint32_t size) const {
  117. return m_visitor_holder.visitor().start_map(size);
  118. }
  119. msgpack_container_type type() const { return MSGPACK_CT_MAP_KEY; }
  120. private:
  121. VisitorHolder& m_visitor_holder;
  122. };
  123. struct map_ev {
  124. map_ev(VisitorHolder& visitor_holder):m_visitor_holder(visitor_holder) {}
  125. bool operator()() const {
  126. return m_visitor_holder.visitor().end_map();
  127. }
  128. private:
  129. VisitorHolder& m_visitor_holder;
  130. };
  131. struct unpack_stack {
  132. struct stack_elem {
  133. stack_elem(msgpack_container_type type, uint32_t rest):m_type(type), m_rest(rest) {}
  134. msgpack_container_type m_type;
  135. uint32_t m_rest;
  136. };
  137. unpack_stack() {
  138. m_stack.reserve(MSGPACK_EMBED_STACK_SIZE);
  139. }
  140. parse_return push(VisitorHolder& visitor_holder, msgpack_container_type type, uint32_t rest) {
  141. m_stack.push_back(stack_elem(type, rest));
  142. switch (type) {
  143. case MSGPACK_CT_ARRAY_ITEM:
  144. return visitor_holder.visitor().start_array_item() ? PARSE_CONTINUE : PARSE_STOP_VISITOR;
  145. case MSGPACK_CT_MAP_KEY:
  146. return visitor_holder.visitor().start_map_key() ? PARSE_CONTINUE : PARSE_STOP_VISITOR;
  147. case MSGPACK_CT_MAP_VALUE:
  148. MSGPACK_ASSERT(0);
  149. return PARSE_STOP_VISITOR;
  150. }
  151. MSGPACK_ASSERT(0);
  152. return PARSE_STOP_VISITOR;
  153. }
  154. parse_return consume(VisitorHolder& visitor_holder, char const*& current) {
  155. while (!m_stack.empty()) {
  156. stack_elem& e = m_stack.back();
  157. switch (e.m_type) {
  158. case MSGPACK_CT_ARRAY_ITEM:
  159. if (!visitor_holder.visitor().end_array_item()) {
  160. --current;
  161. return PARSE_STOP_VISITOR;
  162. }
  163. if (--e.m_rest == 0) {
  164. m_stack.pop_back();
  165. if (!visitor_holder.visitor().end_array()) {
  166. --current;
  167. return PARSE_STOP_VISITOR;
  168. }
  169. }
  170. else {
  171. if (!visitor_holder.visitor().start_array_item()) return PARSE_STOP_VISITOR;
  172. return PARSE_CONTINUE;
  173. }
  174. break;
  175. case MSGPACK_CT_MAP_KEY:
  176. if (!visitor_holder.visitor().end_map_key()) {
  177. --current;
  178. return PARSE_STOP_VISITOR;
  179. }
  180. if (!visitor_holder.visitor().start_map_value()) return PARSE_STOP_VISITOR;
  181. e.m_type = MSGPACK_CT_MAP_VALUE;
  182. return PARSE_CONTINUE;
  183. case MSGPACK_CT_MAP_VALUE:
  184. if (!visitor_holder.visitor().end_map_value()) {
  185. --current;
  186. return PARSE_STOP_VISITOR;
  187. }
  188. if (--e.m_rest == 0) {
  189. m_stack.pop_back();
  190. if (!visitor_holder.visitor().end_map()) {
  191. --current;
  192. return PARSE_STOP_VISITOR;
  193. }
  194. }
  195. else {
  196. e.m_type = MSGPACK_CT_MAP_KEY;
  197. if (!visitor_holder.visitor().start_map_key()) return PARSE_STOP_VISITOR;
  198. return PARSE_CONTINUE;
  199. }
  200. break;
  201. }
  202. }
  203. return PARSE_SUCCESS;
  204. }
  205. bool empty() const { return m_stack.empty(); }
  206. void clear() { m_stack.clear(); }
  207. private:
  208. std::vector<stack_elem> m_stack;
  209. };
  210. char const* m_start;
  211. char const* m_current;
  212. std::size_t m_trail;
  213. uint32_t m_cs;
  214. uint32_t m_num_elements;
  215. unpack_stack m_stack;
  216. };
  217. template <std::size_t N>
  218. inline void check_ext_size(std::size_t /*size*/) {
  219. }
  220. template <>
  221. inline void check_ext_size<4>(std::size_t size) {
  222. if (size == 0xffffffff) throw msgpack::ext_size_overflow("ext size overflow");
  223. }
  224. template <typename VisitorHolder>
  225. inline parse_return context<VisitorHolder>::execute(const char* data, std::size_t len, std::size_t& off)
  226. {
  227. MSGPACK_ASSERT(len >= off);
  228. m_start = data;
  229. m_current = data + off;
  230. const char* const pe = data + len;
  231. const char* n = MSGPACK_NULLPTR;
  232. if(m_current == pe) {
  233. off = static_cast<std::size_t>(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 = static_cast<std::size_t>(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 = static_cast<std::size_t>(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 = static_cast<std::size_t>(m_current - m_start);
  597. holder().visitor().parse_error(static_cast<std::size_t>(n - m_start - 1), static_cast<std::size_t>(n - m_start));
  598. return PARSE_PARSE_ERROR;
  599. }
  600. }
  601. } while(m_current != pe);
  602. off = static_cast<std::size_t>(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