13 #include <type_traits>
23 using std::make_shared;
24 using std::initializer_list;
44 virtual void dump(std::ostream& os)
const = 0;
77 } endian_check_data { 0x0001 };
78 static const bool is_big_endian = endian_check_data.bytes[0] == 0x00;
80 template<
typename T >
81 void dump_data(
const T value, std::ostream& os)
85 std::array<uint8_t,
sizeof(T)>
bytes;
87 converter.packed = value;
89 int const n =
sizeof(T);
90 int const offsets[] = {(n-1), 0};
91 int const directions[] = {-1, 1};
92 uint8_t
const off = offsets[
static_cast<int>(is_big_endian)];
93 int const dir = directions[
static_cast<int>(is_big_endian)];
94 for(
int i = 0; i < n; ++i)
96 os.put(converter.bytes[off + dir * i]);
100 inline void dump(NullStruct, std::ostream& os) {
104 inline void dump(
float value, std::ostream& os) {
106 dump_data(value, os);
109 inline void dump(
double value, std::ostream& os) {
111 dump_data(value, os);
114 inline void dump(uint8_t value, std::ostream& os) {
122 inline void dump(uint16_t value, std::ostream& os) {
123 if( value < (1 << 8) )
125 dump(
static_cast<uint8_t
>(value), os );
130 dump_data(value, os);
134 inline void dump(uint32_t value, std::ostream& os) {
135 if( value < (1 << 16) )
137 dump(
static_cast<uint16_t
>(value), os );
142 dump_data(value, os);
146 inline void dump(uint64_t value, std::ostream& os) {
147 if( value < (1ULL << 32) )
149 dump(
static_cast<uint32_t
>(value), os );
154 dump_data(value, os);
158 inline void dump(int8_t value, std::ostream& os) {
166 inline void dump(int16_t value, std::ostream& os) {
167 if( value < -(1 << 7) )
170 dump_data(value, os);
172 else if( value <= 0 )
174 dump(
static_cast<int8_t
>(value), os );
178 dump(
static_cast<uint16_t
>(value), os );
182 inline void dump(int32_t value, std::ostream& os) {
183 if( value < -(1 << 15) )
186 dump_data(value, os);
188 else if( value <= 0 )
190 dump(
static_cast<int16_t
>(value), os );
194 dump(
static_cast<uint32_t
>(value), os );
198 inline void dump(int64_t value, std::ostream& os) {
199 if( value < -(1LL << 31) )
202 dump_data(value, os);
204 else if( value <= 0 )
206 dump(
static_cast<int32_t
>(value), os );
210 dump(
static_cast<uint64_t
>(value), os );
214 inline void dump(
bool value, std::ostream& os) {
215 const uint8_t msgpack_value = (value) ? 0xc3 : 0xc2;
216 os.put(msgpack_value);
219 inline void dump(
const std::string& value, std::ostream& os) {
220 size_t const len = value.size();
223 uint8_t
const first_byte = 0xa0 |
static_cast<uint8_t
>(len);
229 os.put(
static_cast<uint8_t
>(len));
231 else if(len <= 0xffff)
234 dump_data(
static_cast<uint16_t
>(len), os);
236 else if(len <= 0xffffffff)
239 dump_data(
static_cast<uint32_t
>(len), os);
243 throw std::runtime_error(
"exceeded maximum data length");
246 std::for_each(std::begin(value), std::end(value), [&os](
char v){
252 size_t const len = value.size();
255 uint8_t
const first_byte = 0x90 |
static_cast<uint8_t
>(len);
258 else if(len <= 0xffff)
261 dump_data(
static_cast<uint16_t
>(len), os);
263 else if(len <= 0xffffffff)
266 dump_data(
static_cast<uint32_t
>(len), os);
270 throw std::runtime_error(
"exceeded maximum data length");
273 std::for_each(std::begin(value), std::end(value), [&os](MsgPack::array::value_type
const& v){
279 size_t const len = value.size();
282 uint8_t
const first_byte = 0x80 |
static_cast<uint8_t
>(len);
285 else if(len <= 0xffff)
288 dump_data(
static_cast<uint16_t
>(len), os);
290 else if(len <= 0xffffffff)
293 dump_data(
static_cast<uint32_t
>(len), os);
297 throw std::runtime_error(
"too long value.");
300 std::for_each(std::begin(value), std::end(value), [&os](MsgPack::object::value_type
const& v){
307 size_t const len = value.size();
311 dump_data(
static_cast<uint8_t
>(len), os);
313 else if(len <= 0xffff)
316 dump_data(
static_cast<uint16_t
>(len), os);
318 else if(len <= 0xffffffff)
321 dump_data(
static_cast<uint32_t
>(len), os);
325 throw std::runtime_error(
"exceeded maximum data length");
327 os.write(
reinterpret_cast<const char*
>(value.data()), value.size());
331 const uint8_t
type = std::get<0>( value );
333 const size_t len =
data.size();
338 else if(len == 0x02) {
341 else if(len == 0x04) {
344 else if(len == 0x08) {
347 else if(len == 0x10) {
350 else if(len <= 0xff) {
352 os.put(
static_cast<uint8_t
>(len));
354 else if(len <= 0xffff) {
356 dump_data(
static_cast<uint16_t
>(len), os);
358 else if(len <= 0xffffffff) {
360 dump_data(
static_cast<uint32_t
>(len), os);
363 throw std::runtime_error(
"exceeded maximum data length");
367 os.write(
reinterpret_cast<const char*
>(
data.data()),
data.size());
372 msgpack.
m_ptr->dump(os);
382 template <MsgPack::Type tag,
typename T>
397 bool const is_same_type = tag == other->
type();
401 bool const is_same_type = tag == other->
type();
402 bool const is_less_type = tag < other->
type();
403 return is_less_type || (is_same_type && (m_value < static_cast<const Value<tag, T> *>(other)->
m_value));
407 void dump(std::ostream& os)
const override { msgpack11::dump(
m_value, os); }
412 bool const is_positive = 0 <= int64_value;
413 bool const is_leq_int64_max = uint64_value <= static_cast<std::uint64_t>(std::numeric_limits<int64_t>::max());
414 return is_positive && is_leq_int64_max && ( uint64_value ==
static_cast<uint64_t
>(int64_value));
419 bool const is_positive = 0 <= int64_value;
420 bool const is_leq_int64_max = uint64_value <= static_cast<std::uint64_t>(std::numeric_limits<int64_t>::max());
421 return is_positive && is_leq_int64_max && ( uint64_value < static_cast<uint64_t>(int64_value));
426 bool const is_negative = int64_value < 0;
427 bool const is_gt_int64_max =
static_cast<std::uint64_t
>(std::numeric_limits<int64_t>::max()) < uint64_value;
428 return is_negative || is_gt_int64_max || (
static_cast<uint64_t
>(int64_value) < uint64_value );
431 template <MsgPack::Type tag,
typename T>
440 switch( other->
type() )
463 switch( other->
type() )
527 switch( other->
type() )
545 switch( other->
type() )
583 switch( other->
type() )
601 switch( other->
type() )
673 const std::shared_ptr<MsgPackValue>
null = make_shared<MsgPackNull>();
674 const std::shared_ptr<MsgPackValue>
t = make_shared<MsgPackBoolean>(
true);
675 const std::shared_ptr<MsgPackValue>
f = make_shared<MsgPackBoolean>(
false);
691 static const MsgPack msgpack_null;
713 MsgPack::MsgPack(
string &&value) : m_ptr(make_shared<MsgPackString>(move(value))) {}
797 namespace MsgPackParser {
798 MsgPack parse_msgpack(std::istream& is,
int depth);
800 template<
typename T >
801 void read_bytes(std::istream& is, T&
bytes)
803 static_assert(std::is_fundamental<T>::value,
804 "byte read not guaranteed for non-primitive types");
807 int const offsets[] = {(n-1), 0};
808 int const directions[] = {-1, 1};
810 uint8_t* dst_ptr =
reinterpret_cast<uint8_t*
>(&
bytes) + offsets[
static_cast<int>(is_big_endian)];
811 int const dir = directions[
static_cast<int>(is_big_endian)];
812 for(
int i = 0; i < n; ++i)
820 if (is.fail() || is.eof()) {
829 MsgPack fail(std::istream& is) {
830 is.setstate(std::ios::failbit);
834 MsgPack parse_invalid(std::istream& is, uint8_t,
int) {
838 MsgPack parse_nil(std::istream&, uint8_t,
int) {
842 MsgPack parse_bool(std::istream&, uint8_t first_byte,
int) {
843 return MsgPack(first_byte == 0xc3);
846 template<
typename T >
847 MsgPack parse_arith(std::istream& is, uint8_t,
int) {
853 inline std::string parse_string_impl(std::istream& is, uint32_t
bytes) {
856 is.read(&ret[0],
bytes);
860 template<
typename T >
861 MsgPack parse_string(std::istream& is, uint8_t,
int) {
863 read_bytes(is,
bytes);
864 return MsgPack(parse_string_impl(is,
static_cast<uint32_t
>(
bytes)));
871 for(uint32_t i = 0; i <
bytes; ++i) {
872 res.push_back(parse_msgpack(is, depth));
877 template<
typename T >
878 MsgPack parse_array(std::istream& is, uint8_t,
int depth) {
880 read_bytes(is,
bytes);
881 return MsgPack(parse_array_impl(is,
static_cast<uint32_t
>(
bytes), depth));
887 for(uint32_t i = 0; i <
bytes; ++i) {
888 MsgPack key = parse_msgpack(is, depth);
889 MsgPack value = parse_msgpack(is, depth);
890 res.insert(std::make_pair(std::move(key), std::move(value)));
895 template<
typename T >
896 MsgPack parse_object(std::istream& is, uint8_t,
int depth) {
898 read_bytes(is,
bytes);
899 return MsgPack(parse_object_impl(is,
static_cast<uint32_t
>(
bytes), depth));
905 is.read(
reinterpret_cast<char*
>(ret.data()),
bytes);
909 template<
typename T >
910 MsgPack parse_binary(std::istream& is, uint8_t,
int) {
912 read_bytes(is,
bytes);
913 return MsgPack(parse_binary_impl(is,
static_cast<uint32_t
>(
bytes)));
916 template<
typename T >
917 MsgPack parse_extension(std::istream& is, uint8_t,
int) {
919 read_bytes(is,
bytes);
921 read_bytes(is,
type);
926 MsgPack parse_pos_fixint(std::istream&, uint8_t first_byte,
int) {
930 MsgPack parse_fixobject(std::istream& is, uint8_t first_byte,
int depth) {
931 uint32_t
const bytes = first_byte & 0x0f;
935 MsgPack parse_fixarray(std::istream& is, uint8_t first_byte,
int depth) {
936 uint32_t
const bytes = first_byte & 0x0f;
940 MsgPack parse_fixstring(std::istream& is, uint8_t first_byte,
int) {
941 uint32_t
const bytes = first_byte & 0x1f;
945 MsgPack parse_neg_fixint(std::istream&, uint8_t first_byte,
int) {
946 return MsgPack(*
reinterpret_cast<int8_t*
>(&first_byte));
949 MsgPack parse_fixext(std::istream& is, uint8_t first_byte,
int) {
951 read_bytes(is,
type);
952 uint32_t
const BYTES = 1 << (first_byte - 0xd4u);
961 MsgPack parse_msgpack(std::istream& is,
int depth) {
962 static const std::array<
MsgPack(*)(std::istream&, uint8_t, int), 256 > parsers = [](){
963 using parser_template_element_type = std::tuple<uint8_t,
MsgPack(*)(std::istream&,uint8_t,int)>;
964 std::array< parser_template_element_type, 36 >
const parser_template{{
965 parser_template_element_type{ 0x7fu, &MsgPackParser::parse_pos_fixint},
966 parser_template_element_type{ 0x8fu, &MsgPackParser::parse_fixobject},
967 parser_template_element_type{ 0x9fu, &MsgPackParser::parse_fixarray},
968 parser_template_element_type{ 0xbfu, &MsgPackParser::parse_fixstring},
969 parser_template_element_type{ 0xc0u, &MsgPackParser::parse_nil},
970 parser_template_element_type{ 0xc1u, &MsgPackParser::parse_invalid},
971 parser_template_element_type{ 0xc3u, &MsgPackParser::parse_bool},
972 parser_template_element_type{ 0xc4u, &MsgPackParser::parse_binary<uint8_t>},
973 parser_template_element_type{ 0xc5u, &MsgPackParser::parse_binary<uint16_t>},
974 parser_template_element_type{ 0xc6u, &MsgPackParser::parse_binary<uint32_t>},
975 parser_template_element_type{ 0xc7u, &MsgPackParser::parse_extension<uint8_t>},
976 parser_template_element_type{ 0xc8u, &MsgPackParser::parse_extension<uint16_t>},
977 parser_template_element_type{ 0xc9u, &MsgPackParser::parse_extension<uint32_t>},
978 parser_template_element_type{ 0xcau, &MsgPackParser::parse_arith<float>},
979 parser_template_element_type{ 0xcbu, &MsgPackParser::parse_arith<double>},
980 parser_template_element_type{ 0xccu, &MsgPackParser::parse_arith<uint8_t>},
981 parser_template_element_type{ 0xcdu, &MsgPackParser::parse_arith<uint16_t>},
982 parser_template_element_type{ 0xceu, &MsgPackParser::parse_arith<uint32_t>},
983 parser_template_element_type{ 0xcfu, &MsgPackParser::parse_arith<uint64_t>},
984 parser_template_element_type{ 0xd0u, &MsgPackParser::parse_arith<int8_t>},
985 parser_template_element_type{ 0xd1u, &MsgPackParser::parse_arith<int16_t>},
986 parser_template_element_type{ 0xd2u, &MsgPackParser::parse_arith<int32_t>},
987 parser_template_element_type{ 0xd3u, &MsgPackParser::parse_arith<int64_t>},
988 parser_template_element_type{ 0xd8u, &MsgPackParser::parse_fixext},
989 parser_template_element_type{ 0xd9u, &MsgPackParser::parse_string<uint8_t>},
990 parser_template_element_type{ 0xdau, &MsgPackParser::parse_string<uint16_t>},
991 parser_template_element_type{ 0xdbu, &MsgPackParser::parse_string<uint32_t>},
992 parser_template_element_type{ 0xdcu, &MsgPackParser::parse_array<uint16_t>},
993 parser_template_element_type{ 0xddu, &MsgPackParser::parse_array<uint32_t>},
994 parser_template_element_type{ 0xdeu, &MsgPackParser::parse_object<uint16_t>},
995 parser_template_element_type{ 0xdfu, &MsgPackParser::parse_object<uint32_t>},
996 parser_template_element_type{ 0xffu, &MsgPackParser::parse_neg_fixint}
999 std::array<
MsgPack(*)(std::istream&, uint8_t, int), 256 > parsers;
1001 std::for_each(std::begin(parser_template),
1002 std::end(parser_template),
1003 [&parsers,&i]( parser_template_element_type
const& element ) {
1004 int upto = std::get<0>( element );
1005 auto parser = std::get<1>( element );
1020 uint8_t
const first_byte = is.get();
1022 if (is.fail() || is.eof()) {
1026 MsgPack ret = (*parsers[first_byte])(is, first_byte, depth + 1);
1028 if (is.fail() || is.eof()) {
1038 msgpack = MsgPackParser::parse_msgpack(is, 0);
1043 return MsgPackParser::parse_msgpack(is, 0);
1049 err =
"end of buffer.";
1050 }
else if (is.fail()) {
1051 err =
"format error.";
1057 std::stringstream ss(in);
1063 std::string::size_type &parser_stop_pos,
1065 std::stringstream ss(in);
1067 vector<MsgPack> msgpack_vec;
1068 while (
static_cast<size_t>(ss.tellg()) != in.size() && !ss.eof() && !ss.fail()) {
1071 msgpack_vec.emplace_back(std::move(next));
1072 parser_stop_pos = ss.tellg();
1085 err =
"expected MessagePack object";
1089 for (
auto & item : types) {
1090 if ((*
this)[item.first].type() != item.second) {
1091 err =
"bad type for " + item.first;