mirror of
https://github.com/nlohmann/json.git
synced 2026-10-11 17:07:15 +00:00
Use and extend the detail helpers to remove duplicated code (#5783)
* Use and extend the detail helpers to remove duplicated code Library: - binary_reader: format bytes with hex_byte() instead of snprintf - add throw_type_must_be() for the 20 copies of type_error.302 - binary_reader: add last_byte_error()/unexpected_byte() for the 32 "parse error at the last read byte" sites (replaces bon8_error) - json_sax: add check_container_size() for out_of_range.408 and diagnostic_positions::set_container_start/_end() - json_pointer: add throw_no_parent() (405) and throw_unresolved() (404) Tests: - unit-class_parser uses the shared utils::SaxCountdown - move SaxEventLogger (and its ExitAfter* variants) from unit-class_parser and unit-deserialization into the new tests/src/test_sax.hpp Signed-off-by: Niels Lohmann <mail@nlohmann.me> * Factor out more repeated error paths and test boilerplate Library: - add throw_cannot_use_with() for the 34 copies of type_error.304-312 "cannot use X with Y" - iter_impl: add throw_cannot_get_value() (invalid_iterator.214) - parser: add syntax_error() for the 12 parse_error.101 sites - ordered_map: share the four at() bodies via at_impl() - json_sax_dom_callback_parser: add pop_container() for end_object() and end_array() - binary_reader: build the two UBJSON/BJData length-type messages with concat() and last_byte_error() Tests: - move same_value(), the NDEBUG guard, and step 0 (parse without exceptions) of the seven fuzzer drivers into tests/src/fuzzer_common.hpp Signed-off-by: Niels Lohmann <mail@nlohmann.me> * Name the exception ids and address review comments Add detail::exception_id, a scoped enum with one named enumerator per documented exception id, and use it for every id in the library. The create() functions get an overload for it; the int overloads stay for user code. Following the review of #5783: add binary_reader::invalid_byte() and length_type_error(), basic_json::throw_subscript_wrong_type(), move the fuzzer includes and the using-declaration into fuzzer_common.hpp, and rename test_sax.hpp to sax_event_loggers.hpp. Signed-off-by: Niels Lohmann <mail@nlohmann.me> * Silence -Wweak-vtables for the SAX event loggers The loggers moved from anonymous namespaces in the test files into sax_event_loggers.hpp, so clang now warns that their vtables are emitted in every translation unit. Signed-off-by: Niels Lohmann <mail@nlohmann.me> * Silence MSVC 2015 C4100 in parser::syntax_error for static SAX::parse_error Signed-off-by: Niels Lohmann <mail@nlohmann.me> * Inline invalid_byte() into its call sites The wrapper only fixed the message string of unexpected_byte(), which is the same kind of per-argument helper that was declined for throw_type_must_be(). Call unexpected_byte("invalid byte", ...) directly. Signed-off-by: Niels Lohmann <mail@nlohmann.me> --------- Signed-off-by: Niels Lohmann <mail@nlohmann.me>
This commit is contained in:
1 parent
f8b47ff6f6
commit
1649d9eda4
26 files changed
+1329
-1391
No files matched your search
@@ -48,7 +48,7 @@ inline void from_json(const BasicJsonType& j, typename std::nullptr_t& n)
|
||||
{
|
||||
if (JSON_HEDLEY_UNLIKELY(!j.is_null()))
|
||||
{
|
||||
JSON_THROW(type_error::create(302, concat("type must be null, but is ", j.type_name()), &j));
|
||||
throw_type_must_be("null", j);
|
||||
}
|
||||
n = nullptr;
|
||||
}
|
||||
@@ -102,7 +102,7 @@ void get_arithmetic_value(const BasicJsonType& j, ArithmeticType& val)
|
||||
case value_t::binary:
|
||||
case value_t::discarded:
|
||||
default:
|
||||
JSON_THROW(type_error::create(302, concat("type must be number, but is ", j.type_name()), &j));
|
||||
throw_type_must_be("number", j);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -111,7 +111,7 @@ inline void from_json(const BasicJsonType& j, typename BasicJsonType::boolean_t&
|
||||
{
|
||||
if (JSON_HEDLEY_UNLIKELY(!j.is_boolean()))
|
||||
{
|
||||
JSON_THROW(type_error::create(302, concat("type must be boolean, but is ", j.type_name()), &j));
|
||||
throw_type_must_be("boolean", j);
|
||||
}
|
||||
b = *j.template get_ptr<const typename BasicJsonType::boolean_t*>();
|
||||
}
|
||||
@@ -121,7 +121,7 @@ inline void from_json(const BasicJsonType& j, typename BasicJsonType::string_t&
|
||||
{
|
||||
if (JSON_HEDLEY_UNLIKELY(!j.is_string()))
|
||||
{
|
||||
JSON_THROW(type_error::create(302, concat("type must be string, but is ", j.type_name()), &j));
|
||||
throw_type_must_be("string", j);
|
||||
}
|
||||
s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
|
||||
}
|
||||
@@ -137,7 +137,7 @@ inline void from_json(const BasicJsonType& j, StringType& s)
|
||||
{
|
||||
if (JSON_HEDLEY_UNLIKELY(!j.is_string()))
|
||||
{
|
||||
JSON_THROW(type_error::create(302, concat("type must be string, but is ", j.type_name()), &j));
|
||||
throw_type_must_be("string", j);
|
||||
}
|
||||
|
||||
s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
|
||||
@@ -183,7 +183,7 @@ inline void from_json(const BasicJsonType& j, std::forward_list<T, Allocator>& l
|
||||
{
|
||||
if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
|
||||
{
|
||||
JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));
|
||||
throw_type_must_be("array", j);
|
||||
}
|
||||
l.clear();
|
||||
std::transform(j.rbegin(), j.rend(),
|
||||
@@ -200,7 +200,7 @@ inline void from_json(const BasicJsonType& j, std::valarray<T>& l)
|
||||
{
|
||||
if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
|
||||
{
|
||||
JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));
|
||||
throw_type_must_be("array", j);
|
||||
}
|
||||
l.resize(j.size());
|
||||
std::transform(j.begin(), j.end(), std::begin(l),
|
||||
@@ -305,7 +305,7 @@ void())
|
||||
{
|
||||
if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
|
||||
{
|
||||
JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));
|
||||
throw_type_must_be("array", j);
|
||||
}
|
||||
|
||||
from_json_array_impl(j, arr, priority_tag<3> {});
|
||||
@@ -324,7 +324,7 @@ auto from_json(const BasicJsonType& j, identity_tag<std::array<T, N>> tag)
|
||||
{
|
||||
if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
|
||||
{
|
||||
JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));
|
||||
throw_type_must_be("array", j);
|
||||
}
|
||||
|
||||
return from_json_inplace_array_impl(j, tag, make_index_sequence<N> {});
|
||||
@@ -335,7 +335,7 @@ inline void from_json(const BasicJsonType& j, typename BasicJsonType::binary_t&
|
||||
{
|
||||
if (JSON_HEDLEY_UNLIKELY(!j.is_binary()))
|
||||
{
|
||||
JSON_THROW(type_error::create(302, concat("type must be binary, but is ", j.type_name()), &j));
|
||||
throw_type_must_be("binary", j);
|
||||
}
|
||||
|
||||
bin = *j.template get_ptr<const typename BasicJsonType::binary_t*>();
|
||||
@@ -356,7 +356,7 @@ inline void from_json(const BasicJsonType& j, CompatibleArrayType& bin)
|
||||
}
|
||||
else
|
||||
{
|
||||
JSON_THROW(type_error::create(302, concat("type must be binary or array, but is ", j.type_name()), &j));
|
||||
throw_type_must_be("binary or array", j);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -377,7 +377,7 @@ inline void from_json(const BasicJsonType& j, ConstructibleObjectType& obj)
|
||||
{
|
||||
if (JSON_HEDLEY_UNLIKELY(!j.is_object()))
|
||||
{
|
||||
JSON_THROW(type_error::create(302, concat("type must be object, but is ", j.type_name()), &j));
|
||||
throw_type_must_be("object", j);
|
||||
}
|
||||
|
||||
ConstructibleObjectType ret;
|
||||
@@ -432,7 +432,7 @@ inline void from_json(const BasicJsonType& j, ArithmeticType& val)
|
||||
case value_t::binary:
|
||||
case value_t::discarded:
|
||||
default:
|
||||
JSON_THROW(type_error::create(302, concat("type must be number, but is ", j.type_name()), &j));
|
||||
throw_type_must_be("number", j);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -504,7 +504,7 @@ auto from_json(const BasicJsonType& j, TupleRelated&& t)
|
||||
{
|
||||
if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
|
||||
{
|
||||
JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));
|
||||
throw_type_must_be("array", j);
|
||||
}
|
||||
|
||||
return from_json_tuple_impl(j, std::forward<TupleRelated>(t), priority_tag<3> {});
|
||||
@@ -517,14 +517,14 @@ void from_json_pair_array_to_map(const BasicJsonType& j, MapType& m)
|
||||
{
|
||||
if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
|
||||
{
|
||||
JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));
|
||||
throw_type_must_be("array", j);
|
||||
}
|
||||
m.clear();
|
||||
for (const auto& p : j)
|
||||
{
|
||||
if (JSON_HEDLEY_UNLIKELY(!p.is_array()))
|
||||
{
|
||||
JSON_THROW(type_error::create(302, concat("type must be array, but is ", p.type_name()), &p));
|
||||
throw_type_must_be("array", p);
|
||||
}
|
||||
m.emplace(p.at(0).template get<typename MapType::key_type>(), p.at(1).template get<typename MapType::mapped_type>());
|
||||
}
|
||||
@@ -591,7 +591,7 @@ inline void from_json(const BasicJsonType& j, std_fs::path& p)
|
||||
{
|
||||
if (JSON_HEDLEY_UNLIKELY(!j.is_string()))
|
||||
{
|
||||
JSON_THROW(type_error::create(302, concat("type must be string, but is ", j.type_name()), &j));
|
||||
throw_type_must_be("string", j);
|
||||
}
|
||||
const auto& s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
|
||||
// Checking for C++20 standard or later can be insufficient in case the
|
||||
|
||||
@@ -414,13 +414,13 @@ inline void to_json(BasicJsonType& j, const EnumKeyedMap& map)
|
||||
BasicJsonType key = p.first;
|
||||
if (JSON_HEDLEY_UNLIKELY(!key.is_string()))
|
||||
{
|
||||
JSON_THROW(type_error::create(302, concat("type must be string, but is ", key.type_name()), &key));
|
||||
throw_type_must_be("string", key);
|
||||
}
|
||||
|
||||
auto& key_string = *key.template get_ptr<typename BasicJsonType::string_t*>();
|
||||
if (JSON_HEDLEY_UNLIKELY(!obj.emplace(key_string, BasicJsonType(p.second)).second))
|
||||
{
|
||||
JSON_THROW(type_error::create(318, concat("duplicate object key '", key_string, "'"), &key));
|
||||
JSON_THROW(type_error::create(exception_id::enum_key_duplicate, concat("duplicate object key '", key_string, "'"), &key));
|
||||
}
|
||||
}
|
||||
external_constructor<value_t::object>::construct(j, std::move(obj));
|
||||
|
||||
Reference in new issue
Block a user