@@ -118,21 +118,29 @@ JSONCPP_STRING valueToString(UInt value) {
118
118
#endif // # if defined(JSON_HAS_INT64)
119
119
120
120
namespace {
121
- JSONCPP_STRING valueToString (double value, bool useSpecialFloats, unsigned int precision) {
121
+ JSONCPP_STRING valueToString (double value, bool useSpecialFloats, unsigned int precision, PrecisionType precisionType ) {
122
122
// Allocate a buffer that is more than large enough to store the 16 digits of
123
123
// precision requested below.
124
124
char buffer[36 ];
125
125
int len = -1 ;
126
126
127
127
char formatString[15 ];
128
- snprintf (formatString, sizeof (formatString), " %%.%ug" , precision);
128
+ if (precisionType == PrecisionType::significantDigits) {
129
+ snprintf (formatString, sizeof (formatString), " %%.%ug" , precision);
130
+ } else {
131
+ snprintf (formatString, sizeof (formatString), " %%.%uf" , precision);
132
+ }
129
133
130
134
// Print into the buffer. We need not request the alternative representation
131
135
// that always has a decimal point because JSON doesn't distinguish the
132
136
// concepts of reals and integers.
133
137
if (isfinite (value)) {
134
138
len = snprintf (buffer, sizeof (buffer), formatString, value);
135
139
fixNumericLocale (buffer, buffer + len);
140
+ // to delete use-less too much zeros in the end of string
141
+ if (precisionType == PrecisionType::decimalPlaces) {
142
+ fixZerosInTheEnd (buffer, buffer + len);
143
+ }
136
144
137
145
// try to ensure we preserve the fact that this was given to us as a double on input
138
146
if (!strchr (buffer, ' .' ) && !strchr (buffer, ' e' )) {
@@ -154,7 +162,9 @@ JSONCPP_STRING valueToString(double value, bool useSpecialFloats, unsigned int p
154
162
}
155
163
}
156
164
157
- JSONCPP_STRING valueToString (double value) { return valueToString (value, false , 17 ); }
165
+ JSONCPP_STRING valueToString (double value, unsigned int precision, PrecisionType precisionType) {
166
+ return valueToString (value, false , precision, precisionType);
167
+ }
158
168
159
169
JSONCPP_STRING valueToString (bool value) { return value ? " true" : " false" ; }
160
170
@@ -856,7 +866,8 @@ struct BuiltStyledStreamWriter : public StreamWriter
856
866
JSONCPP_STRING const & nullSymbol,
857
867
JSONCPP_STRING const & endingLineFeedSymbol,
858
868
bool useSpecialFloats,
859
- unsigned int precision);
869
+ unsigned int precision,
870
+ PrecisionType precisionType);
860
871
int write (Value const & root, JSONCPP_OSTREAM* sout) JSONCPP_OVERRIDE;
861
872
private:
862
873
void writeValue (Value const & value);
@@ -885,6 +896,7 @@ struct BuiltStyledStreamWriter : public StreamWriter
885
896
bool indented_ : 1 ;
886
897
bool useSpecialFloats_ : 1 ;
887
898
unsigned int precision_;
899
+ PrecisionType precisionType_;
888
900
};
889
901
BuiltStyledStreamWriter::BuiltStyledStreamWriter (
890
902
JSONCPP_STRING const & indentation,
@@ -893,7 +905,8 @@ BuiltStyledStreamWriter::BuiltStyledStreamWriter(
893
905
JSONCPP_STRING const & nullSymbol,
894
906
JSONCPP_STRING const & endingLineFeedSymbol,
895
907
bool useSpecialFloats,
896
- unsigned int precision)
908
+ unsigned int precision,
909
+ PrecisionType precisionType)
897
910
: rightMargin_(74 )
898
911
, indentation_(indentation)
899
912
, cs_(cs)
@@ -904,6 +917,7 @@ BuiltStyledStreamWriter::BuiltStyledStreamWriter(
904
917
, indented_(false )
905
918
, useSpecialFloats_(useSpecialFloats)
906
919
, precision_(precision)
920
+ , precisionType_(precisionType)
907
921
{
908
922
}
909
923
int BuiltStyledStreamWriter::write (Value const & root, JSONCPP_OSTREAM* sout)
@@ -933,7 +947,7 @@ void BuiltStyledStreamWriter::writeValue(Value const& value) {
933
947
pushValue (valueToString (value.asLargestUInt ()));
934
948
break ;
935
949
case realValue:
936
- pushValue (valueToString (value.asDouble (), useSpecialFloats_, precision_));
950
+ pushValue (valueToString (value.asDouble (), useSpecialFloats_, precision_, precisionType_ ));
937
951
break ;
938
952
case stringValue:
939
953
{
@@ -1145,6 +1159,7 @@ StreamWriter* StreamWriterBuilder::newStreamWriter() const
1145
1159
{
1146
1160
JSONCPP_STRING indentation = settings_[" indentation" ].asString ();
1147
1161
JSONCPP_STRING cs_str = settings_[" commentStyle" ].asString ();
1162
+ JSONCPP_STRING pt_str = settings_[" precisionType" ].asString ();
1148
1163
bool eyc = settings_[" enableYAMLCompatibility" ].asBool ();
1149
1164
bool dnp = settings_[" dropNullPlaceholders" ].asBool ();
1150
1165
bool usf = settings_[" useSpecialFloats" ].asBool ();
@@ -1157,6 +1172,14 @@ StreamWriter* StreamWriterBuilder::newStreamWriter() const
1157
1172
} else {
1158
1173
throwRuntimeError (" commentStyle must be 'All' or 'None'" );
1159
1174
}
1175
+ PrecisionType precisionType (significantDigits);
1176
+ if (pt_str == " significant" ) {
1177
+ precisionType = PrecisionType::significantDigits;
1178
+ } else if (pt_str == " decimal" ) {
1179
+ precisionType = PrecisionType::decimalPlaces;
1180
+ } else {
1181
+ throwRuntimeError (" precisionType must be 'significant' or 'decimal'" );
1182
+ }
1160
1183
JSONCPP_STRING colonSymbol = " : " ;
1161
1184
if (eyc) {
1162
1185
colonSymbol = " : " ;
@@ -1171,7 +1194,7 @@ StreamWriter* StreamWriterBuilder::newStreamWriter() const
1171
1194
JSONCPP_STRING endingLineFeedSymbol;
1172
1195
return new BuiltStyledStreamWriter (
1173
1196
indentation, cs,
1174
- colonSymbol, nullSymbol, endingLineFeedSymbol, usf, pre);
1197
+ colonSymbol, nullSymbol, endingLineFeedSymbol, usf, pre, precisionType );
1175
1198
}
1176
1199
static void getValidWriterKeys (std::set<JSONCPP_STRING>* valid_keys)
1177
1200
{
@@ -1182,6 +1205,7 @@ static void getValidWriterKeys(std::set<JSONCPP_STRING>* valid_keys)
1182
1205
valid_keys->insert (" dropNullPlaceholders" );
1183
1206
valid_keys->insert (" useSpecialFloats" );
1184
1207
valid_keys->insert (" precision" );
1208
+ valid_keys->insert (" precisionType" );
1185
1209
}
1186
1210
bool StreamWriterBuilder::validate (Json::Value* invalid) const
1187
1211
{
@@ -1214,6 +1238,7 @@ void StreamWriterBuilder::setDefaults(Json::Value* settings)
1214
1238
(*settings)[" dropNullPlaceholders" ] = false ;
1215
1239
(*settings)[" useSpecialFloats" ] = false ;
1216
1240
(*settings)[" precision" ] = 17 ;
1241
+ (*settings)[" precisionType" ] = " significant" ;
1217
1242
// ! [StreamWriterBuilderDefaults]
1218
1243
}
1219
1244
0 commit comments