parse.hpp 37 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072
  1. //
  2. // MessagePack for C++ deserializing routine
  3. //
  4. // Copyright (C) 2016-2017 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_V2_PARSE_HPP
  11. #define MSGPACK_V2_PARSE_HPP
  12. #if MSGPACK_DEFAULT_API_VERSION >= 2
  13. #include <cstddef>
  14. #include "msgpack/unpack_define.h"
  15. #include "msgpack/parse_return.hpp"
  16. #include "msgpack/unpack_exception.hpp"
  17. #include "msgpack/unpack_decl.hpp"
  18. namespace msgpack {
  19. /// @cond
  20. MSGPACK_API_VERSION_NAMESPACE(v2) {
  21. /// @endcond
  22. namespace detail {
  23. using v1::detail::fix_tag;
  24. using v1::detail::value;
  25. using v1::detail::load;
  26. template <typename VisitorHolder>
  27. class context {
  28. public:
  29. context()
  30. :m_trail(0), m_cs(MSGPACK_CS_HEADER)
  31. {
  32. }
  33. void init()
  34. {
  35. m_cs = MSGPACK_CS_HEADER;
  36. m_trail = 0;
  37. m_stack.clear();
  38. holder().visitor().init();
  39. }
  40. parse_return execute(const char* data, std::size_t len, std::size_t& off);
  41. private:
  42. template <typename T>
  43. static uint32_t next_cs(T p)
  44. {
  45. return static_cast<uint32_t>(*p) & 0x1f;
  46. }
  47. VisitorHolder& holder() {
  48. return static_cast<VisitorHolder&>(*this);
  49. }
  50. template <typename T, typename StartVisitor, typename EndVisitor>
  51. parse_return start_aggregate(
  52. StartVisitor const& sv,
  53. EndVisitor const& ev,
  54. const char* load_pos,
  55. std::size_t& off) {
  56. typename value<T>::type size;
  57. load<T>(size, load_pos);
  58. ++m_current;
  59. if (size == 0) {
  60. if (!sv(size)) {
  61. off = m_current - m_start;
  62. return PARSE_STOP_VISITOR;
  63. }
  64. if (!ev()) {
  65. off = m_current - m_start;
  66. return PARSE_STOP_VISITOR;
  67. }
  68. parse_return ret = m_stack.consume(holder());
  69. if (ret != PARSE_CONTINUE) {
  70. off = m_current - m_start;
  71. return ret;
  72. }
  73. }
  74. else {
  75. if (!sv(size)) {
  76. off = m_current - m_start;
  77. return PARSE_STOP_VISITOR;
  78. }
  79. parse_return ret = m_stack.push(holder(), sv.type(), static_cast<uint32_t>(size));
  80. if (ret != PARSE_CONTINUE) {
  81. off = m_current - m_start;
  82. return ret;
  83. }
  84. }
  85. m_cs = MSGPACK_CS_HEADER;
  86. return PARSE_CONTINUE;
  87. }
  88. parse_return after_visit_proc(bool visit_result, std::size_t& off) {
  89. ++m_current;
  90. if (!visit_result) {
  91. off = m_current - m_start;
  92. return PARSE_STOP_VISITOR;
  93. }
  94. parse_return ret = m_stack.consume(holder());
  95. if (ret != PARSE_CONTINUE) {
  96. off = m_current - m_start;
  97. }
  98. m_cs = MSGPACK_CS_HEADER;
  99. return ret;
  100. }
  101. struct array_sv {
  102. array_sv(VisitorHolder& visitor_holder):m_visitor_holder(visitor_holder) {}
  103. bool operator()(uint32_t size) const {
  104. return m_visitor_holder.visitor().start_array(size);
  105. }
  106. msgpack_container_type type() const { return MSGPACK_CT_ARRAY_ITEM; }
  107. private:
  108. VisitorHolder& m_visitor_holder;
  109. };
  110. struct array_ev {
  111. array_ev(VisitorHolder& visitor_holder):m_visitor_holder(visitor_holder) {}
  112. bool operator()() const {
  113. return m_visitor_holder.visitor().end_array();
  114. }
  115. private:
  116. VisitorHolder& m_visitor_holder;
  117. };
  118. struct map_sv {
  119. map_sv(VisitorHolder& visitor_holder):m_visitor_holder(visitor_holder) {}
  120. bool operator()(uint32_t size) const {
  121. return m_visitor_holder.visitor().start_map(size);
  122. }
  123. msgpack_container_type type() const { return MSGPACK_CT_MAP_KEY; }
  124. private:
  125. VisitorHolder& m_visitor_holder;
  126. };
  127. struct map_ev {
  128. map_ev(VisitorHolder& visitor_holder):m_visitor_holder(visitor_holder) {}
  129. bool operator()() const {
  130. return m_visitor_holder.visitor().end_map();
  131. }
  132. private:
  133. VisitorHolder& m_visitor_holder;
  134. };
  135. struct unpack_stack {
  136. struct stack_elem {
  137. stack_elem(msgpack_container_type type, uint32_t rest):m_type(type), m_rest(rest) {}
  138. msgpack_container_type m_type;
  139. uint32_t m_rest;
  140. };
  141. unpack_stack() {
  142. m_stack.reserve(MSGPACK_EMBED_STACK_SIZE);
  143. }
  144. parse_return push(VisitorHolder& visitor_holder, msgpack_container_type type, uint32_t rest) {
  145. m_stack.push_back(stack_elem(type, rest));
  146. switch (type) {
  147. case MSGPACK_CT_ARRAY_ITEM:
  148. return visitor_holder.visitor().start_array_item() ? PARSE_CONTINUE : PARSE_STOP_VISITOR;
  149. case MSGPACK_CT_MAP_KEY:
  150. return visitor_holder.visitor().start_map_key() ? PARSE_CONTINUE : PARSE_STOP_VISITOR;
  151. case MSGPACK_CT_MAP_VALUE:
  152. assert(0);
  153. return PARSE_STOP_VISITOR;
  154. }
  155. assert(0);
  156. return PARSE_STOP_VISITOR;
  157. }
  158. parse_return consume(VisitorHolder& visitor_holder) {
  159. while (!m_stack.empty()) {
  160. stack_elem& e = m_stack.back();
  161. switch (e.m_type) {
  162. case MSGPACK_CT_ARRAY_ITEM:
  163. if (!visitor_holder.visitor().end_array_item()) return PARSE_STOP_VISITOR;
  164. if (--e.m_rest == 0) {
  165. m_stack.pop_back();
  166. if (!visitor_holder.visitor().end_array()) return PARSE_STOP_VISITOR;
  167. }
  168. else {
  169. if (!visitor_holder.visitor().start_array_item()) return PARSE_STOP_VISITOR;
  170. return PARSE_CONTINUE;
  171. }
  172. break;
  173. case MSGPACK_CT_MAP_KEY:
  174. if (!visitor_holder.visitor().end_map_key()) return PARSE_STOP_VISITOR;
  175. if (!visitor_holder.visitor().start_map_value()) return PARSE_STOP_VISITOR;
  176. e.m_type = MSGPACK_CT_MAP_VALUE;
  177. return PARSE_CONTINUE;
  178. case MSGPACK_CT_MAP_VALUE:
  179. if (!visitor_holder.visitor().end_map_value()) return PARSE_STOP_VISITOR;
  180. if (--e.m_rest == 0) {
  181. m_stack.pop_back();
  182. if (!visitor_holder.visitor().end_map()) return PARSE_STOP_VISITOR;
  183. }
  184. else {
  185. e.m_type = MSGPACK_CT_MAP_KEY;
  186. if (!visitor_holder.visitor().start_map_key()) return PARSE_STOP_VISITOR;
  187. return PARSE_CONTINUE;
  188. }
  189. break;
  190. }
  191. }
  192. return PARSE_SUCCESS;
  193. }
  194. bool empty() const { return m_stack.empty(); }
  195. void clear() { m_stack.clear(); }
  196. private:
  197. std::vector<stack_elem> m_stack;
  198. };
  199. char const* m_start;
  200. char const* m_current;
  201. std::size_t m_trail;
  202. uint32_t m_cs;
  203. uint32_t m_num_elements;
  204. unpack_stack m_stack;
  205. };
  206. template <std::size_t N>
  207. inline void check_ext_size(std::size_t /*size*/) {
  208. }
  209. template <>
  210. inline void check_ext_size<4>(std::size_t size) {
  211. if (size == 0xffffffff) throw msgpack::ext_size_overflow("ext size overflow");
  212. }
  213. template <typename VisitorHolder>
  214. inline parse_return context<VisitorHolder>::execute(const char* data, std::size_t len, std::size_t& off)
  215. {
  216. assert(len >= off);
  217. m_start = data;
  218. m_current = data + off;
  219. const char* const pe = data + len;
  220. const char* n = MSGPACK_NULLPTR;
  221. msgpack::object obj;
  222. if(m_current == pe) {
  223. off = m_current - m_start;
  224. return PARSE_CONTINUE;
  225. }
  226. bool fixed_trail_again = false;
  227. do {
  228. if (m_cs == MSGPACK_CS_HEADER) {
  229. fixed_trail_again = false;
  230. int selector = *reinterpret_cast<const unsigned char*>(m_current);
  231. if (0x00 <= selector && selector <= 0x7f) { // Positive Fixnum
  232. uint8_t tmp = *reinterpret_cast<const uint8_t*>(m_current);
  233. bool visret = holder().visitor().visit_positive_integer(tmp);
  234. parse_return upr = after_visit_proc(visret, off);
  235. if (upr != PARSE_CONTINUE) return upr;
  236. } else if(0xe0 <= selector && selector <= 0xff) { // Negative Fixnum
  237. int8_t tmp = *reinterpret_cast<const int8_t*>(m_current);
  238. bool visret = holder().visitor().visit_negative_integer(tmp);
  239. parse_return upr = after_visit_proc(visret, off);
  240. if (upr != PARSE_CONTINUE) return upr;
  241. } else if (0xc4 <= selector && selector <= 0xdf) {
  242. const uint32_t trail[] = {
  243. 1, // bin 8 0xc4
  244. 2, // bin 16 0xc5
  245. 4, // bin 32 0xc6
  246. 1, // ext 8 0xc7
  247. 2, // ext 16 0xc8
  248. 4, // ext 32 0xc9
  249. 4, // float 32 0xca
  250. 8, // float 64 0xcb
  251. 1, // uint 8 0xcc
  252. 2, // uint 16 0xcd
  253. 4, // uint 32 0xce
  254. 8, // uint 64 0xcf
  255. 1, // int 8 0xd0
  256. 2, // int 16 0xd1
  257. 4, // int 32 0xd2
  258. 8, // int 64 0xd3
  259. 2, // fixext 1 0xd4
  260. 3, // fixext 2 0xd5
  261. 5, // fixext 4 0xd6
  262. 9, // fixext 8 0xd7
  263. 17,// fixext 16 0xd8
  264. 1, // str 8 0xd9
  265. 2, // str 16 0xda
  266. 4, // str 32 0xdb
  267. 2, // array 16 0xdc
  268. 4, // array 32 0xdd
  269. 2, // map 16 0xde
  270. 4, // map 32 0xdf
  271. };
  272. m_trail = trail[selector - 0xc4];
  273. m_cs = next_cs(m_current);
  274. fixed_trail_again = true;
  275. } else if(0xa0 <= selector && selector <= 0xbf) { // FixStr
  276. m_trail = static_cast<uint32_t>(*m_current) & 0x1f;
  277. if(m_trail == 0) {
  278. bool visret = holder().visitor().visit_str(n, static_cast<uint32_t>(m_trail));
  279. parse_return upr = after_visit_proc(visret, off);
  280. if (upr != PARSE_CONTINUE) return upr;
  281. }
  282. else {
  283. m_cs = MSGPACK_ACS_STR_VALUE;
  284. fixed_trail_again = true;
  285. }
  286. } else if(0x90 <= selector && selector <= 0x9f) { // FixArray
  287. parse_return ret = start_aggregate<fix_tag>(array_sv(holder()), array_ev(holder()), m_current, off);
  288. if (ret != PARSE_CONTINUE) return ret;
  289. } else if(0x80 <= selector && selector <= 0x8f) { // FixMap
  290. parse_return ret = start_aggregate<fix_tag>(map_sv(holder()), map_ev(holder()), m_current, off);
  291. if (ret != PARSE_CONTINUE) return ret;
  292. } else if(selector == 0xc2) { // false
  293. bool visret = holder().visitor().visit_boolean(false);
  294. parse_return upr = after_visit_proc(visret, off);
  295. if (upr != PARSE_CONTINUE) return upr;
  296. } else if(selector == 0xc3) { // true
  297. bool visret = holder().visitor().visit_boolean(true);
  298. parse_return upr = after_visit_proc(visret, off);
  299. if (upr != PARSE_CONTINUE) return upr;
  300. } else if(selector == 0xc0) { // nil
  301. bool visret = holder().visitor().visit_nil();
  302. parse_return upr = after_visit_proc(visret, off);
  303. if (upr != PARSE_CONTINUE) return upr;
  304. } else {
  305. off = m_current - m_start;
  306. holder().visitor().parse_error(off - 1, off);
  307. return PARSE_PARSE_ERROR;
  308. }
  309. // end MSGPACK_CS_HEADER
  310. }
  311. if (m_cs != MSGPACK_CS_HEADER || fixed_trail_again) {
  312. if (fixed_trail_again) {
  313. ++m_current;
  314. fixed_trail_again = false;
  315. }
  316. if(static_cast<std::size_t>(pe - m_current) < m_trail) {
  317. off = m_current - m_start;
  318. return PARSE_CONTINUE;
  319. }
  320. n = m_current;
  321. m_current += m_trail - 1;
  322. switch(m_cs) {
  323. //case MSGPACK_CS_
  324. //case MSGPACK_CS_
  325. case MSGPACK_CS_FLOAT: {
  326. union { uint32_t i; float f; } mem;
  327. load<uint32_t>(mem.i, n);
  328. bool visret = holder().visitor().visit_float32(mem.f);
  329. parse_return upr = after_visit_proc(visret, off);
  330. if (upr != PARSE_CONTINUE) return upr;
  331. } break;
  332. case MSGPACK_CS_DOUBLE: {
  333. union { uint64_t i; double f; } mem;
  334. load<uint64_t>(mem.i, n);
  335. #if defined(TARGET_OS_IPHONE)
  336. // ok
  337. #elif defined(__arm__) && !(__ARM_EABI__) // arm-oabi
  338. // https://github.com/msgpack/msgpack-perl/pull/1
  339. mem.i = (mem.i & 0xFFFFFFFFUL) << 32UL | (mem.i >> 32UL);
  340. #endif
  341. bool visret = holder().visitor().visit_float64(mem.f);
  342. parse_return upr = after_visit_proc(visret, off);
  343. if (upr != PARSE_CONTINUE) return upr;
  344. } break;
  345. case MSGPACK_CS_UINT_8: {
  346. uint8_t tmp;
  347. load<uint8_t>(tmp, n);
  348. bool visret = holder().visitor().visit_positive_integer(tmp);
  349. parse_return upr = after_visit_proc(visret, off);
  350. if (upr != PARSE_CONTINUE) return upr;
  351. } break;
  352. case MSGPACK_CS_UINT_16: {
  353. uint16_t tmp;
  354. load<uint16_t>(tmp, n);
  355. bool visret = holder().visitor().visit_positive_integer(tmp);
  356. parse_return upr = after_visit_proc(visret, off);
  357. if (upr != PARSE_CONTINUE) return upr;
  358. } break;
  359. case MSGPACK_CS_UINT_32: {
  360. uint32_t tmp;
  361. load<uint32_t>(tmp, n);
  362. bool visret = holder().visitor().visit_positive_integer(tmp);
  363. parse_return upr = after_visit_proc(visret, off);
  364. if (upr != PARSE_CONTINUE) return upr;
  365. } break;
  366. case MSGPACK_CS_UINT_64: {
  367. uint64_t tmp;
  368. load<uint64_t>(tmp, n);
  369. bool visret = holder().visitor().visit_positive_integer(tmp);
  370. parse_return upr = after_visit_proc(visret, off);
  371. if (upr != PARSE_CONTINUE) return upr;
  372. } break;
  373. case MSGPACK_CS_INT_8: {
  374. int8_t tmp;
  375. load<int8_t>(tmp, n);
  376. bool visret = holder().visitor().visit_negative_integer(tmp);
  377. parse_return upr = after_visit_proc(visret, off);
  378. if (upr != PARSE_CONTINUE) return upr;
  379. } break;
  380. case MSGPACK_CS_INT_16: {
  381. int16_t tmp;
  382. load<int16_t>(tmp, n);
  383. bool visret = holder().visitor().visit_negative_integer(tmp);
  384. parse_return upr = after_visit_proc(visret, off);
  385. if (upr != PARSE_CONTINUE) return upr;
  386. } break;
  387. case MSGPACK_CS_INT_32: {
  388. int32_t tmp;
  389. load<int32_t>(tmp, n);
  390. bool visret = holder().visitor().visit_negative_integer(tmp);
  391. parse_return upr = after_visit_proc(visret, off);
  392. if (upr != PARSE_CONTINUE) return upr;
  393. } break;
  394. case MSGPACK_CS_INT_64: {
  395. int64_t tmp;
  396. load<int64_t>(tmp, n);
  397. bool visret = holder().visitor().visit_negative_integer(tmp);
  398. parse_return upr = after_visit_proc(visret, off);
  399. if (upr != PARSE_CONTINUE) return upr;
  400. } break;
  401. case MSGPACK_CS_FIXEXT_1: {
  402. bool visret = holder().visitor().visit_ext(n, 1+1);
  403. parse_return upr = after_visit_proc(visret, off);
  404. if (upr != PARSE_CONTINUE) return upr;
  405. } break;
  406. case MSGPACK_CS_FIXEXT_2: {
  407. bool visret = holder().visitor().visit_ext(n, 2+1);
  408. parse_return upr = after_visit_proc(visret, off);
  409. if (upr != PARSE_CONTINUE) return upr;
  410. } break;
  411. case MSGPACK_CS_FIXEXT_4: {
  412. bool visret = holder().visitor().visit_ext(n, 4+1);
  413. parse_return upr = after_visit_proc(visret, off);
  414. if (upr != PARSE_CONTINUE) return upr;
  415. } break;
  416. case MSGPACK_CS_FIXEXT_8: {
  417. bool visret = holder().visitor().visit_ext(n, 8+1);
  418. parse_return upr = after_visit_proc(visret, off);
  419. if (upr != PARSE_CONTINUE) return upr;
  420. } break;
  421. case MSGPACK_CS_FIXEXT_16: {
  422. bool visret = holder().visitor().visit_ext(n, 16+1);
  423. parse_return upr = after_visit_proc(visret, off);
  424. if (upr != PARSE_CONTINUE) return upr;
  425. } break;
  426. case MSGPACK_CS_STR_8: {
  427. uint8_t tmp;
  428. load<uint8_t>(tmp, n);
  429. m_trail = tmp;
  430. if(m_trail == 0) {
  431. bool visret = holder().visitor().visit_str(n, static_cast<uint32_t>(m_trail));
  432. parse_return upr = after_visit_proc(visret, off);
  433. if (upr != PARSE_CONTINUE) return upr;
  434. }
  435. else {
  436. m_cs = MSGPACK_ACS_STR_VALUE;
  437. fixed_trail_again = true;
  438. }
  439. } break;
  440. case MSGPACK_CS_BIN_8: {
  441. uint8_t tmp;
  442. load<uint8_t>(tmp, n);
  443. m_trail = tmp;
  444. if(m_trail == 0) {
  445. bool visret = holder().visitor().visit_bin(n, static_cast<uint32_t>(m_trail));
  446. parse_return upr = after_visit_proc(visret, off);
  447. if (upr != PARSE_CONTINUE) return upr;
  448. }
  449. else {
  450. m_cs = MSGPACK_ACS_BIN_VALUE;
  451. fixed_trail_again = true;
  452. }
  453. } break;
  454. case MSGPACK_CS_EXT_8: {
  455. uint8_t tmp;
  456. load<uint8_t>(tmp, n);
  457. m_trail = tmp + 1;
  458. if(m_trail == 0) {
  459. bool visret = holder().visitor().visit_ext(n, static_cast<uint32_t>(m_trail));
  460. parse_return upr = after_visit_proc(visret, off);
  461. if (upr != PARSE_CONTINUE) return upr;
  462. }
  463. else {
  464. m_cs = MSGPACK_ACS_EXT_VALUE;
  465. fixed_trail_again = true;
  466. }
  467. } break;
  468. case MSGPACK_CS_STR_16: {
  469. uint16_t tmp;
  470. load<uint16_t>(tmp, n);
  471. m_trail = tmp;
  472. if(m_trail == 0) {
  473. bool visret = holder().visitor().visit_str(n, static_cast<uint32_t>(m_trail));
  474. parse_return upr = after_visit_proc(visret, off);
  475. if (upr != PARSE_CONTINUE) return upr;
  476. }
  477. else {
  478. m_cs = MSGPACK_ACS_STR_VALUE;
  479. fixed_trail_again = true;
  480. }
  481. } break;
  482. case MSGPACK_CS_BIN_16: {
  483. uint16_t tmp;
  484. load<uint16_t>(tmp, n);
  485. m_trail = tmp;
  486. if(m_trail == 0) {
  487. bool visret = holder().visitor().visit_bin(n, static_cast<uint32_t>(m_trail));
  488. parse_return upr = after_visit_proc(visret, off);
  489. if (upr != PARSE_CONTINUE) return upr;
  490. }
  491. else {
  492. m_cs = MSGPACK_ACS_BIN_VALUE;
  493. fixed_trail_again = true;
  494. }
  495. } break;
  496. case MSGPACK_CS_EXT_16: {
  497. uint16_t tmp;
  498. load<uint16_t>(tmp, n);
  499. m_trail = tmp + 1;
  500. if(m_trail == 0) {
  501. bool visret = holder().visitor().visit_ext(n, static_cast<uint32_t>(m_trail));
  502. parse_return upr = after_visit_proc(visret, off);
  503. if (upr != PARSE_CONTINUE) return upr;
  504. }
  505. else {
  506. m_cs = MSGPACK_ACS_EXT_VALUE;
  507. fixed_trail_again = true;
  508. }
  509. } break;
  510. case MSGPACK_CS_STR_32: {
  511. uint32_t tmp;
  512. load<uint32_t>(tmp, n);
  513. m_trail = tmp;
  514. if(m_trail == 0) {
  515. bool visret = holder().visitor().visit_str(n, static_cast<uint32_t>(m_trail));
  516. parse_return upr = after_visit_proc(visret, off);
  517. if (upr != PARSE_CONTINUE) return upr;
  518. }
  519. else {
  520. m_cs = MSGPACK_ACS_STR_VALUE;
  521. fixed_trail_again = true;
  522. }
  523. } break;
  524. case MSGPACK_CS_BIN_32: {
  525. uint32_t tmp;
  526. load<uint32_t>(tmp, n);
  527. m_trail = tmp;
  528. if(m_trail == 0) {
  529. bool visret = holder().visitor().visit_bin(n, static_cast<uint32_t>(m_trail));
  530. parse_return upr = after_visit_proc(visret, off);
  531. if (upr != PARSE_CONTINUE) return upr;
  532. }
  533. else {
  534. m_cs = MSGPACK_ACS_BIN_VALUE;
  535. fixed_trail_again = true;
  536. }
  537. } break;
  538. case MSGPACK_CS_EXT_32: {
  539. uint32_t tmp;
  540. load<uint32_t>(tmp, n);
  541. check_ext_size<sizeof(std::size_t)>(tmp);
  542. m_trail = tmp;
  543. ++m_trail;
  544. if(m_trail == 0) {
  545. bool visret = holder().visitor().visit_ext(n, static_cast<uint32_t>(m_trail));
  546. parse_return upr = after_visit_proc(visret, off);
  547. if (upr != PARSE_CONTINUE) return upr;
  548. }
  549. else {
  550. m_cs = MSGPACK_ACS_EXT_VALUE;
  551. fixed_trail_again = true;
  552. }
  553. } break;
  554. case MSGPACK_ACS_STR_VALUE: {
  555. bool visret = holder().visitor().visit_str(n, static_cast<uint32_t>(m_trail));
  556. parse_return upr = after_visit_proc(visret, off);
  557. if (upr != PARSE_CONTINUE) return upr;
  558. } break;
  559. case MSGPACK_ACS_BIN_VALUE: {
  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. } break;
  564. case MSGPACK_ACS_EXT_VALUE: {
  565. bool visret = holder().visitor().visit_ext(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_CS_ARRAY_16: {
  570. parse_return ret = start_aggregate<uint16_t>(array_sv(holder()), array_ev(holder()), n, off);
  571. if (ret != PARSE_CONTINUE) return ret;
  572. } break;
  573. case MSGPACK_CS_ARRAY_32: {
  574. parse_return ret = start_aggregate<uint32_t>(array_sv(holder()), array_ev(holder()), n, off);
  575. if (ret != PARSE_CONTINUE) return ret;
  576. } break;
  577. case MSGPACK_CS_MAP_16: {
  578. parse_return ret = start_aggregate<uint16_t>(map_sv(holder()), map_ev(holder()), n, off);
  579. if (ret != PARSE_CONTINUE) return ret;
  580. } break;
  581. case MSGPACK_CS_MAP_32: {
  582. parse_return ret = start_aggregate<uint32_t>(map_sv(holder()), map_ev(holder()), n, off);
  583. if (ret != PARSE_CONTINUE) return ret;
  584. } break;
  585. default:
  586. off = m_current - m_start;
  587. holder().visitor().parse_error(n - m_start - 1, n - m_start);
  588. return PARSE_PARSE_ERROR;
  589. }
  590. }
  591. } while(m_current != pe);
  592. off = m_current - m_start;
  593. return PARSE_CONTINUE;
  594. }
  595. } // detail
  596. /// Parsing class for a stream deserialization.
  597. template <typename VisitorHolder, typename ReferencedBufferHook>
  598. class parser : public detail::context<VisitorHolder> {
  599. typedef parser<VisitorHolder, ReferencedBufferHook> this_type;
  600. typedef detail::context<VisitorHolder> context_type;
  601. public:
  602. /// Constructor
  603. /**
  604. * @param hook The handler that is called when buffer is allocated internally.
  605. * `hook` should be callable with char* parameter.
  606. * `parser` gives a chance to prepare finalizer.
  607. * See https://github.com/msgpack/msgpack-c/wiki/v2_0_cpp_visitor#parse-api
  608. * @param initial_buffer_size The memory size to allocate when unpacker is constructed.
  609. *
  610. */
  611. parser(ReferencedBufferHook& hook,
  612. std::size_t initial_buffer_size = MSGPACK_UNPACKER_INIT_BUFFER_SIZE);
  613. #if !defined(MSGPACK_USE_CPP03)
  614. parser(this_type&& other);
  615. this_type& operator=(this_type&& other);
  616. #endif // !defined(MSGPACK_USE_CPP03)
  617. ~parser();
  618. public:
  619. /// Reserve a buffer memory.
  620. /**
  621. * @param size The size of allocating memory.
  622. *
  623. * After returning this function, buffer_capacity() returns at least 'size'.
  624. * See:
  625. * https://github.com/msgpack/msgpack-c/wiki/v1_1_cpp_unpacker#msgpack-controls-a-buffer
  626. */
  627. void reserve_buffer(std::size_t size = MSGPACK_UNPACKER_RESERVE_SIZE);
  628. /// Get buffer pointer.
  629. /**
  630. * You need to care about the memory is enable between buffer() and buffer() + buffer_capacity()
  631. * See:
  632. * https://github.com/msgpack/msgpack-c/wiki/v1_1_cpp_unpacker#msgpack-controls-a-buffer
  633. */
  634. char* buffer();
  635. /// Get buffer capacity.
  636. /**
  637. * @return The memory size that you can write.
  638. *
  639. * See:
  640. * https://github.com/msgpack/msgpack-c/wiki/v1_1_cpp_unpacker#msgpack-controls-a-buffer
  641. */
  642. std::size_t buffer_capacity() const;
  643. /// Notify a buffer consumed information to msgpack::unpacker.
  644. /**
  645. * @param size The size of memory that you consumed.
  646. *
  647. * After copying the data to the memory that is pointed by buffer(), you need to call the
  648. * function to notify how many bytes are consumed. Then you can call next() functions.
  649. *
  650. * See:
  651. * https://github.com/msgpack/msgpack-c/wiki/v1_1_cpp_unpacker#msgpack-controls-a-buffer
  652. */
  653. void buffer_consumed(std::size_t size);
  654. /// Unpack one msgpack::object.
  655. /**
  656. *
  657. *
  658. * @return If one msgpack::object is unpacked, then return true, if msgpack::object is incomplete
  659. * and additional data is required, then return false. If data format is invalid, throw
  660. * msgpack::parse_error.
  661. *
  662. * See:
  663. * https://github.com/msgpack/msgpack-c/wiki/v1_1_cpp_unpacker#msgpack-controls-a-buffer
  664. */
  665. bool next();
  666. /// Get message size.
  667. /**
  668. * @return Returns parsed_size() + nonparsed_size()
  669. */
  670. std::size_t message_size() const;
  671. public:
  672. /// Get parsed message size.
  673. /**
  674. * @return Parsed message size.
  675. *
  676. * This function is usable when non-MessagePack message follows after
  677. * MessagePack message.
  678. */
  679. std::size_t parsed_size() const;
  680. /// Get the address that is not parsed in the buffer.
  681. /**
  682. * @return Address of the buffer that is not parsed
  683. *
  684. * This function is usable when non-MessagePack message follows after
  685. * MessagePack message.
  686. */
  687. char* nonparsed_buffer();
  688. /// Get the size of the buffer that is not parsed.
  689. /**
  690. * @return Size of the buffer that is not parsed
  691. *
  692. * This function is usable when non-MessagePack message follows after
  693. * MessagePack message.
  694. */
  695. std::size_t nonparsed_size() const;
  696. /// Skip the specified size of non-parsed buffer.
  697. /**
  698. * @param size to skip
  699. *
  700. * Note that the `size' argument must be smaller than nonparsed_size().
  701. * This function is usable when non-MessagePack message follows after
  702. * MessagePack message.
  703. */
  704. void skip_nonparsed_buffer(std::size_t size);
  705. /// Remove nonparsed buffer and reset the current position as a new start point.
  706. /**
  707. * This function is usable when non-MessagePack message follows after
  708. * MessagePack message.
  709. */
  710. void remove_nonparsed_buffer();
  711. void reset();
  712. protected:
  713. char* get_raw_buffer() {
  714. return m_buffer;
  715. }
  716. private:
  717. void expand_buffer(std::size_t size);
  718. parse_return execute_imp();
  719. private:
  720. char* m_buffer;
  721. std::size_t m_used;
  722. std::size_t m_free;
  723. std::size_t m_off;
  724. std::size_t m_parsed;
  725. std::size_t m_initial_buffer_size;
  726. ReferencedBufferHook& m_referenced_buffer_hook;
  727. #if defined(MSGPACK_USE_CPP03)
  728. private:
  729. parser(const this_type&);
  730. this_type& operator=(const this_type&);
  731. #else // defined(MSGPACK_USE_CPP03)
  732. public:
  733. parser(const this_type&) = delete;
  734. this_type& operator=(const this_type&) = delete;
  735. #endif // defined(MSGPACK_USE_CPP03)
  736. };
  737. template <typename VisitorHolder, typename ReferencedBufferHook>
  738. inline parser<VisitorHolder, ReferencedBufferHook>::parser(
  739. ReferencedBufferHook& hook,
  740. std::size_t initial_buffer_size)
  741. :m_referenced_buffer_hook(hook)
  742. {
  743. if(initial_buffer_size < COUNTER_SIZE) {
  744. initial_buffer_size = COUNTER_SIZE;
  745. }
  746. char* buffer = static_cast<char*>(::malloc(initial_buffer_size));
  747. if(!buffer) {
  748. throw std::bad_alloc();
  749. }
  750. m_buffer = buffer;
  751. m_used = COUNTER_SIZE;
  752. m_free = initial_buffer_size - m_used;
  753. m_off = COUNTER_SIZE;
  754. m_parsed = 0;
  755. m_initial_buffer_size = initial_buffer_size;
  756. detail::init_count(m_buffer);
  757. }
  758. #if !defined(MSGPACK_USE_CPP03)
  759. // Move constructor and move assignment operator
  760. template <typename VisitorHolder, typename ReferencedBufferHook>
  761. inline parser<VisitorHolder, ReferencedBufferHook>::parser(this_type&& other)
  762. :context_type(std::move(other)),
  763. m_buffer(other.m_buffer),
  764. m_used(other.m_used),
  765. m_free(other.m_free),
  766. m_off(other.m_off),
  767. m_parsed(other.m_parsed),
  768. m_initial_buffer_size(other.m_initial_buffer_size),
  769. m_referenced_buffer_hook(other.m_referenced_buffer_hook) {
  770. other.m_buffer = MSGPACK_NULLPTR;
  771. other.m_used = 0;
  772. other.m_free = 0;
  773. other.m_off = 0;
  774. other.m_parsed = 0;
  775. }
  776. template <typename VisitorHolder, typename ReferencedBufferHook>
  777. inline parser<VisitorHolder, ReferencedBufferHook>& parser<VisitorHolder, ReferencedBufferHook>::operator=(this_type&& other) {
  778. this->~parser();
  779. new (this) this_type(std::move(other));
  780. return *this;
  781. }
  782. #endif // !defined(MSGPACK_USE_CPP03)
  783. template <typename VisitorHolder, typename ReferencedBufferHook>
  784. inline parser<VisitorHolder, ReferencedBufferHook>::~parser()
  785. {
  786. // These checks are required for move operations.
  787. if (m_buffer) detail::decr_count(m_buffer);
  788. }
  789. template <typename VisitorHolder, typename ReferencedBufferHook>
  790. inline void parser<VisitorHolder, ReferencedBufferHook>::reserve_buffer(std::size_t size)
  791. {
  792. if(m_free >= size) return;
  793. expand_buffer(size);
  794. }
  795. template <typename VisitorHolder, typename ReferencedBufferHook>
  796. inline void parser<VisitorHolder, ReferencedBufferHook>::expand_buffer(std::size_t size)
  797. {
  798. if(m_used == m_off && detail::get_count(m_buffer) == 1
  799. && !static_cast<VisitorHolder&>(*this).visitor().referenced()) {
  800. // rewind buffer
  801. m_free += m_used - COUNTER_SIZE;
  802. m_used = COUNTER_SIZE;
  803. m_off = COUNTER_SIZE;
  804. if(m_free >= size) return;
  805. }
  806. if(m_off == COUNTER_SIZE) {
  807. std::size_t next_size = (m_used + m_free) * 2; // include COUNTER_SIZE
  808. while(next_size < size + m_used) {
  809. std::size_t tmp_next_size = next_size * 2;
  810. if (tmp_next_size <= next_size) {
  811. next_size = size + m_used;
  812. break;
  813. }
  814. next_size = tmp_next_size;
  815. }
  816. char* tmp = static_cast<char*>(::realloc(m_buffer, next_size));
  817. if(!tmp) {
  818. throw std::bad_alloc();
  819. }
  820. m_buffer = tmp;
  821. m_free = next_size - m_used;
  822. } else {
  823. std::size_t next_size = m_initial_buffer_size; // include COUNTER_SIZE
  824. std::size_t not_parsed = m_used - m_off;
  825. while(next_size < size + not_parsed + COUNTER_SIZE) {
  826. std::size_t tmp_next_size = next_size * 2;
  827. if (tmp_next_size <= next_size) {
  828. next_size = size + not_parsed + COUNTER_SIZE;
  829. break;
  830. }
  831. next_size = tmp_next_size;
  832. }
  833. char* tmp = static_cast<char*>(::malloc(next_size));
  834. if(!tmp) {
  835. throw std::bad_alloc();
  836. }
  837. detail::init_count(tmp);
  838. std::memcpy(tmp+COUNTER_SIZE, m_buffer + m_off, not_parsed);
  839. if(static_cast<VisitorHolder&>(*this).referenced()) {
  840. try {
  841. m_referenced_buffer_hook(m_buffer);
  842. }
  843. catch (...) {
  844. ::free(tmp);
  845. throw;
  846. }
  847. static_cast<VisitorHolder&>(*this).set_referenced(false);
  848. } else {
  849. detail::decr_count(m_buffer);
  850. }
  851. m_buffer = tmp;
  852. m_used = not_parsed + COUNTER_SIZE;
  853. m_free = next_size - m_used;
  854. m_off = COUNTER_SIZE;
  855. }
  856. }
  857. template <typename VisitorHolder, typename ReferencedBufferHook>
  858. inline char* parser<VisitorHolder, ReferencedBufferHook>::buffer()
  859. {
  860. return m_buffer + m_used;
  861. }
  862. template <typename VisitorHolder, typename ReferencedBufferHook>
  863. inline std::size_t parser<VisitorHolder, ReferencedBufferHook>::buffer_capacity() const
  864. {
  865. return m_free;
  866. }
  867. template <typename VisitorHolder, typename ReferencedBufferHook>
  868. inline void parser<VisitorHolder, ReferencedBufferHook>::buffer_consumed(std::size_t size)
  869. {
  870. m_used += size;
  871. m_free -= size;
  872. }
  873. template <typename VisitorHolder, typename ReferencedBufferHook>
  874. inline bool parser<VisitorHolder, ReferencedBufferHook>::next()
  875. {
  876. parse_return ret = execute_imp();
  877. return ret == PARSE_SUCCESS;
  878. }
  879. template <typename VisitorHolder, typename ReferencedBufferHook>
  880. inline parse_return parser<VisitorHolder, ReferencedBufferHook>::execute_imp()
  881. {
  882. std::size_t off = m_off;
  883. parse_return ret = context_type::execute(m_buffer, m_used, m_off);
  884. if(m_off > off) {
  885. m_parsed += m_off - off;
  886. }
  887. return ret;
  888. }
  889. template <typename VisitorHolder, typename ReferencedBufferHook>
  890. inline void parser<VisitorHolder, ReferencedBufferHook>::reset()
  891. {
  892. context_type::init();
  893. // don't reset referenced flag
  894. m_parsed = 0;
  895. }
  896. template <typename VisitorHolder, typename ReferencedBufferHook>
  897. inline std::size_t parser<VisitorHolder, ReferencedBufferHook>::message_size() const
  898. {
  899. return m_parsed - m_off + m_used;
  900. }
  901. template <typename VisitorHolder, typename ReferencedBufferHook>
  902. inline std::size_t parser<VisitorHolder, ReferencedBufferHook>::parsed_size() const
  903. {
  904. return m_parsed;
  905. }
  906. template <typename VisitorHolder, typename ReferencedBufferHook>
  907. inline char* parser<VisitorHolder, ReferencedBufferHook>::nonparsed_buffer()
  908. {
  909. return m_buffer + m_off;
  910. }
  911. template <typename VisitorHolder, typename ReferencedBufferHook>
  912. inline std::size_t parser<VisitorHolder, ReferencedBufferHook>::nonparsed_size() const
  913. {
  914. return m_used - m_off;
  915. }
  916. template <typename VisitorHolder, typename ReferencedBufferHook>
  917. inline void parser<VisitorHolder, ReferencedBufferHook>::skip_nonparsed_buffer(std::size_t size)
  918. {
  919. m_off += size;
  920. }
  921. template <typename VisitorHolder, typename ReferencedBufferHook>
  922. inline void parser<VisitorHolder, ReferencedBufferHook>::remove_nonparsed_buffer()
  923. {
  924. m_used = m_off;
  925. }
  926. template <typename Visitor>
  927. inline bool parse(const char* data, size_t len, size_t& off, Visitor& v) {
  928. parse_return ret = msgpack::detail::parse_imp(data, len, off, v);
  929. return ret == PARSE_SUCCESS || ret == PARSE_EXTRA_BYTES;
  930. }
  931. template <typename Visitor>
  932. inline bool parse(const char* data, size_t len, Visitor& v) {
  933. std::size_t off = 0;
  934. return msgpack::parse(data, len, off, v);
  935. }
  936. namespace detail {
  937. template <typename Visitor>
  938. struct parse_helper : detail::context<parse_helper<Visitor> > {
  939. parse_helper(Visitor& v):m_visitor(v) {}
  940. parse_return execute(const char* data, std::size_t len, std::size_t& off) {
  941. return detail::context<parse_helper<Visitor> >::execute(data, len, off);
  942. }
  943. Visitor& visitor() const { return m_visitor; }
  944. Visitor& m_visitor;
  945. };
  946. template <typename Visitor>
  947. inline parse_return
  948. parse_imp(const char* data, size_t len, size_t& off, Visitor& v) {
  949. std::size_t noff = off;
  950. if(len <= noff) {
  951. // FIXME
  952. v.insufficient_bytes(noff, noff);
  953. return PARSE_CONTINUE;
  954. }
  955. detail::parse_helper<Visitor> h(v);
  956. parse_return ret = h.execute(data, len, noff);
  957. switch (ret) {
  958. case PARSE_CONTINUE:
  959. off = noff;
  960. v.insufficient_bytes(noff - 1, noff);
  961. return ret;
  962. case PARSE_SUCCESS:
  963. off = noff;
  964. if(noff < len) {
  965. return PARSE_EXTRA_BYTES;
  966. }
  967. return ret;
  968. default:
  969. return ret;
  970. }
  971. }
  972. } // detail
  973. /// @cond
  974. } // MSGPACK_API_VERSION_NAMESPACE(v2)
  975. /// @endcond
  976. } // namespace msgpack
  977. #endif // MSGPACK_DEFAULT_API_VERSION >= 2
  978. #endif // MSGPACK_V2_PARSE_HPP