msgpack parser implemented by template/typetraits, not by inheritance

This commit is contained in:
Luca 2022-10-07 02:07:07 +02:00
parent b49de73092
commit 620b59f067
6 changed files with 23889 additions and 2028 deletions

1
.gitignore vendored
View File

@ -22,6 +22,7 @@ benchmarks/files/numbers/*.json
test/test-* test/test-*
/.vs /.vs
/.vscode
doc/html doc/html
doc/mkdocs/venv/ doc/mkdocs/venv/

1693
Makefile

File diff suppressed because it is too large Load Diff

View File

@ -1363,7 +1363,16 @@ class binary_reader
case 0x9D: case 0x9D:
case 0x9E: case 0x9E:
case 0x9F: case 0x9F:
return get_msgpack_array(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x0Fu)); {
const auto len = static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x0Fu);
return JSON_HEDLEY_LIKELY(
sax->start_array(len)
&&
get_msgpack_array(len)
&&
sax->end_array()
);
}
// fixstr // fixstr
case 0xA0: case 0xA0:
@ -1494,25 +1503,58 @@ class binary_reader
case 0xDC: // array 16 case 0xDC: // array 16
{ {
std::uint16_t len{}; std::uint16_t len{};
return get_number(input_format_t::msgpack, len) && get_msgpack_array(static_cast<std::size_t>(len)); return JSON_HEDLEY_LIKELY(
get_number(input_format_t::msgpack, len)
&&
sax->start_array(static_cast<std::size_t>(len))
&&
get_msgpack_array(static_cast<std::size_t>(len))
&&
sax->end_array()
);
} }
case 0xDD: // array 32 case 0xDD: // array 32
{ {
std::uint32_t len{}; std::uint32_t len{};
return get_number(input_format_t::msgpack, len) && get_msgpack_array(static_cast<std::size_t>(len)); return JSON_HEDLEY_LIKELY(
get_number(input_format_t::msgpack, len)
&&
sax->start_array(static_cast<std::size_t>(len))
&&
get_msgpack_array(static_cast<std::size_t>(len))
&&
sax->end_array()
);
} }
case 0xDE: // map 16 case 0xDE: // map 16
{ {
std::uint16_t len{}; std::uint16_t len{};
return get_number(input_format_t::msgpack, len) && sax->start_object(len) && get_msgpack_object(static_cast<std::size_t>(len)) && sax->end_object();
return JSON_HEDLEY_LIKELY(
get_number(input_format_t::msgpack, len)
&&
sax->start_object(len)
&&
get_msgpack_object(static_cast<std::size_t>(len))
&&
sax->end_object()
);
} }
case 0xDF: // map 32 case 0xDF: // map 32
{ {
std::uint32_t len{}; std::uint32_t len{};
return get_number(input_format_t::msgpack, len) && sax->start_object(len) && get_msgpack_object(static_cast<std::size_t>(len)) && sax->end_object(); return JSON_HEDLEY_LIKELY(
get_number(input_format_t::msgpack, len)
&&
sax->start_object(len)
&&
get_msgpack_object(static_cast<std::size_t>(len))
&&
sax->end_object()
);
} }
// negative fixint // negative fixint
@ -1765,11 +1807,6 @@ class binary_reader
*/ */
bool get_msgpack_array(const std::size_t len) bool get_msgpack_array(const std::size_t len)
{ {
if (JSON_HEDLEY_UNLIKELY(!sax->start_array(len)))
{
return false;
}
for (std::size_t i = 0; i < len; ++i) for (std::size_t i = 0; i < len; ++i)
{ {
if (JSON_HEDLEY_UNLIKELY(!parse_msgpack_internal())) if (JSON_HEDLEY_UNLIKELY(!parse_msgpack_internal()))
@ -1778,52 +1815,54 @@ class binary_reader
} }
} }
return sax->end_array();
}
/*!
@param[in] len the length of the object
@return whether object creation completed
*/
bool get_msgpack_object(const std::size_t len){
return get_msgpack_object_impl(len, detail::is_sax_msgpack<SAX, BasicJsonType>());
}
/*!
@param[in] len the length of the object
@param[in] full_msgpack_support is full msgpack protocoll suppored by sax
@return whether object creation completed
*/
bool get_msgpack_object_impl(const std::size_t len, std::false_type)
{
string_t key;
for (std::size_t i = 0; i < len; ++i)
{
get();
if (JSON_HEDLEY_UNLIKELY(!get_msgpack_string(key) || !sax->key(key)))
{
return false;
}
if (JSON_HEDLEY_UNLIKELY(!parse_msgpack_internal()))
{
return false;
}
key.clear();
}
return true; return true;
} }
/*! /*!
@param[in] len the length of the object @param[in] len the length of the object
@param[in] full_msgpack_support is full msgpack protocoll suppored by sax
@return whether object creation completed @return whether object creation completed
*/ */
bool get_msgpack_object_impl(const std::size_t len, std::true_type) bool get_msgpack_object(const std::size_t len)
{ {
string_t recycle_string;
for (std::size_t i = 0; i < len; ++i) for (std::size_t i = 0; i < len; ++i)
{
if (JSON_HEDLEY_UNLIKELY(
!(
get_msgpack_object_key(recycle_string, detail::is_sax_msgpack<SAX, BasicJsonType>())
&&
parse_msgpack_internal()
)
)
)
{
return false;
}
recycle_string.clear();
}
return true;
}
// /*!
// @param[in] len the length of the object
// @param[in] full_msgpack_support is full msgpack protocoll suppored by sax
// @return whether object creation completed
// */
bool get_msgpack_object_key(string_t& recycle_string, std::false_type)
{
get();
return JSON_HEDLEY_LIKELY(get_msgpack_string(recycle_string) && sax->key(recycle_string));
}
// /*!
// @param[in] len the length of the object
// @param[in] full_msgpack_support is full msgpack protocoll suppored by sax
// @return whether object creation completed
// */
bool get_msgpack_object_key(string_t& recycle_string, std::true_type)
{ {
switch (get()) switch (get())
{ {
@ -1962,13 +2001,7 @@ class binary_reader
case 0x7D: case 0x7D:
case 0x7E: case 0x7E:
case 0x7F: case 0x7F:
{ return JSON_HEDLEY_LIKELY(sax->key_unsigned(static_cast<number_unsigned_t>(current) ) );
if ( JSON_HEDLEY_UNLIKELY( ! sax->key_unsigned(static_cast<number_unsigned_t>(current) ) ) )
{
return false;
}
break;
}
// fixmap // fixmap
case 0x80: case 0x80:
@ -1989,43 +2022,30 @@ class binary_reader
case 0x8F: case 0x8F:
{ {
const auto len = static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x0Fu); const auto len = static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x0Fu);
return JSON_HEDLEY_LIKELY( sax->start_key_object(len) && get_msgpack_object() && sax->end_key_object() );
}
if ( JSON_HEDLEY_UNLIKELY( // fixarray
! ( case 0x90:
sax->start_key_object(len) case 0x91:
&& case 0x92:
get_msgpack_object() case 0x93:
&& case 0x94:
sax->end_key_object() case 0x95:
) case 0x96:
) case 0x97:
) case 0x98:
case 0x99:
case 0x9A:
case 0x9B:
case 0x9C:
case 0x9D:
case 0x9E:
case 0x9F:
{ {
return false; const auto len = static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x0Fu);
return sax->start_key_array(len) && get_msgpack_array(len) && sax->end_key_array();
} }
break;
}
// // fixarray
// case 0x90:
// case 0x91:
// case 0x92:
// case 0x93:
// case 0x94:
// case 0x95:
// case 0x96:
// case 0x97:
// case 0x98:
// case 0x99:
// case 0x9A:
// case 0x9B:
// case 0x9C:
// case 0x9D:
// case 0x9E:
// case 0x9F:
// return get_msgpack_array(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x0Fu));
// fixstr // fixstr
case 0xA0: case 0xA0:
@ -2064,147 +2084,111 @@ class binary_reader
case 0xDA: // str 16 case 0xDA: // str 16
case 0xDB: // str 32 case 0xDB: // str 32
{ {
string_t s; return JSON_HEDLEY_LIKELY( get_msgpack_string(recycle_string) && sax->key(recycle_string) );
if ( JSON_HEDLEY_UNLIKELY( ! ( get_msgpack_string(s) && sax->key(s) ) ) )
{
return false;
}
break;
} }
case 0xC0: // nil case 0xC0: // nil
{ return JSON_HEDLEY_LIKELY( sax->key_null() );
if ( JSON_HEDLEY_UNLIKELY( ! sax->key_null() ) )
{
return false;
}
break;
}
case 0xC2: // false case 0xC2: // false
{ return JSON_HEDLEY_LIKELY( sax->key_boolean(false) );
if ( JSON_HEDLEY_UNLIKELY( ! sax->key_boolean(false) ) )
{
return false;
}
break;
}
case 0xC3: // true case 0xC3: // true
return JSON_HEDLEY_LIKELY( sax->key_boolean(true) );
case 0xC4: // bin 8
case 0xC5: // bin 16
case 0xC6: // bin 32
case 0xC7: // ext 8
case 0xC8: // ext 16
case 0xC9: // ext 32
case 0xD4: // fixext 1
case 0xD5: // fixext 2
case 0xD6: // fixext 4
case 0xD7: // fixext 8
case 0xD8: // fixext 16
{ {
if ( JSON_HEDLEY_UNLIKELY( ! sax->key_boolean(true) ) ) binary_t b;
{ return get_msgpack_binary(b) && sax->key_binary(b);
return false;
}
break;
} }
case 0xCA: // float 32 case 0xCA: // float 32
{ {
float number{}; float number{};
if ( JSON_HEDLEY_UNLIKELY( ! ( get_number(input_format_t::msgpack, number) && sax->key_float(static_cast<number_float_t>(number), "") ) ) ) return JSON_HEDLEY_LIKELY( get_number(input_format_t::msgpack, number) && sax->key_float(static_cast<number_float_t>(number), "") );
{
return false;
}
break;
} }
case 0xCB: // float 64 case 0xCB: // float 64
{ {
double number{}; double number{};
if ( JSON_HEDLEY_UNLIKELY( ! ( get_number(input_format_t::msgpack, number) && sax->key_float(static_cast<number_float_t>(number), "") ) ) ) return JSON_HEDLEY_LIKELY( get_number(input_format_t::msgpack, number) && sax->key_float(static_cast<number_float_t>(number), "") );
{
return false;
}
break;
} }
case 0xCC: // uint 8 case 0xCC: // uint 8
{ {
std::uint8_t number{}; std::uint8_t number{};
if ( JSON_HEDLEY_UNLIKELY( ! ( get_number(input_format_t::msgpack, number) && sax->key_unsigned(number) ) ) ) return JSON_HEDLEY_LIKELY( get_number(input_format_t::msgpack, number) && sax->key_unsigned(number) );
{
return false;
}
break;
} }
case 0xCD: // uint 16 case 0xCD: // uint 16
{ {
std::uint16_t number{}; std::uint16_t number{};
if ( JSON_HEDLEY_UNLIKELY( ! ( get_number(input_format_t::msgpack, number) && sax->key_unsigned(number) ) ) ) return JSON_HEDLEY_LIKELY( get_number(input_format_t::msgpack, number) && sax->key_unsigned(number) );
{
return false;
}
break;
} }
case 0xCE: // uint 32 case 0xCE: // uint 32
{ {
std::uint32_t number{}; std::uint32_t number{};
if ( JSON_HEDLEY_UNLIKELY( ! ( get_number(input_format_t::msgpack, number) && sax->key_unsigned(number) ) ) ) return JSON_HEDLEY_LIKELY( get_number(input_format_t::msgpack, number) && sax->key_unsigned(number) );
{
return false;
}
break;
} }
case 0xCF: // uint 64 case 0xCF: // uint 64
{ {
std::uint64_t number{}; std::uint64_t number{};
if ( JSON_HEDLEY_UNLIKELY( ! ( get_number(input_format_t::msgpack, number) && sax->key_unsigned(number) ) ) ) return JSON_HEDLEY_LIKELY( get_number(input_format_t::msgpack, number) && sax->key_unsigned(number) );
{
return false;
}
break;
} }
case 0xD0: // int 8 case 0xD0: // int 8
{ {
std::int8_t number{}; std::int8_t number{};
if ( JSON_HEDLEY_UNLIKELY( ! ( get_number(input_format_t::msgpack, number) && sax->key_integer(number) ) ) ) return JSON_HEDLEY_LIKELY( get_number(input_format_t::msgpack, number) && sax->key_integer(number) );
{
return false;
}
break;
} }
case 0xD1: // int 16 case 0xD1: // int 16
{ {
std::int16_t number{}; std::int16_t number{};
if ( JSON_HEDLEY_UNLIKELY( ! ( get_number(input_format_t::msgpack, number) && sax->key_integer(number) ) ) ) return JSON_HEDLEY_LIKELY( get_number(input_format_t::msgpack, number) && sax->key_integer(number) );
{
return false;
}
break;
} }
case 0xD2: // int 32 case 0xD2: // int 32
{ {
std::int32_t number{}; std::int32_t number{};
if ( JSON_HEDLEY_UNLIKELY( ! ( get_number(input_format_t::msgpack, number) && sax->key_integer(number) ) ) ) return JSON_HEDLEY_LIKELY( get_number(input_format_t::msgpack, number) && sax->key_integer(number) );
{
return false;
}
break;
} }
case 0xD3: // int 64 case 0xD3: // int 64
{ {
std::int64_t number{}; std::int64_t number{};
if ( JSON_HEDLEY_UNLIKELY( ! ( get_number(input_format_t::msgpack, number) && sax->key_integer(number) ) ) ) return JSON_HEDLEY_LIKELY( get_number(input_format_t::msgpack, number) && sax->key_integer(number) );
{
return false;
} }
break;
case 0xDC: // array 16
{
std::uint16_t len{};
return get_number(input_format_t::msgpack, len) && sax->start_key_array(static_cast<std::size_t>(len)) && get_msgpack_array(static_cast<std::size_t>(len)) && sax->end_key_array();
}
case 0xDD: // array 32
{
std::uint32_t len{};
return get_number(input_format_t::msgpack, len) && sax->start_key_array(static_cast<std::size_t>(len)) && get_msgpack_array(static_cast<std::size_t>(len)) && sax->end_key_array();
} }
case 0xDE: // map 16 case 0xDE: // map 16
{ {
std::uint16_t len{}; std::uint16_t len{};
if ( JSON_HEDLEY_UNLIKELY( return JSON_HEDLEY_LIKELY(
! (
get_number(input_format_t::msgpack, len) get_number(input_format_t::msgpack, len)
&& &&
sax->start_key_object(len) sax->start_key_object(len)
@ -2212,21 +2196,14 @@ class binary_reader
get_msgpack_object() get_msgpack_object()
&& &&
sax->end_key_object() sax->end_key_object()
) );
)
)
{
return false;
}
break;
} }
case 0xDF: // map 32 case 0xDF: // map 32
{ {
std::uint32_t len{}; std::uint32_t len{};
if ( JSON_HEDLEY_UNLIKELY( return JSON_HEDLEY_LIKELY(
! (
get_number(input_format_t::msgpack, len) get_number(input_format_t::msgpack, len)
&& &&
sax->start_key_object(len) sax->start_key_object(len)
@ -2234,13 +2211,7 @@ class binary_reader
get_msgpack_object() get_msgpack_object()
&& &&
sax->end_key_object() sax->end_key_object()
) );
)
)
{
return false;
}
break;
} }
// negative fixint // negative fixint
@ -2276,13 +2247,7 @@ class binary_reader
case 0xFD: case 0xFD:
case 0xFE: case 0xFE:
case 0xFF: case 0xFF:
{ return JSON_HEDLEY_LIKELY( sax->key_integer( static_cast<std::int8_t>(current) ) );
if ( JSON_HEDLEY_UNLIKELY( ! sax->key_integer(static_cast<std::int8_t>(current)) ) )
{
return false;
}
break;
}
default: // anything else default: // anything else
{ {
@ -2291,15 +2256,6 @@ class binary_reader
exception_message(input_format_t::msgpack, concat("unsupported byte: 0x", last_token), "key"), nullptr)); exception_message(input_format_t::msgpack, concat("unsupported byte: 0x", last_token), "key"), nullptr));
} }
} }
if (JSON_HEDLEY_UNLIKELY(!parse_msgpack_internal()))
{
return false;
}
}
return true;
} }
//////////// ////////////

View File

@ -59,28 +59,55 @@ template<typename T, typename String>
using string_function_t = using string_function_t =
decltype(std::declval<T&>().string(std::declval<String&>())); decltype(std::declval<T&>().string(std::declval<String&>()));
template<typename T, typename Binary>
using binary_function_t =
decltype(std::declval<T&>().binary(std::declval<Binary&>()));
template<typename T>
using start_object_function_t =
decltype(std::declval<T&>().start_object(std::declval<std::size_t>()));
template<typename T, typename String> template<typename T, typename String>
using key_function_t = using key_function_t =
decltype(std::declval<T&>().key(std::declval<String&>())); decltype(std::declval<T&>().key(std::declval<String&>()));
template<typename T>
using end_object_function_t = decltype(std::declval<T&>().end_object()); template<typename T, typename Binary>
using binary_function_t =
decltype(std::declval<T&>().binary(std::declval<Binary&>()));
template<typename T, typename Binary>
using key_binary_function_t =
decltype(std::declval<T&>().key_binary(std::declval<Binary&>()));
template<typename T> template<typename T>
using start_array_function_t = using start_array_function_t =
decltype(std::declval<T&>().start_array(std::declval<std::size_t>())); decltype(std::declval<T&>().start_array(std::declval<std::size_t>()));
template<typename T>
using start_key_array_function_t =
decltype(std::declval<T&>().start_key_array(std::declval<std::size_t>()));
template<typename T> template<typename T>
using end_array_function_t = decltype(std::declval<T&>().end_array()); using end_array_function_t = decltype(std::declval<T&>().end_array());
template<typename T>
using end_key_array_function_t = decltype(std::declval<T&>().end_key_array());
template<typename T>
using start_object_function_t =
decltype(std::declval<T&>().start_object(std::declval<std::size_t>()));
template<typename T>
using start_key_object_function_t =
decltype(std::declval<T&>().start_key_object(std::declval<std::size_t>()));
template<typename T>
using end_object_function_t = decltype(std::declval<T&>().end_object());
template<typename T>
using end_key_object_function_t = decltype(std::declval<T&>().end_key_object());
template<typename T, typename Exception> template<typename T, typename Exception>
using parse_error_function_t = decltype(std::declval<T&>().parse_error( using parse_error_function_t = decltype(std::declval<T&>().parse_error(
std::declval<std::size_t>(), std::declval<const std::string&>(), std::declval<std::size_t>(), std::declval<const std::string&>(),
@ -94,11 +121,11 @@ template<typename SAX, typename BasicJsonType, typename IsTrue = conjunction<
is_detected_exact<bool, number_float_function_t, SAX, typename BasicJsonType::number_float_t, typename BasicJsonType::string_t>, is_detected_exact<bool, number_float_function_t, SAX, typename BasicJsonType::number_float_t, typename BasicJsonType::string_t>,
is_detected_exact<bool, string_function_t, SAX, typename BasicJsonType::string_t>, is_detected_exact<bool, string_function_t, SAX, typename BasicJsonType::string_t>,
is_detected_exact<bool, binary_function_t, SAX, typename BasicJsonType::binary_t>, is_detected_exact<bool, binary_function_t, SAX, typename BasicJsonType::binary_t>,
is_detected_exact<bool, start_object_function_t, SAX>,
is_detected_exact<bool, key_function_t, SAX, typename BasicJsonType::string_t>, is_detected_exact<bool, key_function_t, SAX, typename BasicJsonType::string_t>,
is_detected_exact<bool, end_object_function_t, SAX>,
is_detected_exact<bool, start_array_function_t, SAX>, is_detected_exact<bool, start_array_function_t, SAX>,
is_detected_exact<bool, end_array_function_t, SAX>, is_detected_exact<bool, end_array_function_t, SAX>,
is_detected_exact<bool, start_object_function_t, SAX>,
is_detected_exact<bool, end_object_function_t, SAX>,
is_detected_exact<bool, parse_error_function_t, SAX, typename BasicJsonType::exception> is_detected_exact<bool, parse_error_function_t, SAX, typename BasicJsonType::exception>
> >
> >
@ -116,7 +143,12 @@ template<typename SAX, typename BasicJsonType, typename IsTrue = conjunction<
is_detected_exact<bool, key_boolean_function_t, SAX>, is_detected_exact<bool, key_boolean_function_t, SAX>,
is_detected_exact<bool, key_number_integer_function_t, SAX, typename BasicJsonType::number_integer_t>, is_detected_exact<bool, key_number_integer_function_t, SAX, typename BasicJsonType::number_integer_t>,
is_detected_exact<bool, key_number_unsigned_function_t, SAX, typename BasicJsonType::number_unsigned_t>, is_detected_exact<bool, key_number_unsigned_function_t, SAX, typename BasicJsonType::number_unsigned_t>,
is_detected_exact<bool, key_number_float_function_t, SAX, typename BasicJsonType::number_float_t, typename BasicJsonType::string_t> is_detected_exact<bool, key_number_float_function_t, SAX, typename BasicJsonType::number_float_t, typename BasicJsonType::string_t>,
is_detected_exact<bool, key_binary_function_t, SAX, typename BasicJsonType::binary_t>,
is_detected_exact<bool, start_array_function_t, SAX>,
is_detected_exact<bool, end_array_function_t, SAX>,
is_detected_exact<bool, start_key_object_function_t, SAX>,
is_detected_exact<bool, end_key_object_function_t, SAX>
> >
> >
struct is_sax_msgpack : IsTrue struct is_sax_msgpack : IsTrue

File diff suppressed because it is too large Load Diff