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);
};
String icinga::JsonEncode(const Value& value, bool pretty_print)
String icinga::JsonEncode(const Value& value, bool prettify)
{
std::string output;
JsonEncoder encoder(output, pretty_print);
JsonEncoder encoder(output, prettify);
encoder.Encode(value);
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)
{
String sanitized (Utility::ValidateUTF8(data));

View File

@ -107,7 +107,8 @@ private:
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);
}

View File

@ -4,10 +4,13 @@
#include "base/function.hpp"
#include "base/namespace.hpp"
#include "base/array.hpp"
#include "base/generator.hpp"
#include "base/objectlock.hpp"
#include "base/json.hpp"
#include <boost/algorithm/string/replace.hpp>
#include <BoostTestTargetConfig.h>
#include <limits>
#include <cmath>
using namespace icinga;
@ -15,26 +18,51 @@ BOOST_AUTO_TEST_SUITE(base_json)
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({
{ "array", new Array({ new Namespace() }) },
{ "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>", []() {}) },
{ "int", -42 },
{ "null", Value() },
{ "string", "LF\nTAB\tAUml\xC3\xA4Ill\xC3" },
{ "true", true },
{ "uint", 23u }
{ "uint", 23u },
{ "generator", new ValueGenerator(generate) },
{ "empty_generator", new ValueGenerator([]() -> std::optional<Value> { return std::nullopt; }) },
}));
String output (R"EOF({
"array": [
{}
],
"empty_generator": [],
"false": false,
"float": -1.25,
"float_without_fraction": 23,
"fx": "Object of type 'Function'",
"generator": [
1,
2,
3
],
"int": -42,
"max_double": 1.7976931348623157e+308,
"max_int_in_double": 18446744073709549568,
"null": null,
"string": "LF\nTAB\tAUml\u00e4Ill\ufffd",
"true": true,
@ -42,7 +70,12 @@ BOOST_AUTO_TEST_CASE(encode)
}
)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, "Objectoftype'Function'", "Object of type 'Function'");