Introduce JsonEncode helper function

It's just a wrapper around the `JsonEncoder` class to simplify its usage.
This commit is contained in:
Yonas Habteab 2025-04-22 09:48:09 +02:00
parent 9dd2e2a3ec
commit 2461e0415d
3 changed files with 53 additions and 6 deletions

View File

@ -287,14 +287,27 @@ private:
void FillCurrentTarget(Value value); void FillCurrentTarget(Value value);
}; };
String icinga::JsonEncode(const Value& value, bool pretty_print) String icinga::JsonEncode(const Value& value, bool prettify)
{ {
std::string output; std::string output;
JsonEncoder encoder(output, pretty_print); JsonEncoder encoder(output, prettify);
encoder.Encode(value); encoder.Encode(value);
return String(std::move(output)); return String(std::move(output));
} }
/**
* Serializes an Icinga Value into a JSON object and writes it to the given output stream.
*
* @param value The value to be JSON serialized.
* @param os The output stream to write the JSON data to.
* @param prettify Whether to pretty print the serialized JSON.
*/
void icinga::JsonEncode(const Value& value, std::ostream& os, bool prettify)
{
JsonEncoder encoder(os, prettify);
encoder.Encode(value);
}
Value icinga::JsonDecode(const String& data) Value icinga::JsonDecode(const String& data)
{ {
String sanitized (Utility::ValidateUTF8(data)); String sanitized (Utility::ValidateUTF8(data));

View File

@ -107,7 +107,8 @@ private:
nlohmann::detail::output_adapter_t<char> m_Writer; nlohmann::detail::output_adapter_t<char> m_Writer;
}; };
String JsonEncode(const Value& value, bool pretty_print = false); String JsonEncode(const Value& value, bool prettify = false);
void JsonEncode(const Value& value, std::ostream& os, bool prettify = false);
Value JsonDecode(const String& data); Value JsonDecode(const String& data);
} }

View File

@ -4,10 +4,13 @@
#include "base/function.hpp" #include "base/function.hpp"
#include "base/namespace.hpp" #include "base/namespace.hpp"
#include "base/array.hpp" #include "base/array.hpp"
#include "base/generator.hpp"
#include "base/objectlock.hpp" #include "base/objectlock.hpp"
#include "base/json.hpp" #include "base/json.hpp"
#include <boost/algorithm/string/replace.hpp> #include <boost/algorithm/string/replace.hpp>
#include <BoostTestTargetConfig.h> #include <BoostTestTargetConfig.h>
#include <limits>
#include <cmath>
using namespace icinga; using namespace icinga;
@ -15,26 +18,51 @@ BOOST_AUTO_TEST_SUITE(base_json)
BOOST_AUTO_TEST_CASE(encode) BOOST_AUTO_TEST_CASE(encode)
{ {
auto generate = []() -> std::optional<Value> {
static int count = 0;
if (++count == 4) {
count = 0;
return std::nullopt;
}
return Value(count);
};
Dictionary::Ptr input (new Dictionary({ Dictionary::Ptr input (new Dictionary({
{ "array", new Array({ new Namespace() }) }, { "array", new Array({ new Namespace() }) },
{ "false", false }, { "false", false },
{ "float", -1.25 }, // Use double max value to test JSON encoding of large numbers and trigger boost numeric_cast exceptions
{ "max_double", std::numeric_limits<double>::max() },
// Test the maximum number that can be exact represented by a double is 2^64-2048.
{ "max_int_in_double", std::nextafter(std::pow(2, 64), 0.0) },
{ "float", -1.25f },
{ "float_without_fraction", 23.0f },
{ "fx", new Function("<test>", []() {}) }, { "fx", new Function("<test>", []() {}) },
{ "int", -42 }, { "int", -42 },
{ "null", Value() }, { "null", Value() },
{ "string", "LF\nTAB\tAUml\xC3\xA4Ill\xC3" }, { "string", "LF\nTAB\tAUml\xC3\xA4Ill\xC3" },
{ "true", true }, { "true", true },
{ "uint", 23u } { "uint", 23u },
{ "generator", new ValueGenerator(generate) },
{ "empty_generator", new ValueGenerator([]() -> std::optional<Value> { return std::nullopt; }) },
})); }));
String output (R"EOF({ String output (R"EOF({
"array": [ "array": [
{} {}
], ],
"empty_generator": [],
"false": false, "false": false,
"float": -1.25, "float": -1.25,
"float_without_fraction": 23,
"fx": "Object of type 'Function'", "fx": "Object of type 'Function'",
"generator": [
1,
2,
3
],
"int": -42, "int": -42,
"max_double": 1.7976931348623157e+308,
"max_int_in_double": 18446744073709549568,
"null": null, "null": null,
"string": "LF\nTAB\tAUml\u00e4Ill\ufffd", "string": "LF\nTAB\tAUml\u00e4Ill\ufffd",
"true": true, "true": true,
@ -42,7 +70,12 @@ BOOST_AUTO_TEST_CASE(encode)
} }
)EOF"); )EOF");
BOOST_CHECK(JsonEncode(input, true) == output); auto got(JsonEncode(input, true));
BOOST_CHECK_EQUAL(output, got);
std::ostringstream oss;
JsonEncode(input, oss, true);
BOOST_CHECK_EQUAL(output, oss.str());
boost::algorithm::replace_all(output, " ", ""); boost::algorithm::replace_all(output, " ", "");
boost::algorithm::replace_all(output, "Objectoftype'Function'", "Object of type 'Function'"); boost::algorithm::replace_all(output, "Objectoftype'Function'", "Object of type 'Function'");