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 23 #pragma GCC diagnostic push 24 #pragma GCC diagnostic ignored "-Wunused-parameter" 25 #endif // __GNUC__ >= 4 27 #include <boost/config/warning_disable.hpp> 28 #include <boost/spirit/home/x3.hpp> 29 #include <boost/spirit/home/x3/binary.hpp> 39 namespace x3 = boost::spirit::x3;
44 const auto byte_range = [](
const std::uint8_t from,
const std::uint8_t to) {
45 const auto check = [from, to](
auto& ctx)
47 const std::uint8_t value = x3::_attr(ctx);
48 x3::_val(ctx) = value;
49 x3::_pass(ctx) = from <= value && value <= to;
51 return x3::byte_ [check];
55 const auto mp_positive_fixint = byte_range(0x00, 0x7f);
56 const auto mp_fixmap = byte_range(0x80, 0x8f);
57 const auto mp_fixarray = byte_range(0x90, 0x9f);
58 const auto mp_fixstr = byte_range(0xa0, 0xbf);
59 const auto mp_nil = x3::byte_(0xc0);
60 const auto mp_false = x3::byte_(0xc2);
61 const auto mp_true = x3::byte_(0xc3);
62 const auto mp_bin8 = x3::byte_(0xc4);
63 const auto mp_bin16 = x3::byte_(0xc5);
64 const auto mp_bin32 = x3::byte_(0xc6);
65 const auto mp_ext8 = x3::byte_(0xc7);
66 const auto mp_ext16 = x3::byte_(0xc8);
67 const auto mp_ext32 = x3::byte_(0xc9);
68 const auto mp_float32 = x3::byte_(0xca);
69 const auto mp_float64 = x3::byte_(0xcb);
70 const auto mp_uint8 = x3::byte_(0xcc);
71 const auto mp_uint16 = x3::byte_(0xcd);
72 const auto mp_uint32 = x3::byte_(0xce);
73 const auto mp_uint64 = x3::byte_(0xcf);
74 const auto mp_int8 = x3::byte_(0xd0);
75 const auto mp_int16 = x3::byte_(0xd1);
76 const auto mp_int32 = x3::byte_(0xd2);
77 const auto mp_int64 = x3::byte_(0xd3);
78 const auto mp_fixext1 = x3::byte_(0xd4);
79 const auto mp_fixext2 = x3::byte_(0xd5);
80 const auto mp_fixext4 = x3::byte_(0xd6);
81 const auto mp_fixext8 = x3::byte_(0xd7);
82 const auto mp_fixext16 = x3::byte_(0xd8);
83 const auto mp_str8 = x3::byte_(0xd9);
84 const auto mp_str16 = x3::byte_(0xda);
85 const auto mp_str32 = x3::byte_(0xdb);
86 const auto mp_array16 = x3::byte_(0xdc);
87 const auto mp_array32 = x3::byte_(0xdd);
88 const auto mp_map16 = x3::byte_(0xde);
89 const auto mp_map32 = x3::byte_(0xdf);
90 const auto mp_negative_fixint = byte_range(0xe0, 0xff);
92 const auto mp_d_uint8 = x3::byte_;
93 const auto mp_d_uint16 = x3::big_word;
94 const auto mp_d_uint32 = x3::big_dword;
95 const auto mp_d_uint64 = x3::big_qword;
97 const auto mp_d_int8 = x3::byte_;
98 const auto mp_d_int16 = x3::big_word;
99 const auto mp_d_int32 = x3::big_dword;
100 const auto mp_d_int64 = x3::big_qword;
102 x3::rule<class mp_object>
const mp_object(
"mp_object");
103 x3::rule<class array_items>
const array_item(
"array_item");
104 x3::rule<class map_items>
const map_item(
"map_item");
105 x3::rule<class kv>
const kv(
"kv");
107 struct tag_app_specific {};
114 index_size(std::size_t
size, type_t type = type_t::other):size(size), type(type) {}
115 std::size_t index = 0;
120 template <
typename Visitor>
121 struct app_specific {
122 template <
typename Vis>
123 app_specific(Vis&& vis):vis(vis) {}
124 std::vector<index_size> index_sizes;
128 template <
typename Visitor>
129 app_specific<Visitor> make_app_specific(Visitor&& vis) {
130 return app_specific<Visitor>(std::forward<Visitor>(vis));
133 const auto more = [](
auto &ctx) {
134 auto& app_specific = x3::get<tag_app_specific>(ctx).
get();
135 _pass(ctx) = app_specific.index_sizes.back().index++ < app_specific.index_sizes.back().size;
138 const auto done = [](
auto &ctx) {
139 auto& app_specific = x3::get<tag_app_specific>(ctx).
get();
140 if (app_specific.index_sizes.back().index == app_specific.index_sizes.back().size + 1) {
142 switch (app_specific.index_sizes.back().type) {
143 case index_size::type_t::array:
144 app_specific.vis.end_array();
146 case index_size::type_t::map:
147 app_specific.vis.end_map();
149 case index_size::type_t::other:
152 app_specific.index_sizes.pop_back();
159 const auto mp_object_def =
164 auto& app_specific = x3::get<tag_app_specific>(ctx).
get();
165 app_specific.vis.visit_nil();
174 auto& app_specific = x3::get<tag_app_specific>(ctx).
get();
175 app_specific.vis.visit_boolean(
true);
184 auto& app_specific = x3::get<tag_app_specific>(ctx).
get();
185 app_specific.vis.visit_boolean(
false);
194 auto& app_specific = x3::get<tag_app_specific>(ctx).
get();
195 app_specific.vis.visit_positive_integer(_attr(ctx));
204 auto& app_specific = x3::get<tag_app_specific>(ctx).
get();
205 std::int8_t val = _attr(ctx);
206 app_specific.vis.visit_negative_integer(val);
212 mp_uint8 >> mp_d_uint8 [
215 auto& app_specific = x3::get<tag_app_specific>(ctx).
get();
216 app_specific.vis.visit_negative_integer(_attr(ctx));
222 mp_uint16 >> mp_d_uint16 [
225 auto& app_specific = x3::get<tag_app_specific>(ctx).
get();
226 app_specific.vis.visit_positive_integer(_attr(ctx));
232 mp_uint32 >> mp_d_uint32 [
235 auto& app_specific = x3::get<tag_app_specific>(ctx).
get();
236 app_specific.vis.visit_positive_integer(_attr(ctx));
242 mp_uint64 >> mp_d_uint64 [
245 auto& app_specific = x3::get<tag_app_specific>(ctx).
get();
246 app_specific.vis.visit_positive_integer(_attr(ctx));
252 mp_int8 >> mp_d_int8 [
255 auto& app_specific = x3::get<tag_app_specific>(ctx).
get();
256 std::int8_t val = _attr(ctx);
257 app_specific.vis.visit_negative_integer(val);
263 mp_int16 >> mp_d_int16 [
266 auto& app_specific = x3::get<tag_app_specific>(ctx).
get();
267 std::int16_t val = _attr(ctx);
268 app_specific.vis.visit_negative_integer(val);
274 mp_int32 >> mp_d_int32 [
277 auto& app_specific = x3::get<tag_app_specific>(ctx).
get();
278 std::int32_t val = _attr(ctx);
279 app_specific.vis.visit_negative_integer(val);
285 mp_int64 >> mp_d_int64 [
288 auto& app_specific = x3::get<tag_app_specific>(ctx).
get();
289 std::int64_t val = _attr(ctx);
290 app_specific.vis.visit_negative_integer(val);
296 mp_float32 >> mp_d_uint32 [
299 auto& app_specific = x3::get<tag_app_specific>(ctx).
get();
300 union { uint32_t i;
float f; } mem;
302 app_specific.vis.visit_float32(mem.f);
308 mp_float64 >> mp_d_uint64 [
311 auto& app_specific = x3::get<tag_app_specific>(ctx).
get();
312 union { uint64_t i;
double f; } mem;
314 #if defined(TARGET_OS_IPHONE) 316 #elif defined(__arm__) && !(__ARM_EABI__) // arm-oabi 318 mem.i = (mem.i & 0xFFFFFFFFUL) << 32UL | (mem.i >> 32UL);
320 app_specific.vis.visit_float64(mem.f);
329 auto& app_specific = x3::get<tag_app_specific>(ctx).
get();
330 std::size_t
size = _attr(ctx) & 0b00011111;
331 app_specific.index_sizes.emplace_back(size);
337 *(x3::eps [more] >> x3::char_)
342 auto& app_specific = x3::get<tag_app_specific>(ctx).
get();
343 auto const& str = _attr(ctx);
344 std::size_t size = std::distance(str.begin(), str.end());
345 app_specific.vis.visit_str(size ? &str.front() :
nullptr,
size);
351 mp_str8 >> mp_d_uint8 [
354 auto& app_specific = x3::get<tag_app_specific>(ctx).
get();
355 app_specific.index_sizes.emplace_back(_attr(ctx));
361 *(x3::eps [more] >> x3::char_)
366 auto& app_specific = x3::get<tag_app_specific>(ctx).
get();
367 auto const& str = _attr(ctx);
368 std::size_t size = std::distance(str.begin(), str.end());
369 app_specific.vis.visit_str(size ? &str.front() :
nullptr,
size);
375 mp_str16 >> mp_d_uint16 [
378 auto& app_specific = x3::get<tag_app_specific>(ctx).
get();
379 app_specific.index_sizes.emplace_back(_attr(ctx));
385 *(x3::eps [more] >> x3::char_)
390 auto& app_specific = x3::get<tag_app_specific>(ctx).
get();
391 auto const& str = _attr(ctx);
392 std::size_t size = std::distance(str.begin(), str.end());
393 app_specific.vis.visit_str(size ? &str.front() :
nullptr,
size);
399 mp_str32 >> mp_d_uint32 [
402 auto& app_specific = x3::get<tag_app_specific>(ctx).
get();
403 app_specific.index_sizes.emplace_back(_attr(ctx));
409 *(x3::eps [more] >> x3::char_)
414 auto& app_specific = x3::get<tag_app_specific>(ctx).
get();
415 auto const& str = _attr(ctx);
416 std::size_t size = std::distance(str.begin(), str.end());
417 app_specific.vis.visit_str(size ? &str.front() :
nullptr,
size);
423 mp_bin8 >> mp_d_uint8 [
426 auto& app_specific = x3::get<tag_app_specific>(ctx).
get();
427 app_specific.index_sizes.emplace_back(_attr(ctx));
433 *(x3::eps [more] >> x3::char_)
438 auto& app_specific = x3::get<tag_app_specific>(ctx).
get();
439 auto const& bin = _attr(ctx);
440 std::size_t size = std::distance(bin.begin(), bin.end());
441 app_specific.vis.visit_bin(size ? &bin.front() :
nullptr,
size);
447 mp_bin16 >> mp_d_uint16 [
450 auto& app_specific = x3::get<tag_app_specific>(ctx).
get();
451 app_specific.index_sizes.emplace_back(_attr(ctx));
457 *(x3::eps [more] >> x3::char_)
462 auto& app_specific = x3::get<tag_app_specific>(ctx).
get();
463 auto const& bin = _attr(ctx);
464 std::size_t size = std::distance(bin.begin(), bin.end());
465 app_specific.vis.visit_bin(size ? &bin.front() :
nullptr,
size);
471 mp_bin32 >> mp_d_uint32 [
474 auto& app_specific = x3::get<tag_app_specific>(ctx).
get();
475 app_specific.index_sizes.emplace_back(_attr(ctx));
481 *(x3::eps [more] >> x3::char_)
486 auto& app_specific = x3::get<tag_app_specific>(ctx).
get();
487 auto const& bin = _attr(ctx);
488 std::size_t size = std::distance(bin.begin(), bin.end());
489 app_specific.vis.visit_bin(size ? &bin.front() :
nullptr,
size);
498 auto& app_specific = x3::get<tag_app_specific>(ctx).
get();
499 std::size_t size = _attr(ctx) & 0b00001111;
500 app_specific.index_sizes.emplace_back(size, index_size::type_t::array);
501 app_specific.vis.start_array(size);
505 >> *(x3::eps [more] >> array_item)
509 mp_array16 >> mp_d_uint16 [
512 auto& app_specific = x3::get<tag_app_specific>(ctx).
get();
513 std::size_t size = _attr(ctx);
514 app_specific.index_sizes.emplace_back(size, index_size::type_t::array);
515 app_specific.vis.start_array(size);
519 >> *(x3::eps [more] >> array_item)
523 mp_array32 >> mp_d_uint32 [
526 auto& app_specific = x3::get<tag_app_specific>(ctx).
get();
527 std::size_t size = _attr(ctx);
528 app_specific.index_sizes.emplace_back(size, index_size::type_t::array);
529 app_specific.vis.start_array(size);
533 >> *(x3::eps [more] >> array_item)
540 auto& app_specific = x3::get<tag_app_specific>(ctx).
get();
541 std::size_t size = _attr(ctx) & 0b00001111;
542 app_specific.index_sizes.emplace_back(size, index_size::type_t::map);
543 app_specific.vis.start_map(size);
547 >> *(x3::eps [more] >> map_item)
551 mp_map16 >> mp_d_uint16 [
554 auto& app_specific = x3::get<tag_app_specific>(ctx).
get();
555 std::size_t size = _attr(ctx);
556 app_specific.index_sizes.emplace_back(size, index_size::type_t::map);
557 app_specific.vis.start_map(size);
561 >> *(x3::eps [more] >> map_item)
565 mp_map32 >> mp_d_uint32 [
568 auto& app_specific = x3::get<tag_app_specific>(ctx).
get();
569 std::size_t size = _attr(ctx);
570 app_specific.index_sizes.emplace_back(size, index_size::type_t::map);
571 app_specific.vis.start_map(size);
575 >> *(x3::eps [more] >> map_item)
582 auto& app_specific = x3::get<tag_app_specific>(ctx).
get();
583 app_specific.index_sizes.emplace_back(1+1);
589 *(x3::eps [more] >> x3::char_)
594 auto& app_specific = x3::get<tag_app_specific>(ctx).
get();
595 auto const& ext = _attr(ctx);
596 std::size_t size = std::distance(ext.begin(), ext.end());
597 app_specific.vis.visit_ext(size ? &ext.front() :
nullptr,
size);
606 auto& app_specific = x3::get<tag_app_specific>(ctx).
get();
607 app_specific.index_sizes.emplace_back(2+1);
613 *(x3::eps [more] >> x3::char_)
618 auto& app_specific = x3::get<tag_app_specific>(ctx).
get();
619 auto const& ext = _attr(ctx);
620 std::size_t size = std::distance(ext.begin(), ext.end());
621 app_specific.vis.visit_ext(size ? &ext.front() :
nullptr,
size);
630 auto& app_specific = x3::get<tag_app_specific>(ctx).
get();
631 app_specific.index_sizes.emplace_back(4+1);
637 *(x3::eps [more] >> x3::char_)
642 auto& app_specific = x3::get<tag_app_specific>(ctx).
get();
643 auto const& ext = _attr(ctx);
644 std::size_t size = std::distance(ext.begin(), ext.end());
645 app_specific.vis.visit_ext(size ? &ext.front() :
nullptr,
size);
654 auto& app_specific = x3::get<tag_app_specific>(ctx).
get();
655 app_specific.index_sizes.emplace_back(8+1);
661 *(x3::eps [more] >> x3::char_)
666 auto& app_specific = x3::get<tag_app_specific>(ctx).
get();
667 auto const& ext = _attr(ctx);
668 std::size_t size = std::distance(ext.begin(), ext.end());
669 app_specific.vis.visit_ext(size ? &ext.front() :
nullptr,
size);
678 auto& app_specific = x3::get<tag_app_specific>(ctx).
get();
679 app_specific.index_sizes.emplace_back(16+1);
685 *(x3::eps [more] >> x3::char_)
690 auto& app_specific = x3::get<tag_app_specific>(ctx).
get();
691 auto const& ext = _attr(ctx);
692 std::size_t size = std::distance(ext.begin(), ext.end());
693 app_specific.vis.visit_ext(size ? &ext.front() :
nullptr,
size);
699 mp_ext8 >> mp_d_uint8 [
702 auto& app_specific = x3::get<tag_app_specific>(ctx).
get();
703 app_specific.index_sizes.emplace_back(_attr(ctx)+1);
709 *(x3::eps [more] >> x3::char_)
714 auto& app_specific = x3::get<tag_app_specific>(ctx).
get();
715 auto const& ext = _attr(ctx);
716 std::size_t size = std::distance(ext.begin(), ext.end());
717 app_specific.vis.visit_ext(size ? &ext.front() :
nullptr,
size);
723 mp_ext16 >> mp_d_uint16 [
726 auto& app_specific = x3::get<tag_app_specific>(ctx).
get();
727 app_specific.index_sizes.emplace_back(_attr(ctx)+1);
733 *(x3::eps [more] >> x3::char_)
738 auto& app_specific = x3::get<tag_app_specific>(ctx).
get();
739 auto const& ext = _attr(ctx);
740 std::size_t size = std::distance(ext.begin(), ext.end());
741 app_specific.vis.visit_ext(size ? &ext.front() :
nullptr,
size);
747 mp_ext32 >> mp_d_uint32 [
750 auto& app_specific = x3::get<tag_app_specific>(ctx).
get();
751 app_specific.index_sizes.emplace_back(_attr(ctx)+1);
757 *(x3::eps [more] >> x3::char_)
762 auto& app_specific = x3::get<tag_app_specific>(ctx).
get();
763 auto const& ext = _attr(ctx);
764 std::size_t size = std::distance(ext.begin(), ext.end());
765 app_specific.vis.visit_ext(size ? &ext.front() :
nullptr,
size);
770 const auto array_item_def =
774 auto& app_specific = x3::get<tag_app_specific>(ctx).
get();
775 app_specific.vis.start_array_item();
786 auto& app_specific = x3::get<tag_app_specific>(ctx).
get();
787 app_specific.vis.end_array_item();
793 const auto map_item_def = kv;
798 auto& app_specific = x3::get<tag_app_specific>(ctx).
get();
799 app_specific.vis.start_map_key();
810 auto& app_specific = x3::get<tag_app_specific>(ctx).
get();
811 app_specific.vis.end_map_key();
820 auto& app_specific = x3::get<tag_app_specific>(ctx).
get();
821 app_specific.vis.start_map_value();
832 auto& app_specific = x3::get<tag_app_specific>(ctx).
get();
833 app_specific.vis.end_map_value();
840 mp_object, array_item, map_item, kv
843 const auto rule = mp_object;
847 template <
typename Iterator,
typename Visitor>
848 inline bool parse(Iterator&&
begin, Iterator&&
end, Visitor&& vis) {
849 auto data = detail::make_app_specific(std::forward<Visitor>(vis));
851 std::forward<Iterator>(
begin),
852 std::forward<Iterator>(
end),
853 detail::x3::with<detail::tag_app_specific>(std::ref(data))[detail::rule]
864 #pragma GCC diagnostic pop 865 #endif // __GNUC__ >= 4 867 #else // BOOST_VERSION >= 106100 869 #error Boost 1.61.0 or later is required to use x3 parse 871 #endif // BOOST_VERSION >= 106100 873 #endif // defined(MSGPACK_USE_X3_PARSE) 875 #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.
#define MSGPACK_API_VERSION_NAMESPACE(ns)
Definition: versioning.hpp:58