Merge 59192e9ed9 into b2306145e1
This commit is contained in:
commit
5484d3c872
@ -109,6 +109,46 @@ class serializer
|
||||
const bool ensure_ascii,
|
||||
const unsigned int indent_step,
|
||||
const unsigned int current_indent = 0)
|
||||
{
|
||||
auto predicate = [pretty_print](const BasicJsonType&, int)
|
||||
{
|
||||
return pretty_print;
|
||||
};
|
||||
dump_configured(val, ensure_ascii, indent_step, current_indent, predicate);
|
||||
}
|
||||
|
||||
/*!
|
||||
@brief internal implementation of the serialization function
|
||||
|
||||
This function is called by the public member function dump and organizes
|
||||
the serialization internally. The indentation level is propagated as
|
||||
additional parameter. In case of arrays and objects, the function is
|
||||
called recursively. If uses a predicate to decide whether to avoid pretty
|
||||
printing a subtree. If the predicate returns false, pretty printing is
|
||||
avoided for the whole tree, otherwise the current value is pretty printed
|
||||
and the function is reevaluated for nested values.
|
||||
|
||||
- strings and object keys are escaped using `escape_string()`
|
||||
- integer numbers are converted implicitly via `operator<<`
|
||||
- floating-point numbers are converted to a string using `"%g"` format
|
||||
- binary values are serialized as objects containing the subtype and the
|
||||
byte array
|
||||
|
||||
@param[in] val value to serialize
|
||||
@param[in] pretty_print whether the output shall be pretty-printed based
|
||||
on the value and current identation
|
||||
@param[in] ensure_ascii If @a ensure_ascii is true, all non-ASCII characters
|
||||
in the output are escaped with `\uXXXX` sequences, and the result consists
|
||||
of ASCII characters only.
|
||||
@param[in] indent_step the indent level
|
||||
@param[in] current_indent the current indent level (only used internally)
|
||||
*/
|
||||
template<typename PrettyPrintPredicate>
|
||||
void dump_configured(const BasicJsonType& val,
|
||||
const bool ensure_ascii,
|
||||
const unsigned int indent_step,
|
||||
const unsigned int current_indent,
|
||||
const PrettyPrintPredicate& pretty_print)
|
||||
{
|
||||
switch (val.m_type)
|
||||
{
|
||||
@ -120,7 +160,7 @@ class serializer
|
||||
return;
|
||||
}
|
||||
|
||||
if (pretty_print)
|
||||
if (pretty_print(val, static_cast<int>(current_indent)))
|
||||
{
|
||||
o->write_characters("{\n", 2);
|
||||
|
||||
@ -139,7 +179,7 @@ class serializer
|
||||
o->write_character('\"');
|
||||
dump_escaped(i->first, ensure_ascii);
|
||||
o->write_characters("\": ", 3);
|
||||
dump(i->second, true, ensure_ascii, indent_step, new_indent);
|
||||
dump_configured(i->second, ensure_ascii, indent_step, new_indent, pretty_print);
|
||||
o->write_characters(",\n", 2);
|
||||
}
|
||||
|
||||
@ -150,7 +190,7 @@ class serializer
|
||||
o->write_character('\"');
|
||||
dump_escaped(i->first, ensure_ascii);
|
||||
o->write_characters("\": ", 3);
|
||||
dump(i->second, true, ensure_ascii, indent_step, new_indent);
|
||||
dump_configured(i->second, ensure_ascii, indent_step, new_indent, pretty_print);
|
||||
|
||||
o->write_character('\n');
|
||||
o->write_characters(indent_string.c_str(), current_indent);
|
||||
@ -193,7 +233,7 @@ class serializer
|
||||
return;
|
||||
}
|
||||
|
||||
if (pretty_print)
|
||||
if (pretty_print(val, static_cast<int>(current_indent)))
|
||||
{
|
||||
o->write_characters("[\n", 2);
|
||||
|
||||
@ -206,17 +246,18 @@ class serializer
|
||||
|
||||
// first n-1 elements
|
||||
for (auto i = val.m_value.array->cbegin();
|
||||
i != val.m_value.array->cend() - 1; ++i)
|
||||
i != val.m_value.array->cend() - 1;
|
||||
++i)
|
||||
{
|
||||
o->write_characters(indent_string.c_str(), new_indent);
|
||||
dump(*i, true, ensure_ascii, indent_step, new_indent);
|
||||
dump_configured(*i, ensure_ascii, indent_step, new_indent, pretty_print);
|
||||
o->write_characters(",\n", 2);
|
||||
}
|
||||
|
||||
// last element
|
||||
JSON_ASSERT(!val.m_value.array->empty());
|
||||
o->write_characters(indent_string.c_str(), new_indent);
|
||||
dump(val.m_value.array->back(), true, ensure_ascii, indent_step, new_indent);
|
||||
dump_configured(val.m_value.array->back(), ensure_ascii, indent_step, new_indent, pretty_print);
|
||||
|
||||
o->write_character('\n');
|
||||
o->write_characters(indent_string.c_str(), current_indent);
|
||||
@ -254,7 +295,7 @@ class serializer
|
||||
|
||||
case value_t::binary:
|
||||
{
|
||||
if (pretty_print)
|
||||
if (pretty_print(val, static_cast<int>(current_indent)))
|
||||
{
|
||||
o->write_characters("{\n", 2);
|
||||
|
||||
|
||||
@ -1266,13 +1266,32 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
const char indent_char = ' ',
|
||||
const bool ensure_ascii = false,
|
||||
const error_handler_t error_handler = error_handler_t::strict) const
|
||||
{
|
||||
return dump(indent, indent_char, ensure_ascii, error_handler, [](basic_json const&, int)
|
||||
{
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
/// @name object inspection
|
||||
/// Functions to inspect the type of a JSON value.
|
||||
/// @{
|
||||
|
||||
/// @brief serialization
|
||||
/// @sa https://json.nlohmann.me/api/basic_json/dump/
|
||||
template <typename PrettyPrintPredicate>
|
||||
string_t dump(const int indent,
|
||||
const char indent_char,
|
||||
const bool ensure_ascii,
|
||||
const error_handler_t error_handler,
|
||||
const PrettyPrintPredicate& pretty_print) const
|
||||
{
|
||||
string_t result;
|
||||
serializer s(detail::output_adapter<char, string_t>(result), indent_char, error_handler);
|
||||
|
||||
if (indent >= 0)
|
||||
{
|
||||
s.dump(*this, true, ensure_ascii, static_cast<unsigned int>(indent));
|
||||
s.dump_configured(*this, ensure_ascii, static_cast<unsigned int>(indent), 0, pretty_print);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@ -18031,6 +18031,46 @@ class serializer
|
||||
const bool ensure_ascii,
|
||||
const unsigned int indent_step,
|
||||
const unsigned int current_indent = 0)
|
||||
{
|
||||
auto predicate = [pretty_print](const BasicJsonType&, int)
|
||||
{
|
||||
return pretty_print;
|
||||
};
|
||||
dump_configured(val, ensure_ascii, indent_step, current_indent, predicate);
|
||||
}
|
||||
|
||||
/*!
|
||||
@brief internal implementation of the serialization function
|
||||
|
||||
This function is called by the public member function dump and organizes
|
||||
the serialization internally. The indentation level is propagated as
|
||||
additional parameter. In case of arrays and objects, the function is
|
||||
called recursively. If uses a predicate to decide whether to avoid pretty
|
||||
printing a subtree. If the predicate returns false, pretty printing is
|
||||
avoided for the whole tree, otherwise the current value is pretty printed
|
||||
and the function is reevaluated for nested values.
|
||||
|
||||
- strings and object keys are escaped using `escape_string()`
|
||||
- integer numbers are converted implicitly via `operator<<`
|
||||
- floating-point numbers are converted to a string using `"%g"` format
|
||||
- binary values are serialized as objects containing the subtype and the
|
||||
byte array
|
||||
|
||||
@param[in] val value to serialize
|
||||
@param[in] pretty_print whether the output shall be pretty-printed based
|
||||
on the value and current identation
|
||||
@param[in] ensure_ascii If @a ensure_ascii is true, all non-ASCII characters
|
||||
in the output are escaped with `\uXXXX` sequences, and the result consists
|
||||
of ASCII characters only.
|
||||
@param[in] indent_step the indent level
|
||||
@param[in] current_indent the current indent level (only used internally)
|
||||
*/
|
||||
template<typename PrettyPrintPredicate>
|
||||
void dump_configured(const BasicJsonType& val,
|
||||
const bool ensure_ascii,
|
||||
const unsigned int indent_step,
|
||||
const unsigned int current_indent,
|
||||
const PrettyPrintPredicate& pretty_print)
|
||||
{
|
||||
switch (val.m_type)
|
||||
{
|
||||
@ -18042,7 +18082,7 @@ class serializer
|
||||
return;
|
||||
}
|
||||
|
||||
if (pretty_print)
|
||||
if (pretty_print(val, static_cast<int>(current_indent)))
|
||||
{
|
||||
o->write_characters("{\n", 2);
|
||||
|
||||
@ -18061,7 +18101,7 @@ class serializer
|
||||
o->write_character('\"');
|
||||
dump_escaped(i->first, ensure_ascii);
|
||||
o->write_characters("\": ", 3);
|
||||
dump(i->second, true, ensure_ascii, indent_step, new_indent);
|
||||
dump_configured(i->second, ensure_ascii, indent_step, new_indent, pretty_print);
|
||||
o->write_characters(",\n", 2);
|
||||
}
|
||||
|
||||
@ -18072,7 +18112,7 @@ class serializer
|
||||
o->write_character('\"');
|
||||
dump_escaped(i->first, ensure_ascii);
|
||||
o->write_characters("\": ", 3);
|
||||
dump(i->second, true, ensure_ascii, indent_step, new_indent);
|
||||
dump_configured(i->second, ensure_ascii, indent_step, new_indent, pretty_print);
|
||||
|
||||
o->write_character('\n');
|
||||
o->write_characters(indent_string.c_str(), current_indent);
|
||||
@ -18115,7 +18155,7 @@ class serializer
|
||||
return;
|
||||
}
|
||||
|
||||
if (pretty_print)
|
||||
if (pretty_print(val, static_cast<int>(current_indent)))
|
||||
{
|
||||
o->write_characters("[\n", 2);
|
||||
|
||||
@ -18128,17 +18168,18 @@ class serializer
|
||||
|
||||
// first n-1 elements
|
||||
for (auto i = val.m_value.array->cbegin();
|
||||
i != val.m_value.array->cend() - 1; ++i)
|
||||
i != val.m_value.array->cend() - 1;
|
||||
++i)
|
||||
{
|
||||
o->write_characters(indent_string.c_str(), new_indent);
|
||||
dump(*i, true, ensure_ascii, indent_step, new_indent);
|
||||
dump_configured(*i, ensure_ascii, indent_step, new_indent, pretty_print);
|
||||
o->write_characters(",\n", 2);
|
||||
}
|
||||
|
||||
// last element
|
||||
JSON_ASSERT(!val.m_value.array->empty());
|
||||
o->write_characters(indent_string.c_str(), new_indent);
|
||||
dump(val.m_value.array->back(), true, ensure_ascii, indent_step, new_indent);
|
||||
dump_configured(val.m_value.array->back(), ensure_ascii, indent_step, new_indent, pretty_print);
|
||||
|
||||
o->write_character('\n');
|
||||
o->write_characters(indent_string.c_str(), current_indent);
|
||||
@ -18176,7 +18217,7 @@ class serializer
|
||||
|
||||
case value_t::binary:
|
||||
{
|
||||
if (pretty_print)
|
||||
if (pretty_print(val, static_cast<int>(current_indent)))
|
||||
{
|
||||
o->write_characters("{\n", 2);
|
||||
|
||||
@ -20482,13 +20523,32 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
const char indent_char = ' ',
|
||||
const bool ensure_ascii = false,
|
||||
const error_handler_t error_handler = error_handler_t::strict) const
|
||||
{
|
||||
return dump(indent, indent_char, ensure_ascii, error_handler, [](basic_json const&, int)
|
||||
{
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
/// @name object inspection
|
||||
/// Functions to inspect the type of a JSON value.
|
||||
/// @{
|
||||
|
||||
/// @brief serialization
|
||||
/// @sa https://json.nlohmann.me/api/basic_json/dump/
|
||||
template <typename PrettyPrintPredicate>
|
||||
string_t dump(const int indent,
|
||||
const char indent_char,
|
||||
const bool ensure_ascii,
|
||||
const error_handler_t error_handler,
|
||||
const PrettyPrintPredicate& pretty_print) const
|
||||
{
|
||||
string_t result;
|
||||
serializer s(detail::output_adapter<char, string_t>(result), indent_char, error_handler);
|
||||
|
||||
if (indent >= 0)
|
||||
{
|
||||
s.dump(*this, true, ensure_ascii, static_cast<unsigned int>(indent));
|
||||
s.dump_configured(*this, ensure_ascii, static_cast<unsigned int>(indent), 0, pretty_print);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@ -79,6 +79,20 @@ TEST_CASE("serialization")
|
||||
|
||||
SECTION("dump")
|
||||
{
|
||||
SECTION("no pretty primitive arrays")
|
||||
{
|
||||
auto pretty_print = [](json const & x, int)
|
||||
{
|
||||
return !x.is_array() || std::any_of(x.cbegin(), x.cend(), [](json const & e)
|
||||
{
|
||||
return !e.is_primitive();
|
||||
});
|
||||
};
|
||||
|
||||
const json j = {{"foo", {1, 2, 3}}};
|
||||
CHECK(j.dump(1, ' ', false, json::error_handler_t::strict, pretty_print) == "{\n \"foo\": [1,2,3]\n}");
|
||||
}
|
||||
|
||||
SECTION("invalid character")
|
||||
{
|
||||
const json j = "ä\xA9ü";
|
||||
|
||||
Loading…
Reference in New Issue
Block a user