parse.hpp 38 KB

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