10 #ifndef MSGPACK_V2_X3_PARSE_HPP 11 #define MSGPACK_V2_X3_PARSE_HPP 13 #if defined(MSGPACK_USE_X3_PARSE) 15 #include <boost/version.hpp> 17 #if BOOST_VERSION >= 106100 22 #pragma GCC diagnostic push 23 #pragma GCC diagnostic ignored "-Wunused-parameter" 24 #endif // __GNUC__ >= 4 26 #include <boost/config/warning_disable.hpp> 27 #include <boost/spirit/home/x3.hpp> 28 #include <boost/spirit/home/x3/binary.hpp> 38 namespace x3 = boost::spirit::x3;
43 const auto byte_range = [](
const std::uint8_t from,
const std::uint8_t to) {
44 const auto check = [from, to](
auto& ctx)
46 const std::uint8_t value = x3::_attr(ctx);
47 x3::_val(ctx) = value;
48 x3::_pass(ctx) = from <= value && value <= to;
50 return x3::byte_ [check];
54 const auto mp_positive_fixint = byte_range(0x00, 0x7f);
55 const auto mp_fixmap = byte_range(0x80, 0x8f);
56 const auto mp_fixarray = byte_range(0x90, 0x9f);
57 const auto mp_fixstr = byte_range(0xa0, 0xbf);
58 const auto mp_nil = x3::byte_(0xc0);
59 const auto mp_false = x3::byte_(0xc2);
60 const auto mp_true = x3::byte_(0xc3);
61 const auto mp_bin8 = x3::byte_(0xc4);
62 const auto mp_bin16 = x3::byte_(0xc5);
63 const auto mp_bin32 = x3::byte_(0xc6);
64 const auto mp_ext8 = x3::byte_(0xc7);
65 const auto mp_ext16 = x3::byte_(0xc8);
66 const auto mp_ext32 = x3::byte_(0xc9);
67 const auto mp_float32 = x3::byte_(0xca);
68 const auto mp_float64 = x3::byte_(0xcb);
69 const auto mp_uint8 = x3::byte_(0xcc);
70 const auto mp_uint16 = x3::byte_(0xcd);
71 const auto mp_uint32 = x3::byte_(0xce);
72 const auto mp_uint64 = x3::byte_(0xcf);
73 const auto mp_int8 = x3::byte_(0xd0);
74 const auto mp_int16 = x3::byte_(0xd1);
75 const auto mp_int32 = x3::byte_(0xd2);
76 const auto mp_int64 = x3::byte_(0xd3);
77 const auto mp_fixext1 = x3::byte_(0xd4);
78 const auto mp_fixext2 = x3::byte_(0xd5);
79 const auto mp_fixext4 = x3::byte_(0xd6);
80 const auto mp_fixext8 = x3::byte_(0xd7);
81 const auto mp_fixext16 = x3::byte_(0xd8);
82 const auto mp_str8 = x3::byte_(0xd9);
83 const auto mp_str16 = x3::byte_(0xda);
84 const auto mp_str32 = x3::byte_(0xdb);
85 const auto mp_array16 = x3::byte_(0xdc);
86 const auto mp_array32 = x3::byte_(0xdd);
87 const auto mp_map16 = x3::byte_(0xde);
88 const auto mp_map32 = x3::byte_(0xdf);
89 const auto mp_negative_fixint = byte_range(0xe0, 0xff);
91 const auto mp_d_uint8 = x3::byte_;
92 const auto mp_d_uint16 = x3::big_word;
93 const auto mp_d_uint32 = x3::big_dword;
94 const auto mp_d_uint64 = x3::big_qword;
96 const auto mp_d_int8 = x3::byte_;
97 const auto mp_d_int16 = x3::big_word;
98 const auto mp_d_int32 = x3::big_dword;
99 const auto mp_d_int64 = x3::big_qword;
101 x3::rule<class mp_object>
const mp_object(
"mp_object");
102 x3::rule<class array_items>
const array_item(
"array_item");
103 x3::rule<class map_items>
const map_item(
"map_item");
104 x3::rule<class kv>
const kv(
"kv");
106 struct tag_app_specific {};
113 index_size(std::size_t
size, type_t type = type_t::other):size(size), type(type) {}
114 std::size_t index = 0;
119 template <
typename Visitor>
120 struct app_specific {
121 template <
typename Vis>
122 app_specific(Vis&& vis):vis(vis) {}
123 std::vector<index_size> index_sizes;
127 template <
typename Visitor>
128 app_specific<Visitor> make_app_specific(Visitor&& vis) {
129 return app_specific<Visitor>(std::forward<Visitor>(vis));
132 const auto more = [](
auto &ctx) {
133 auto& app_specific = x3::get<tag_app_specific>(ctx).
get();
134 _pass(ctx) = app_specific.index_sizes.back().index++ < app_specific.index_sizes.back().size;
137 const auto done = [](
auto &ctx) {
138 auto& app_specific = x3::get<tag_app_specific>(ctx).
get();
139 if (app_specific.index_sizes.back().index == app_specific.index_sizes.back().size + 1) {
141 switch (app_specific.index_sizes.back().type) {
142 case index_size::type_t::array:
143 app_specific.vis.end_array();
145 case index_size::type_t::map:
146 app_specific.vis.end_map();
148 case index_size::type_t::other:
151 app_specific.index_sizes.pop_back();
158 const auto mp_object_def =
163 auto& app_specific = x3::get<tag_app_specific>(ctx).
get();
164 app_specific.vis.visit_nil();
173 auto& app_specific = x3::get<tag_app_specific>(ctx).
get();
174 app_specific.vis.visit_boolean(
true);
183 auto& app_specific = x3::get<tag_app_specific>(ctx).
get();
184 app_specific.vis.visit_boolean(
false);
193 auto& app_specific = x3::get<tag_app_specific>(ctx).
get();
194 app_specific.vis.visit_positive_integer(_attr(ctx));
203 auto& app_specific = x3::get<tag_app_specific>(ctx).
get();
204 std::int8_t val = _attr(ctx);
205 app_specific.vis.visit_negative_integer(val);
211 mp_uint8 >> mp_d_uint8 [
214 auto& app_specific = x3::get<tag_app_specific>(ctx).
get();
215 app_specific.vis.visit_negative_integer(_attr(ctx));
221 mp_uint16 >> mp_d_uint16 [
224 auto& app_specific = x3::get<tag_app_specific>(ctx).
get();
225 app_specific.vis.visit_positive_integer(_attr(ctx));
231 mp_uint32 >> mp_d_uint32 [
234 auto& app_specific = x3::get<tag_app_specific>(ctx).
get();
235 app_specific.vis.visit_positive_integer(_attr(ctx));
241 mp_uint64 >> mp_d_uint64 [
244 auto& app_specific = x3::get<tag_app_specific>(ctx).
get();
245 app_specific.vis.visit_positive_integer(_attr(ctx));
251 mp_int8 >> mp_d_int8 [
254 auto& app_specific = x3::get<tag_app_specific>(ctx).
get();
255 std::int8_t val = _attr(ctx);
256 app_specific.vis.visit_negative_integer(val);
262 mp_int16 >> mp_d_int16 [
265 auto& app_specific = x3::get<tag_app_specific>(ctx).
get();
266 std::int16_t val = _attr(ctx);
267 app_specific.vis.visit_negative_integer(val);
273 mp_int32 >> mp_d_int32 [
276 auto& app_specific = x3::get<tag_app_specific>(ctx).
get();
277 std::int32_t val = _attr(ctx);
278 app_specific.vis.visit_negative_integer(val);
284 mp_int64 >> mp_d_int64 [
287 auto& app_specific = x3::get<tag_app_specific>(ctx).
get();
288 std::int64_t val = _attr(ctx);
289 app_specific.vis.visit_negative_integer(val);
295 mp_float32 >> mp_d_uint32 [
298 auto& app_specific = x3::get<tag_app_specific>(ctx).
get();
299 union { uint32_t i;
float f; } mem;
301 app_specific.vis.visit_float(mem.f);
307 mp_float64 >> mp_d_uint64 [
310 auto& app_specific = x3::get<tag_app_specific>(ctx).
get();
311 union { uint64_t i;
double f; } mem;
313 #if defined(TARGET_OS_IPHONE) 315 #elif defined(__arm__) && !(__ARM_EABI__) // arm-oabi 317 mem.i = (mem.i & 0xFFFFFFFFUL) << 32UL | (mem.i >> 32UL);
319 app_specific.vis.visit_float(mem.f);
328 auto& app_specific = x3::get<tag_app_specific>(ctx).
get();
329 std::size_t
size = _attr(ctx) & 0b00011111;
330 app_specific.index_sizes.emplace_back(size);
336 *(x3::eps [more] >> x3::char_)
341 auto& app_specific = x3::get<tag_app_specific>(ctx).
get();
342 auto const& str = _attr(ctx);
343 std::size_t size = std::distance(str.begin(), str.end());
344 app_specific.vis.visit_str(size ? &str.front() :
nullptr,
size);
350 mp_str8 >> mp_d_uint8 [
353 auto& app_specific = x3::get<tag_app_specific>(ctx).
get();
354 app_specific.index_sizes.emplace_back(_attr(ctx));
360 *(x3::eps [more] >> x3::char_)
365 auto& app_specific = x3::get<tag_app_specific>(ctx).
get();
366 auto const& str = _attr(ctx);
367 std::size_t size = std::distance(str.begin(), str.end());
368 app_specific.vis.visit_str(size ? &str.front() :
nullptr,
size);
374 mp_str16 >> mp_d_uint16 [
377 auto& app_specific = x3::get<tag_app_specific>(ctx).
get();
378 app_specific.index_sizes.emplace_back(_attr(ctx));
384 *(x3::eps [more] >> x3::char_)
389 auto& app_specific = x3::get<tag_app_specific>(ctx).
get();
390 auto const& str = _attr(ctx);
391 std::size_t size = std::distance(str.begin(), str.end());
392 app_specific.vis.visit_str(size ? &str.front() :
nullptr,
size);
398 mp_str32 >> mp_d_uint32 [
401 auto& app_specific = x3::get<tag_app_specific>(ctx).
get();
402 app_specific.index_sizes.emplace_back(_attr(ctx));
408 *(x3::eps [more] >> x3::char_)
413 auto& app_specific = x3::get<tag_app_specific>(ctx).
get();
414 auto const& str = _attr(ctx);
415 std::size_t size = std::distance(str.begin(), str.end());
416 app_specific.vis.visit_str(size ? &str.front() :
nullptr,
size);
422 mp_bin8 >> mp_d_uint8 [
425 auto& app_specific = x3::get<tag_app_specific>(ctx).
get();
426 app_specific.index_sizes.emplace_back(_attr(ctx));
432 *(x3::eps [more] >> x3::char_)
437 auto& app_specific = x3::get<tag_app_specific>(ctx).
get();
438 auto const& bin = _attr(ctx);
439 std::size_t size = std::distance(bin.begin(), bin.end());
440 app_specific.vis.visit_bin(size ? &bin.front() :
nullptr,
size);
446 mp_bin16 >> mp_d_uint16 [
449 auto& app_specific = x3::get<tag_app_specific>(ctx).
get();
450 app_specific.index_sizes.emplace_back(_attr(ctx));
456 *(x3::eps [more] >> x3::char_)
461 auto& app_specific = x3::get<tag_app_specific>(ctx).
get();
462 auto const& bin = _attr(ctx);
463 std::size_t size = std::distance(bin.begin(), bin.end());
464 app_specific.vis.visit_bin(size ? &bin.front() :
nullptr,
size);
470 mp_bin32 >> mp_d_uint32 [
473 auto& app_specific = x3::get<tag_app_specific>(ctx).
get();
474 app_specific.index_sizes.emplace_back(_attr(ctx));
480 *(x3::eps [more] >> x3::char_)
485 auto& app_specific = x3::get<tag_app_specific>(ctx).
get();
486 auto const& bin = _attr(ctx);
487 std::size_t size = std::distance(bin.begin(), bin.end());
488 app_specific.vis.visit_bin(size ? &bin.front() :
nullptr,
size);
497 auto& app_specific = x3::get<tag_app_specific>(ctx).
get();
498 std::size_t size = _attr(ctx) & 0b00001111;
499 app_specific.index_sizes.emplace_back(size, index_size::type_t::array);
500 app_specific.vis.start_array(size);
504 >> *(x3::eps [more] >> array_item)
508 mp_array16 >> mp_d_uint16 [
511 auto& app_specific = x3::get<tag_app_specific>(ctx).
get();
512 std::size_t size = _attr(ctx);
513 app_specific.index_sizes.emplace_back(size, index_size::type_t::array);
514 app_specific.vis.start_array(size);
518 >> *(x3::eps [more] >> array_item)
522 mp_array32 >> mp_d_uint32 [
525 auto& app_specific = x3::get<tag_app_specific>(ctx).
get();
526 std::size_t size = _attr(ctx);
527 app_specific.index_sizes.emplace_back(size, index_size::type_t::array);
528 app_specific.vis.start_array(size);
532 >> *(x3::eps [more] >> array_item)
539 auto& app_specific = x3::get<tag_app_specific>(ctx).
get();
540 std::size_t size = _attr(ctx) & 0b00001111;
541 app_specific.index_sizes.emplace_back(size, index_size::type_t::map);
542 app_specific.vis.start_map(size);
546 >> *(x3::eps [more] >> map_item)
550 mp_map16 >> mp_d_uint16 [
553 auto& app_specific = x3::get<tag_app_specific>(ctx).
get();
554 std::size_t size = _attr(ctx);
555 app_specific.index_sizes.emplace_back(size, index_size::type_t::map);
556 app_specific.vis.start_map(size);
560 >> *(x3::eps [more] >> map_item)
564 mp_map32 >> mp_d_uint32 [
567 auto& app_specific = x3::get<tag_app_specific>(ctx).
get();
568 std::size_t size = _attr(ctx);
569 app_specific.index_sizes.emplace_back(size, index_size::type_t::map);
570 app_specific.vis.start_map(size);
574 >> *(x3::eps [more] >> map_item)
581 auto& app_specific = x3::get<tag_app_specific>(ctx).
get();
582 app_specific.index_sizes.emplace_back(1+1);
588 *(x3::eps [more] >> x3::char_)
593 auto& app_specific = x3::get<tag_app_specific>(ctx).
get();
594 auto const& ext = _attr(ctx);
595 std::size_t size = std::distance(ext.begin(), ext.end());
596 app_specific.vis.visit_ext(size ? &ext.front() :
nullptr,
size);
605 auto& app_specific = x3::get<tag_app_specific>(ctx).
get();
606 app_specific.index_sizes.emplace_back(2+1);
612 *(x3::eps [more] >> x3::char_)
617 auto& app_specific = x3::get<tag_app_specific>(ctx).
get();
618 auto const& ext = _attr(ctx);
619 std::size_t size = std::distance(ext.begin(), ext.end());
620 app_specific.vis.visit_ext(size ? &ext.front() :
nullptr,
size);
629 auto& app_specific = x3::get<tag_app_specific>(ctx).
get();
630 app_specific.index_sizes.emplace_back(4+1);
636 *(x3::eps [more] >> x3::char_)
641 auto& app_specific = x3::get<tag_app_specific>(ctx).
get();
642 auto const& ext = _attr(ctx);
643 std::size_t size = std::distance(ext.begin(), ext.end());
644 app_specific.vis.visit_ext(size ? &ext.front() :
nullptr,
size);
653 auto& app_specific = x3::get<tag_app_specific>(ctx).
get();
654 app_specific.index_sizes.emplace_back(8+1);
660 *(x3::eps [more] >> x3::char_)
665 auto& app_specific = x3::get<tag_app_specific>(ctx).
get();
666 auto const& ext = _attr(ctx);
667 std::size_t size = std::distance(ext.begin(), ext.end());
668 app_specific.vis.visit_ext(size ? &ext.front() :
nullptr,
size);
677 auto& app_specific = x3::get<tag_app_specific>(ctx).
get();
678 app_specific.index_sizes.emplace_back(16+1);
684 *(x3::eps [more] >> x3::char_)
689 auto& app_specific = x3::get<tag_app_specific>(ctx).
get();
690 auto const& ext = _attr(ctx);
691 std::size_t size = std::distance(ext.begin(), ext.end());
692 app_specific.vis.visit_ext(size ? &ext.front() :
nullptr,
size);
698 mp_ext8 >> mp_d_uint8 [
701 auto& app_specific = x3::get<tag_app_specific>(ctx).
get();
702 app_specific.index_sizes.emplace_back(_attr(ctx)+1);
708 *(x3::eps [more] >> x3::char_)
713 auto& app_specific = x3::get<tag_app_specific>(ctx).
get();
714 auto const& ext = _attr(ctx);
715 std::size_t size = std::distance(ext.begin(), ext.end());
716 app_specific.vis.visit_ext(size ? &ext.front() :
nullptr,
size);
722 mp_ext16 >> mp_d_uint16 [
725 auto& app_specific = x3::get<tag_app_specific>(ctx).
get();
726 app_specific.index_sizes.emplace_back(_attr(ctx)+1);
732 *(x3::eps [more] >> x3::char_)
737 auto& app_specific = x3::get<tag_app_specific>(ctx).
get();
738 auto const& ext = _attr(ctx);
739 std::size_t size = std::distance(ext.begin(), ext.end());
740 app_specific.vis.visit_ext(size ? &ext.front() :
nullptr,
size);
746 mp_ext32 >> mp_d_uint32 [
749 auto& app_specific = x3::get<tag_app_specific>(ctx).
get();
750 app_specific.index_sizes.emplace_back(_attr(ctx)+1);
756 *(x3::eps [more] >> x3::char_)
761 auto& app_specific = x3::get<tag_app_specific>(ctx).
get();
762 auto const& ext = _attr(ctx);
763 std::size_t size = std::distance(ext.begin(), ext.end());
764 app_specific.vis.visit_ext(size ? &ext.front() :
nullptr,
size);
769 const auto array_item_def =
773 auto& app_specific = x3::get<tag_app_specific>(ctx).
get();
774 app_specific.vis.start_array_item();
785 auto& app_specific = x3::get<tag_app_specific>(ctx).
get();
786 app_specific.vis.end_array_item();
792 const auto map_item_def = kv;
797 auto& app_specific = x3::get<tag_app_specific>(ctx).
get();
798 app_specific.vis.start_map_key();
809 auto& app_specific = x3::get<tag_app_specific>(ctx).
get();
810 app_specific.vis.end_map_key();
819 auto& app_specific = x3::get<tag_app_specific>(ctx).
get();
820 app_specific.vis.start_map_value();
831 auto& app_specific = x3::get<tag_app_specific>(ctx).
get();
832 app_specific.vis.end_map_value();
839 mp_object, array_item, map_item, kv
842 const auto rule = mp_object;
846 template <
typename Iterator,
typename Visitor>
847 inline bool parse(Iterator&&
begin, Iterator&&
end, Visitor&& vis) {
848 auto data = detail::make_app_specific(std::forward<Visitor>(vis));
850 std::forward<Iterator>(
begin),
851 std::forward<Iterator>(
end),
852 detail::x3::with<detail::tag_app_specific>(std::ref(data))[detail::rule]
863 #pragma GCC diagnostic pop 864 #endif // __GNUC__ >= 4 866 #else // BOOST_VERSION >= 106100 868 #error Boost 1.61.0 or later is required to use x3 parse 870 #endif // BOOST_VERSION >= 106100 872 #endif // defined(MSGPACK_USE_X3_PARSE) 874 #endif // MSGPACK_V2_X3_PARSE_HPP msgpack::object_kv * begin(msgpack::object_map &map)
Definition: iterator.hpp:23
Definition: adaptor_base.hpp:15
msgpack::object_kv * end(msgpack::object_map &map)
Definition: iterator.hpp:25
std::size_t size(T const &t)
Definition: size_equal_only.hpp:24
bool parse(const char *data, size_t len, size_t &off, Visitor &v)
Unpack msgpack formatted data via a visitor.
Definition: parse.hpp:1000
#define MSGPACK_API_VERSION_NAMESPACE(ns)
Definition: versioning.hpp:58