x3_parse.hpp 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875
  1. //
  2. // MessagePack for C++ deserializing routine
  3. //
  4. // Copyright (C) 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_X3_PARSE_HPP
  11. #define MSGPACK_V2_X3_PARSE_HPP
  12. #if defined(MSGPACK_USE_X3_PARSE)
  13. #include <boost/version.hpp>
  14. #if BOOST_VERSION >= 106100
  15. #include "msgpack/versioning.hpp"
  16. #include "msgpack/x3_parse_decl.hpp"
  17. #if __GNUC__ >= 4
  18. #pragma GCC diagnostic push
  19. #pragma GCC diagnostic ignored "-Wunused-parameter"
  20. #pragma GCC diagnostic ignored "-Wconversion"
  21. #endif // __GNUC__ >= 4
  22. #include <boost/config/warning_disable.hpp>
  23. #include <boost/spirit/home/x3.hpp>
  24. #include <boost/spirit/home/x3/binary.hpp>
  25. namespace msgpack {
  26. /// @cond
  27. MSGPACK_API_VERSION_NAMESPACE(v2) {
  28. /// @endcond
  29. namespace detail {
  30. namespace x3 = boost::spirit::x3;
  31. using x3::byte_;
  32. // byte range utility
  33. const auto byte_range = [](const std::uint8_t from, const std::uint8_t to) {
  34. const auto check = [from, to](auto& ctx)
  35. {
  36. const std::uint8_t value = x3::_attr(ctx);
  37. x3::_val(ctx) = value;
  38. x3::_pass(ctx) = from <= value && value <= to;
  39. };
  40. return x3::byte_ [check];
  41. };
  42. // MessagePack rule
  43. const auto mp_positive_fixint = byte_range(0x00, 0x7f);
  44. const auto mp_fixmap = byte_range(0x80, 0x8f);
  45. const auto mp_fixarray = byte_range(0x90, 0x9f);
  46. const auto mp_fixstr = byte_range(0xa0, 0xbf);
  47. const auto mp_nil = x3::byte_(0xc0);
  48. const auto mp_false = x3::byte_(0xc2);
  49. const auto mp_true = x3::byte_(0xc3);
  50. const auto mp_bin8 = x3::byte_(0xc4);
  51. const auto mp_bin16 = x3::byte_(0xc5);
  52. const auto mp_bin32 = x3::byte_(0xc6);
  53. const auto mp_ext8 = x3::byte_(0xc7);
  54. const auto mp_ext16 = x3::byte_(0xc8);
  55. const auto mp_ext32 = x3::byte_(0xc9);
  56. const auto mp_float32 = x3::byte_(0xca);
  57. const auto mp_float64 = x3::byte_(0xcb);
  58. const auto mp_uint8 = x3::byte_(0xcc);
  59. const auto mp_uint16 = x3::byte_(0xcd);
  60. const auto mp_uint32 = x3::byte_(0xce);
  61. const auto mp_uint64 = x3::byte_(0xcf);
  62. const auto mp_int8 = x3::byte_(0xd0);
  63. const auto mp_int16 = x3::byte_(0xd1);
  64. const auto mp_int32 = x3::byte_(0xd2);
  65. const auto mp_int64 = x3::byte_(0xd3);
  66. const auto mp_fixext1 = x3::byte_(0xd4);
  67. const auto mp_fixext2 = x3::byte_(0xd5);
  68. const auto mp_fixext4 = x3::byte_(0xd6);
  69. const auto mp_fixext8 = x3::byte_(0xd7);
  70. const auto mp_fixext16 = x3::byte_(0xd8);
  71. const auto mp_str8 = x3::byte_(0xd9);
  72. const auto mp_str16 = x3::byte_(0xda);
  73. const auto mp_str32 = x3::byte_(0xdb);
  74. const auto mp_array16 = x3::byte_(0xdc);
  75. const auto mp_array32 = x3::byte_(0xdd);
  76. const auto mp_map16 = x3::byte_(0xde);
  77. const auto mp_map32 = x3::byte_(0xdf);
  78. const auto mp_negative_fixint = byte_range(0xe0, 0xff);
  79. const auto mp_d_uint8 = x3::byte_;
  80. const auto mp_d_uint16 = x3::big_word;
  81. const auto mp_d_uint32 = x3::big_dword;
  82. const auto mp_d_uint64 = x3::big_qword;
  83. const auto mp_d_int8 = x3::byte_;
  84. const auto mp_d_int16 = x3::big_word;
  85. const auto mp_d_int32 = x3::big_dword;
  86. const auto mp_d_int64 = x3::big_qword;
  87. x3::rule<class mp_object> const mp_object("mp_object");
  88. x3::rule<class array_items> const array_item("array_item");
  89. x3::rule<class map_items> const map_item("map_item");
  90. x3::rule<class kv> const kv("kv");
  91. struct tag_app_specific {};
  92. struct index_size {
  93. enum struct type_t {
  94. array,
  95. map,
  96. other
  97. };
  98. index_size(std::size_t size, type_t type = type_t::other):size(size), type(type) {}
  99. std::size_t index = 0;
  100. std::size_t size;
  101. type_t type;
  102. };
  103. template <typename Visitor>
  104. struct app_specific {
  105. template <typename Vis>
  106. app_specific(Vis&& vis):vis(vis) {}
  107. std::vector<index_size> index_sizes;
  108. Visitor vis;
  109. };
  110. template <typename Visitor>
  111. app_specific<Visitor> make_app_specific(Visitor&& vis) {
  112. return app_specific<Visitor>(std::forward<Visitor>(vis));
  113. }
  114. const auto more = [](auto &ctx) {
  115. auto& app_specific = x3::get<tag_app_specific>(ctx).get();
  116. _pass(ctx) = app_specific.index_sizes.back().index++ < app_specific.index_sizes.back().size;
  117. };
  118. const auto done = [](auto &ctx) {
  119. auto& app_specific = x3::get<tag_app_specific>(ctx).get();
  120. if (app_specific.index_sizes.back().index == app_specific.index_sizes.back().size + 1) {
  121. _pass(ctx) = true;
  122. switch (app_specific.index_sizes.back().type) {
  123. case index_size::type_t::array:
  124. app_specific.vis.end_array();
  125. break;
  126. case index_size::type_t::map:
  127. app_specific.vis.end_map();
  128. break;
  129. case index_size::type_t::other:
  130. break;
  131. }
  132. app_specific.index_sizes.pop_back();
  133. }
  134. else {
  135. _pass(ctx) = false;
  136. }
  137. };
  138. const auto mp_object_def =
  139. // -----------------------------------------------
  140. mp_nil [
  141. (
  142. [](auto& ctx){
  143. auto& app_specific = x3::get<tag_app_specific>(ctx).get();
  144. app_specific.vis.visit_nil();
  145. }
  146. )
  147. ]
  148. |
  149. // -----------------------------------------------
  150. mp_true [
  151. (
  152. [](auto& ctx){
  153. auto& app_specific = x3::get<tag_app_specific>(ctx).get();
  154. app_specific.vis.visit_boolean(true);
  155. }
  156. )
  157. ]
  158. |
  159. // -----------------------------------------------
  160. mp_false [
  161. (
  162. [](auto& ctx){
  163. auto& app_specific = x3::get<tag_app_specific>(ctx).get();
  164. app_specific.vis.visit_boolean(false);
  165. }
  166. )
  167. ]
  168. |
  169. // -----------------------------------------------
  170. mp_positive_fixint [
  171. (
  172. [](auto& ctx){
  173. auto& app_specific = x3::get<tag_app_specific>(ctx).get();
  174. app_specific.vis.visit_positive_integer(_attr(ctx));
  175. }
  176. )
  177. ]
  178. |
  179. // -----------------------------------------------
  180. mp_negative_fixint [
  181. (
  182. [](auto& ctx){
  183. auto& app_specific = x3::get<tag_app_specific>(ctx).get();
  184. std::int8_t val = static_cast<std::int8_t>(_attr(ctx));
  185. app_specific.vis.visit_negative_integer(val);
  186. }
  187. )
  188. ]
  189. |
  190. // -----------------------------------------------
  191. mp_uint8 >> mp_d_uint8 [
  192. (
  193. [](auto& ctx){
  194. auto& app_specific = x3::get<tag_app_specific>(ctx).get();
  195. app_specific.vis.visit_negative_integer(_attr(ctx));
  196. }
  197. )
  198. ]
  199. |
  200. // -----------------------------------------------
  201. mp_uint16 >> mp_d_uint16 [
  202. (
  203. [](auto& ctx){
  204. auto& app_specific = x3::get<tag_app_specific>(ctx).get();
  205. app_specific.vis.visit_positive_integer(_attr(ctx));
  206. }
  207. )
  208. ]
  209. |
  210. // -----------------------------------------------
  211. mp_uint32 >> mp_d_uint32 [
  212. (
  213. [](auto& ctx){
  214. auto& app_specific = x3::get<tag_app_specific>(ctx).get();
  215. app_specific.vis.visit_positive_integer(_attr(ctx));
  216. }
  217. )
  218. ]
  219. |
  220. // -----------------------------------------------
  221. mp_uint64 >> mp_d_uint64 [
  222. (
  223. [](auto& ctx){
  224. auto& app_specific = x3::get<tag_app_specific>(ctx).get();
  225. app_specific.vis.visit_positive_integer(_attr(ctx));
  226. }
  227. )
  228. ]
  229. |
  230. // -----------------------------------------------
  231. mp_int8 >> mp_d_int8 [
  232. (
  233. [](auto& ctx){
  234. auto& app_specific = x3::get<tag_app_specific>(ctx).get();
  235. std::int8_t val = static_cast<std::int8_t>(_attr(ctx));
  236. app_specific.vis.visit_negative_integer(val);
  237. }
  238. )
  239. ]
  240. |
  241. // -----------------------------------------------
  242. mp_int16 >> mp_d_int16 [
  243. (
  244. [](auto& ctx){
  245. auto& app_specific = x3::get<tag_app_specific>(ctx).get();
  246. std::int16_t val = static_cast<std::int16_t>(_attr(ctx));
  247. app_specific.vis.visit_negative_integer(val);
  248. }
  249. )
  250. ]
  251. |
  252. // -----------------------------------------------
  253. mp_int32 >> mp_d_int32 [
  254. (
  255. [](auto& ctx){
  256. auto& app_specific = x3::get<tag_app_specific>(ctx).get();
  257. std::int32_t val = static_cast<std::int32_t>(_attr(ctx));
  258. app_specific.vis.visit_negative_integer(val);
  259. }
  260. )
  261. ]
  262. |
  263. // -----------------------------------------------
  264. mp_int64 >> mp_d_int64 [
  265. (
  266. [](auto& ctx){
  267. auto& app_specific = x3::get<tag_app_specific>(ctx).get();
  268. std::int64_t val = static_cast<std::int64_t>(_attr(ctx));
  269. app_specific.vis.visit_negative_integer(val);
  270. }
  271. )
  272. ]
  273. |
  274. // -----------------------------------------------
  275. mp_float32 >> mp_d_uint32 [
  276. (
  277. [](auto& ctx){
  278. auto& app_specific = x3::get<tag_app_specific>(ctx).get();
  279. union { uint32_t i; float f; } mem = { _attr(ctx) };
  280. app_specific.vis.visit_float32(mem.f);
  281. }
  282. )
  283. ]
  284. |
  285. // -----------------------------------------------
  286. mp_float64 >> mp_d_uint64 [
  287. (
  288. [](auto& ctx){
  289. auto& app_specific = x3::get<tag_app_specific>(ctx).get();
  290. union { uint64_t i; double f; } mem = { _attr(ctx) };
  291. #if defined(TARGET_OS_IPHONE)
  292. // ok
  293. #elif defined(__arm__) && !(__ARM_EABI__) // arm-oabi
  294. // https://github.com/msgpack/msgpack-perl/pull/1
  295. mem.i = (mem.i & 0xFFFFFFFFUL) << 32UL | (mem.i >> 32UL);
  296. #endif
  297. app_specific.vis.visit_float64(mem.f);
  298. }
  299. )
  300. ]
  301. |
  302. // -----------------------------------------------
  303. mp_fixstr [
  304. (
  305. [](auto& ctx){
  306. auto& app_specific = x3::get<tag_app_specific>(ctx).get();
  307. std::size_t size = _attr(ctx) & 0b00011111;
  308. app_specific.index_sizes.emplace_back(size);
  309. }
  310. )
  311. ]
  312. >>
  313. x3::raw [
  314. *(x3::eps [more] >> x3::char_)
  315. >> x3::eps [done]
  316. ][
  317. (
  318. [](auto& ctx){
  319. auto& app_specific = x3::get<tag_app_specific>(ctx).get();
  320. auto const& str = _attr(ctx);
  321. auto size = static_cast<uint32_t>(std::distance(str.begin(), str.end()));
  322. app_specific.vis.visit_str(size ? &str.front() : nullptr, size);
  323. }
  324. )
  325. ]
  326. |
  327. // -----------------------------------------------
  328. mp_str8 >> mp_d_uint8 [
  329. (
  330. [](auto& ctx){
  331. auto& app_specific = x3::get<tag_app_specific>(ctx).get();
  332. app_specific.index_sizes.emplace_back(_attr(ctx));
  333. }
  334. )
  335. ]
  336. >>
  337. x3::raw [
  338. *(x3::eps [more] >> x3::char_)
  339. >> x3::eps [done]
  340. ][
  341. (
  342. [](auto& ctx){
  343. auto& app_specific = x3::get<tag_app_specific>(ctx).get();
  344. auto const& str = _attr(ctx);
  345. auto size = static_cast<uint32_t>(std::distance(str.begin(), str.end()));
  346. app_specific.vis.visit_str(size ? &str.front() : nullptr, size);
  347. }
  348. )
  349. ]
  350. |
  351. // -----------------------------------------------
  352. mp_str16 >> mp_d_uint16 [
  353. (
  354. [](auto& ctx){
  355. auto& app_specific = x3::get<tag_app_specific>(ctx).get();
  356. app_specific.index_sizes.emplace_back(_attr(ctx));
  357. }
  358. )
  359. ]
  360. >>
  361. x3::raw [
  362. *(x3::eps [more] >> x3::char_)
  363. >> x3::eps [done]
  364. ][
  365. (
  366. [](auto& ctx){
  367. auto& app_specific = x3::get<tag_app_specific>(ctx).get();
  368. auto const& str = _attr(ctx);
  369. auto size = static_cast<uint32_t>(std::distance(str.begin(), str.end()));
  370. app_specific.vis.visit_str(size ? &str.front() : nullptr, size);
  371. }
  372. )
  373. ]
  374. |
  375. // -----------------------------------------------
  376. mp_str32 >> mp_d_uint32 [
  377. (
  378. [](auto& ctx){
  379. auto& app_specific = x3::get<tag_app_specific>(ctx).get();
  380. app_specific.index_sizes.emplace_back(_attr(ctx));
  381. }
  382. )
  383. ]
  384. >>
  385. x3::raw [
  386. *(x3::eps [more] >> x3::char_)
  387. >> x3::eps [done]
  388. ][
  389. (
  390. [](auto& ctx){
  391. auto& app_specific = x3::get<tag_app_specific>(ctx).get();
  392. auto const& str = _attr(ctx);
  393. auto size = static_cast<uint32_t>(std::distance(str.begin(), str.end()));
  394. app_specific.vis.visit_str(size ? &str.front() : nullptr, size);
  395. }
  396. )
  397. ]
  398. |
  399. // -----------------------------------------------
  400. mp_bin8 >> mp_d_uint8 [
  401. (
  402. [](auto& ctx){
  403. auto& app_specific = x3::get<tag_app_specific>(ctx).get();
  404. app_specific.index_sizes.emplace_back(_attr(ctx));
  405. }
  406. )
  407. ]
  408. >>
  409. x3::raw [
  410. *(x3::eps [more] >> x3::char_)
  411. >> x3::eps [done]
  412. ][
  413. (
  414. [](auto& ctx){
  415. auto& app_specific = x3::get<tag_app_specific>(ctx).get();
  416. auto const& bin = _attr(ctx);
  417. auto size = static_cast<uint32_t>(std::distance(bin.begin(), bin.end()));
  418. app_specific.vis.visit_bin(size ? &bin.front() : nullptr, size);
  419. }
  420. )
  421. ]
  422. |
  423. // -----------------------------------------------
  424. mp_bin16 >> mp_d_uint16 [
  425. (
  426. [](auto& ctx){
  427. auto& app_specific = x3::get<tag_app_specific>(ctx).get();
  428. app_specific.index_sizes.emplace_back(_attr(ctx));
  429. }
  430. )
  431. ]
  432. >>
  433. x3::raw [
  434. *(x3::eps [more] >> x3::char_)
  435. >> x3::eps [done]
  436. ][
  437. (
  438. [](auto& ctx){
  439. auto& app_specific = x3::get<tag_app_specific>(ctx).get();
  440. auto const& bin = _attr(ctx);
  441. auto size = static_cast<uint32_t>(std::distance(bin.begin(), bin.end()));
  442. app_specific.vis.visit_bin(size ? &bin.front() : nullptr, size);
  443. }
  444. )
  445. ]
  446. |
  447. // -----------------------------------------------
  448. mp_bin32 >> mp_d_uint32 [
  449. (
  450. [](auto& ctx){
  451. auto& app_specific = x3::get<tag_app_specific>(ctx).get();
  452. app_specific.index_sizes.emplace_back(_attr(ctx));
  453. }
  454. )
  455. ]
  456. >>
  457. x3::raw [
  458. *(x3::eps [more] >> x3::char_)
  459. >> x3::eps [done]
  460. ][
  461. (
  462. [](auto& ctx){
  463. auto& app_specific = x3::get<tag_app_specific>(ctx).get();
  464. auto const& bin = _attr(ctx);
  465. auto size = static_cast<uint32_t>(std::distance(bin.begin(), bin.end()));
  466. app_specific.vis.visit_bin(size ? &bin.front() : nullptr, size);
  467. }
  468. )
  469. ]
  470. |
  471. // -----------------------------------------------
  472. mp_fixarray [
  473. (
  474. [](auto& ctx){
  475. auto& app_specific = x3::get<tag_app_specific>(ctx).get();
  476. uint32_t size = _attr(ctx) & 0b00001111;
  477. app_specific.index_sizes.emplace_back(size, index_size::type_t::array);
  478. app_specific.vis.start_array(size);
  479. }
  480. )
  481. ]
  482. >> *(x3::eps [more] >> array_item)
  483. >> x3::eps [done]
  484. |
  485. // -----------------------------------------------
  486. mp_array16 >> mp_d_uint16 [
  487. (
  488. [](auto& ctx){
  489. auto& app_specific = x3::get<tag_app_specific>(ctx).get();
  490. uint32_t size = _attr(ctx);
  491. app_specific.index_sizes.emplace_back(size, index_size::type_t::array);
  492. app_specific.vis.start_array(size);
  493. }
  494. )
  495. ]
  496. >> *(x3::eps [more] >> array_item)
  497. >> x3::eps [done]
  498. |
  499. // -----------------------------------------------
  500. mp_array32 >> mp_d_uint32 [
  501. (
  502. [](auto& ctx){
  503. auto& app_specific = x3::get<tag_app_specific>(ctx).get();
  504. uint32_t size = _attr(ctx);
  505. app_specific.index_sizes.emplace_back(size, index_size::type_t::array);
  506. app_specific.vis.start_array(size);
  507. }
  508. )
  509. ]
  510. >> *(x3::eps [more] >> array_item)
  511. >> x3::eps [done]
  512. |
  513. // -----------------------------------------------
  514. mp_fixmap [
  515. (
  516. [](auto& ctx){
  517. auto& app_specific = x3::get<tag_app_specific>(ctx).get();
  518. uint32_t size = _attr(ctx) & 0b00001111;
  519. app_specific.index_sizes.emplace_back(size, index_size::type_t::map);
  520. app_specific.vis.start_map(size);
  521. }
  522. )
  523. ]
  524. >> *(x3::eps [more] >> map_item)
  525. >> x3::eps [done]
  526. |
  527. // -----------------------------------------------
  528. mp_map16 >> mp_d_uint16 [
  529. (
  530. [](auto& ctx){
  531. auto& app_specific = x3::get<tag_app_specific>(ctx).get();
  532. uint32_t size = _attr(ctx);
  533. app_specific.index_sizes.emplace_back(size, index_size::type_t::map);
  534. app_specific.vis.start_map(size);
  535. }
  536. )
  537. ]
  538. >> *(x3::eps [more] >> map_item)
  539. >> x3::eps [done]
  540. |
  541. // -----------------------------------------------
  542. mp_map32 >> mp_d_uint32 [
  543. (
  544. [](auto& ctx){
  545. auto& app_specific = x3::get<tag_app_specific>(ctx).get();
  546. uint32_t size = _attr(ctx);
  547. app_specific.index_sizes.emplace_back(size, index_size::type_t::map);
  548. app_specific.vis.start_map(size);
  549. }
  550. )
  551. ]
  552. >> *(x3::eps [more] >> map_item)
  553. >> x3::eps [done]
  554. |
  555. // -----------------------------------------------
  556. mp_fixext1 [
  557. (
  558. [](auto& ctx){
  559. auto& app_specific = x3::get<tag_app_specific>(ctx).get();
  560. app_specific.index_sizes.emplace_back(1+1);
  561. }
  562. )
  563. ]
  564. >>
  565. x3::raw [
  566. *(x3::eps [more] >> x3::char_)
  567. >> x3::eps [done]
  568. ][
  569. (
  570. [](auto& ctx){
  571. auto& app_specific = x3::get<tag_app_specific>(ctx).get();
  572. auto const& ext = _attr(ctx);
  573. auto size = static_cast<uint32_t>(std::distance(ext.begin(), ext.end()));
  574. app_specific.vis.visit_ext(size ? &ext.front() : nullptr, size);
  575. }
  576. )
  577. ]
  578. |
  579. // -----------------------------------------------
  580. mp_fixext2 [
  581. (
  582. [](auto& ctx){
  583. auto& app_specific = x3::get<tag_app_specific>(ctx).get();
  584. app_specific.index_sizes.emplace_back(2+1);
  585. }
  586. )
  587. ]
  588. >>
  589. x3::raw [
  590. *(x3::eps [more] >> x3::char_)
  591. >> x3::eps [done]
  592. ][
  593. (
  594. [](auto& ctx){
  595. auto& app_specific = x3::get<tag_app_specific>(ctx).get();
  596. auto const& ext = _attr(ctx);
  597. auto size = static_cast<uint32_t>(std::distance(ext.begin(), ext.end()));
  598. app_specific.vis.visit_ext(size ? &ext.front() : nullptr, size);
  599. }
  600. )
  601. ]
  602. |
  603. // -----------------------------------------------
  604. mp_fixext4 [
  605. (
  606. [](auto& ctx){
  607. auto& app_specific = x3::get<tag_app_specific>(ctx).get();
  608. app_specific.index_sizes.emplace_back(4+1);
  609. }
  610. )
  611. ]
  612. >>
  613. x3::raw [
  614. *(x3::eps [more] >> x3::char_)
  615. >> x3::eps [done]
  616. ][
  617. (
  618. [](auto& ctx){
  619. auto& app_specific = x3::get<tag_app_specific>(ctx).get();
  620. auto const& ext = _attr(ctx);
  621. auto size = static_cast<uint32_t>(std::distance(ext.begin(), ext.end()));
  622. app_specific.vis.visit_ext(size ? &ext.front() : nullptr, size);
  623. }
  624. )
  625. ]
  626. |
  627. // -----------------------------------------------
  628. mp_fixext8 [
  629. (
  630. [](auto& ctx){
  631. auto& app_specific = x3::get<tag_app_specific>(ctx).get();
  632. app_specific.index_sizes.emplace_back(8+1);
  633. }
  634. )
  635. ]
  636. >>
  637. x3::raw [
  638. *(x3::eps [more] >> x3::char_)
  639. >> x3::eps [done]
  640. ][
  641. (
  642. [](auto& ctx){
  643. auto& app_specific = x3::get<tag_app_specific>(ctx).get();
  644. auto const& ext = _attr(ctx);
  645. auto size = static_cast<uint32_t>(std::distance(ext.begin(), ext.end()));
  646. app_specific.vis.visit_ext(size ? &ext.front() : nullptr, size);
  647. }
  648. )
  649. ]
  650. |
  651. // -----------------------------------------------
  652. mp_fixext16 [
  653. (
  654. [](auto& ctx){
  655. auto& app_specific = x3::get<tag_app_specific>(ctx).get();
  656. app_specific.index_sizes.emplace_back(16+1);
  657. }
  658. )
  659. ]
  660. >>
  661. x3::raw [
  662. *(x3::eps [more] >> x3::char_)
  663. >> x3::eps [done]
  664. ][
  665. (
  666. [](auto& ctx){
  667. auto& app_specific = x3::get<tag_app_specific>(ctx).get();
  668. auto const& ext = _attr(ctx);
  669. auto size = static_cast<uint32_t>(std::distance(ext.begin(), ext.end()));
  670. app_specific.vis.visit_ext(size ? &ext.front() : nullptr, size);
  671. }
  672. )
  673. ]
  674. |
  675. // -----------------------------------------------
  676. mp_ext8 >> mp_d_uint8 [
  677. (
  678. [](auto& ctx){
  679. auto& app_specific = x3::get<tag_app_specific>(ctx).get();
  680. app_specific.index_sizes.emplace_back(_attr(ctx)+1);
  681. }
  682. )
  683. ]
  684. >>
  685. x3::raw [
  686. *(x3::eps [more] >> x3::char_)
  687. >> x3::eps [done]
  688. ][
  689. (
  690. [](auto& ctx){
  691. auto& app_specific = x3::get<tag_app_specific>(ctx).get();
  692. auto const& ext = _attr(ctx);
  693. auto size = static_cast<uint32_t>(std::distance(ext.begin(), ext.end()));
  694. app_specific.vis.visit_ext(size ? &ext.front() : nullptr, size);
  695. }
  696. )
  697. ]
  698. |
  699. // -----------------------------------------------
  700. mp_ext16 >> mp_d_uint16 [
  701. (
  702. [](auto& ctx){
  703. auto& app_specific = x3::get<tag_app_specific>(ctx).get();
  704. app_specific.index_sizes.emplace_back(_attr(ctx)+1);
  705. }
  706. )
  707. ]
  708. >>
  709. x3::raw [
  710. *(x3::eps [more] >> x3::char_)
  711. >> x3::eps [done]
  712. ][
  713. (
  714. [](auto& ctx){
  715. auto& app_specific = x3::get<tag_app_specific>(ctx).get();
  716. auto const& ext = _attr(ctx);
  717. auto size = static_cast<uint32_t>(std::distance(ext.begin(), ext.end()));
  718. app_specific.vis.visit_ext(size ? &ext.front() : nullptr, size);
  719. }
  720. )
  721. ]
  722. |
  723. // -----------------------------------------------
  724. mp_ext32 >> mp_d_uint32 [
  725. (
  726. [](auto& ctx){
  727. auto& app_specific = x3::get<tag_app_specific>(ctx).get();
  728. app_specific.index_sizes.emplace_back(_attr(ctx)+1);
  729. }
  730. )
  731. ]
  732. >>
  733. x3::raw [
  734. *(x3::eps [more] >> x3::char_)
  735. >> x3::eps [done]
  736. ][
  737. (
  738. [](auto& ctx){
  739. auto& app_specific = x3::get<tag_app_specific>(ctx).get();
  740. auto const& ext = _attr(ctx);
  741. auto size = static_cast<uint32_t>(std::distance(ext.begin(), ext.end()));
  742. app_specific.vis.visit_ext(size ? &ext.front() : nullptr, size);
  743. }
  744. )
  745. ];
  746. const auto array_item_def =
  747. x3::eps[
  748. (
  749. [](auto& ctx){
  750. auto& app_specific = x3::get<tag_app_specific>(ctx).get();
  751. app_specific.vis.start_array_item();
  752. _pass(ctx) = true;
  753. }
  754. )
  755. ]
  756. >>
  757. mp_object
  758. >>
  759. x3::eps[
  760. (
  761. [](auto& ctx){
  762. auto& app_specific = x3::get<tag_app_specific>(ctx).get();
  763. app_specific.vis.end_array_item();
  764. _pass(ctx) = true;
  765. }
  766. )
  767. ];
  768. const auto map_item_def = kv;
  769. const auto kv_def =
  770. x3::eps[
  771. (
  772. [](auto& ctx){
  773. auto& app_specific = x3::get<tag_app_specific>(ctx).get();
  774. app_specific.vis.start_map_key();
  775. _pass(ctx) = true;
  776. }
  777. )
  778. ]
  779. >>
  780. mp_object
  781. >>
  782. x3::eps[
  783. (
  784. [](auto& ctx){
  785. auto& app_specific = x3::get<tag_app_specific>(ctx).get();
  786. app_specific.vis.end_map_key();
  787. _pass(ctx) = true;
  788. }
  789. )
  790. ]
  791. >>
  792. x3::eps[
  793. (
  794. [](auto& ctx){
  795. auto& app_specific = x3::get<tag_app_specific>(ctx).get();
  796. app_specific.vis.start_map_value();
  797. _pass(ctx) = true;
  798. }
  799. )
  800. ]
  801. >>
  802. mp_object
  803. >>
  804. x3::eps[
  805. (
  806. [](auto& ctx){
  807. auto& app_specific = x3::get<tag_app_specific>(ctx).get();
  808. app_specific.vis.end_map_value();
  809. _pass(ctx) = true;
  810. }
  811. )
  812. ];
  813. BOOST_SPIRIT_DEFINE(
  814. mp_object, array_item, map_item, kv
  815. );
  816. const auto rule = mp_object;
  817. } // namespace detail
  818. template <typename Iterator, typename Visitor>
  819. inline bool parse(Iterator&& begin, Iterator&& end, Visitor&& vis) {
  820. auto data = detail::make_app_specific(std::forward<Visitor>(vis));
  821. return detail::x3::parse(
  822. std::forward<Iterator>(begin),
  823. std::forward<Iterator>(end),
  824. detail::x3::with<detail::tag_app_specific>(std::ref(data))[detail::rule]
  825. );
  826. }
  827. /// @cond
  828. } // MSGPACK_API_VERSION_NAMESPACE(v2)
  829. /// @endcond
  830. } // namespace msgpack
  831. #if __GNUC__ >= 4
  832. #pragma GCC diagnostic pop
  833. #endif // __GNUC__ >= 4
  834. #else // BOOST_VERSION >= 106100
  835. #error Boost 1.61.0 or later is required to use x3 parse
  836. #endif // BOOST_VERSION >= 106100
  837. #endif // defined(MSGPACK_USE_X3_PARSE)
  838. #endif // MSGPACK_V2_X3_PARSE_HPP