mirror of
https://github.com/open-source-parsers/jsoncpp.git
synced 2025-01-19 16:56:08 +01:00
commit
772f634548
@ -133,17 +133,20 @@ std::string valueToString(UInt value) {
|
|||||||
|
|
||||||
#endif // # if defined(JSON_HAS_INT64)
|
#endif // # if defined(JSON_HAS_INT64)
|
||||||
|
|
||||||
std::string valueToString(double value, bool useSpecialFloats) {
|
std::string valueToString(double value, bool useSpecialFloats, unsigned int precision) {
|
||||||
// Allocate a buffer that is more than large enough to store the 16 digits of
|
// Allocate a buffer that is more than large enough to store the 16 digits of
|
||||||
// precision requested below.
|
// precision requested below.
|
||||||
char buffer[32];
|
char buffer[32];
|
||||||
int len = -1;
|
int len = -1;
|
||||||
|
|
||||||
|
char formatString[6];
|
||||||
|
sprintf(formatString, "%%.%dg", precision);
|
||||||
|
|
||||||
// Print into the buffer. We need not request the alternative representation
|
// Print into the buffer. We need not request the alternative representation
|
||||||
// that always has a decimal point because JSON doesn't distingish the
|
// that always has a decimal point because JSON doesn't distingish the
|
||||||
// concepts of reals and integers.
|
// concepts of reals and integers.
|
||||||
if (isfinite(value)) {
|
if (isfinite(value)) {
|
||||||
len = snprintf(buffer, sizeof(buffer), "%.17g", value);
|
len = snprintf(buffer, sizeof(buffer), formatString, value);
|
||||||
} else {
|
} else {
|
||||||
// IEEE standard states that NaN values will not compare to themselves
|
// IEEE standard states that NaN values will not compare to themselves
|
||||||
if (value != value) {
|
if (value != value) {
|
||||||
@ -160,7 +163,7 @@ std::string valueToString(double value, bool useSpecialFloats) {
|
|||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string valueToString(double value) { return valueToString(value, false); }
|
std::string valueToString(double value) { return valueToString(value, false, 17); }
|
||||||
|
|
||||||
std::string valueToString(bool value) { return value ? "true" : "false"; }
|
std::string valueToString(bool value) { return value ? "true" : "false"; }
|
||||||
|
|
||||||
@ -832,7 +835,8 @@ struct BuiltStyledStreamWriter : public StreamWriter
|
|||||||
std::string const& colonSymbol,
|
std::string const& colonSymbol,
|
||||||
std::string const& nullSymbol,
|
std::string const& nullSymbol,
|
||||||
std::string const& endingLineFeedSymbol,
|
std::string const& endingLineFeedSymbol,
|
||||||
bool useSpecialFloats);
|
bool useSpecialFloats,
|
||||||
|
unsigned int precision);
|
||||||
int write(Value const& root, std::ostream* sout) override;
|
int write(Value const& root, std::ostream* sout) override;
|
||||||
private:
|
private:
|
||||||
void writeValue(Value const& value);
|
void writeValue(Value const& value);
|
||||||
@ -860,6 +864,7 @@ private:
|
|||||||
bool addChildValues_ : 1;
|
bool addChildValues_ : 1;
|
||||||
bool indented_ : 1;
|
bool indented_ : 1;
|
||||||
bool useSpecialFloats_ : 1;
|
bool useSpecialFloats_ : 1;
|
||||||
|
unsigned int precision_;
|
||||||
};
|
};
|
||||||
BuiltStyledStreamWriter::BuiltStyledStreamWriter(
|
BuiltStyledStreamWriter::BuiltStyledStreamWriter(
|
||||||
std::string const& indentation,
|
std::string const& indentation,
|
||||||
@ -867,7 +872,8 @@ BuiltStyledStreamWriter::BuiltStyledStreamWriter(
|
|||||||
std::string const& colonSymbol,
|
std::string const& colonSymbol,
|
||||||
std::string const& nullSymbol,
|
std::string const& nullSymbol,
|
||||||
std::string const& endingLineFeedSymbol,
|
std::string const& endingLineFeedSymbol,
|
||||||
bool useSpecialFloats)
|
bool useSpecialFloats,
|
||||||
|
unsigned int precision)
|
||||||
: rightMargin_(74)
|
: rightMargin_(74)
|
||||||
, indentation_(indentation)
|
, indentation_(indentation)
|
||||||
, cs_(cs)
|
, cs_(cs)
|
||||||
@ -877,6 +883,7 @@ BuiltStyledStreamWriter::BuiltStyledStreamWriter(
|
|||||||
, addChildValues_(false)
|
, addChildValues_(false)
|
||||||
, indented_(false)
|
, indented_(false)
|
||||||
, useSpecialFloats_(useSpecialFloats)
|
, useSpecialFloats_(useSpecialFloats)
|
||||||
|
, precision_(precision)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
int BuiltStyledStreamWriter::write(Value const& root, std::ostream* sout)
|
int BuiltStyledStreamWriter::write(Value const& root, std::ostream* sout)
|
||||||
@ -906,7 +913,7 @@ void BuiltStyledStreamWriter::writeValue(Value const& value) {
|
|||||||
pushValue(valueToString(value.asLargestUInt()));
|
pushValue(valueToString(value.asLargestUInt()));
|
||||||
break;
|
break;
|
||||||
case realValue:
|
case realValue:
|
||||||
pushValue(valueToString(value.asDouble(), useSpecialFloats_));
|
pushValue(valueToString(value.asDouble(), useSpecialFloats_, precision_));
|
||||||
break;
|
break;
|
||||||
case stringValue:
|
case stringValue:
|
||||||
{
|
{
|
||||||
@ -1121,6 +1128,7 @@ StreamWriter* StreamWriterBuilder::newStreamWriter() const
|
|||||||
bool eyc = settings_["enableYAMLCompatibility"].asBool();
|
bool eyc = settings_["enableYAMLCompatibility"].asBool();
|
||||||
bool dnp = settings_["dropNullPlaceholders"].asBool();
|
bool dnp = settings_["dropNullPlaceholders"].asBool();
|
||||||
bool usf = settings_["useSpecialFloats"].asBool();
|
bool usf = settings_["useSpecialFloats"].asBool();
|
||||||
|
unsigned int pre = settings_["precision"].asUInt();
|
||||||
CommentStyle::Enum cs = CommentStyle::All;
|
CommentStyle::Enum cs = CommentStyle::All;
|
||||||
if (cs_str == "All") {
|
if (cs_str == "All") {
|
||||||
cs = CommentStyle::All;
|
cs = CommentStyle::All;
|
||||||
@ -1139,10 +1147,11 @@ StreamWriter* StreamWriterBuilder::newStreamWriter() const
|
|||||||
if (dnp) {
|
if (dnp) {
|
||||||
nullSymbol = "";
|
nullSymbol = "";
|
||||||
}
|
}
|
||||||
|
if (pre > 17) pre = 17;
|
||||||
std::string endingLineFeedSymbol = "";
|
std::string endingLineFeedSymbol = "";
|
||||||
return new BuiltStyledStreamWriter(
|
return new BuiltStyledStreamWriter(
|
||||||
indentation, cs,
|
indentation, cs,
|
||||||
colonSymbol, nullSymbol, endingLineFeedSymbol, usf);
|
colonSymbol, nullSymbol, endingLineFeedSymbol, usf, pre);
|
||||||
}
|
}
|
||||||
static void getValidWriterKeys(std::set<std::string>* valid_keys)
|
static void getValidWriterKeys(std::set<std::string>* valid_keys)
|
||||||
{
|
{
|
||||||
@ -1152,6 +1161,7 @@ static void getValidWriterKeys(std::set<std::string>* valid_keys)
|
|||||||
valid_keys->insert("enableYAMLCompatibility");
|
valid_keys->insert("enableYAMLCompatibility");
|
||||||
valid_keys->insert("dropNullPlaceholders");
|
valid_keys->insert("dropNullPlaceholders");
|
||||||
valid_keys->insert("useSpecialFloats");
|
valid_keys->insert("useSpecialFloats");
|
||||||
|
valid_keys->insert("precision");
|
||||||
}
|
}
|
||||||
bool StreamWriterBuilder::validate(Json::Value* invalid) const
|
bool StreamWriterBuilder::validate(Json::Value* invalid) const
|
||||||
{
|
{
|
||||||
@ -1183,6 +1193,7 @@ void StreamWriterBuilder::setDefaults(Json::Value* settings)
|
|||||||
(*settings)["enableYAMLCompatibility"] = false;
|
(*settings)["enableYAMLCompatibility"] = false;
|
||||||
(*settings)["dropNullPlaceholders"] = false;
|
(*settings)["dropNullPlaceholders"] = false;
|
||||||
(*settings)["useSpecialFloats"] = false;
|
(*settings)["useSpecialFloats"] = false;
|
||||||
|
(*settings)["precision"] = 17;
|
||||||
//! [StreamWriterBuilderDefaults]
|
//! [StreamWriterBuilderDefaults]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1675,6 +1675,43 @@ JSONTEST_FIXTURE(ValueTest, specialFloats) {
|
|||||||
JSONTEST_ASSERT_STRING_EQUAL(expected, result);
|
JSONTEST_ASSERT_STRING_EQUAL(expected, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
JSONTEST_FIXTURE(ValueTest, precision) {
|
||||||
|
Json::StreamWriterBuilder b;
|
||||||
|
b.settings_["precision"] = 5;
|
||||||
|
|
||||||
|
Json::Value v = 100.0/3;
|
||||||
|
std::string expected = "33.333";
|
||||||
|
std::string result = Json::writeString(b, v);
|
||||||
|
JSONTEST_ASSERT_STRING_EQUAL(expected, result);
|
||||||
|
|
||||||
|
v = 0.25000000;
|
||||||
|
expected = "0.25";
|
||||||
|
result = Json::writeString(b, v);
|
||||||
|
JSONTEST_ASSERT_STRING_EQUAL(expected, result);
|
||||||
|
|
||||||
|
v = 0.2563456;
|
||||||
|
expected = "0.25635";
|
||||||
|
result = Json::writeString(b, v);
|
||||||
|
JSONTEST_ASSERT_STRING_EQUAL(expected, result);
|
||||||
|
|
||||||
|
b.settings_["precision"] = 1;
|
||||||
|
expected = "0.3";
|
||||||
|
result = Json::writeString(b, v);
|
||||||
|
JSONTEST_ASSERT_STRING_EQUAL(expected, result);
|
||||||
|
|
||||||
|
b.settings_["precision"] = 17;
|
||||||
|
v = 1234857476305.256345694873740545068;
|
||||||
|
expected = "1234857476305.2563";
|
||||||
|
result = Json::writeString(b, v);
|
||||||
|
JSONTEST_ASSERT_STRING_EQUAL(expected, result);
|
||||||
|
|
||||||
|
b.settings_["precision"] = 24;
|
||||||
|
v = 0.256345694873740545068;
|
||||||
|
expected = "0.25634569487374054";
|
||||||
|
result = Json::writeString(b, v);
|
||||||
|
JSONTEST_ASSERT_STRING_EQUAL(expected, result);
|
||||||
|
}
|
||||||
|
|
||||||
struct WriterTest : JsonTest::TestCase {};
|
struct WriterTest : JsonTest::TestCase {};
|
||||||
|
|
||||||
JSONTEST_FIXTURE(WriterTest, dropNullPlaceholders) {
|
JSONTEST_FIXTURE(WriterTest, dropNullPlaceholders) {
|
||||||
@ -2489,6 +2526,7 @@ int main(int argc, const char* argv[]) {
|
|||||||
JSONTEST_REGISTER_FIXTURE(runner, ValueTest, zeroes);
|
JSONTEST_REGISTER_FIXTURE(runner, ValueTest, zeroes);
|
||||||
JSONTEST_REGISTER_FIXTURE(runner, ValueTest, zeroesInKeys);
|
JSONTEST_REGISTER_FIXTURE(runner, ValueTest, zeroesInKeys);
|
||||||
JSONTEST_REGISTER_FIXTURE(runner, ValueTest, specialFloats);
|
JSONTEST_REGISTER_FIXTURE(runner, ValueTest, specialFloats);
|
||||||
|
JSONTEST_REGISTER_FIXTURE(runner, ValueTest, precision);
|
||||||
|
|
||||||
JSONTEST_REGISTER_FIXTURE(runner, WriterTest, dropNullPlaceholders);
|
JSONTEST_REGISTER_FIXTURE(runner, WriterTest, dropNullPlaceholders);
|
||||||
JSONTEST_REGISTER_FIXTURE(runner, StreamWriterTest, dropNullPlaceholders);
|
JSONTEST_REGISTER_FIXTURE(runner, StreamWriterTest, dropNullPlaceholders);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user