@@ -127,48 +127,45 @@ JSONCPP_STRING valueToString(UInt value) {
127127
128128namespace {
129129JSONCPP_STRING valueToString (double value, bool useSpecialFloats, unsigned int precision, PrecisionType precisionType) {
130- // Allocate a buffer that is more than large enough to store the 16 digits of
131- // precision requested below.
132- char buffer[36 ];
133- int len = -1 ;
134-
135- char formatString[15 ];
136- if (precisionType == PrecisionType::significantDigits) {
137- snprintf (formatString, sizeof (formatString), " %%.%ug" , precision);
138- } else {
139- snprintf (formatString, sizeof (formatString), " %%.%uf" , precision);
140- }
141-
142130 // Print into the buffer. We need not request the alternative representation
143131 // that always has a decimal point because JSON doesn't distinguish the
144132 // concepts of reals and integers.
145- if (isfinite (value)) {
146- len = snprintf (buffer, sizeof (buffer), formatString, value);
147- fixNumericLocale (buffer, buffer + len);
148- // to delete use-less too much zeros in the end of string
149- if (precisionType == PrecisionType::decimalPlaces) {
150- fixZerosInTheEnd (buffer, buffer + len);
151- }
133+ if (!isfinite (value)) {
134+ static const char * const reps[2 ][3 ] = {
135+ {" NaN" , " -Infinity" , " Infinity" },
136+ {" null" , " -1e+9999" , " 1e+9999" }};
137+ return reps[useSpecialFloats ? 0 : 1 ][isnan (value) ? 0 : (value < 0 ) ? 1 : 2 ];
138+ }
152139
153- // try to ensure we preserve the fact that this was given to us as a double on input
154- if (!strchr (buffer, ' .' ) && !strchr (buffer, ' e' )) {
155- strcat (buffer, " .0" );
156- }
140+ JSONCPP_STRING buffer (36 , ' \0 ' );
141+ while (true ) {
142+ int len = snprintf (&*buffer.begin (), buffer.size (),
143+ (precisionType == PrecisionType::significantDigits) ? " %.*g" : " %.*f" ,
144+ precision, value);
145+ assert (len >= 0 );
146+ size_t wouldPrint = static_cast <size_t >(len);
147+ if (wouldPrint >= buffer.size ()) {
148+ buffer.resize (wouldPrint + 1 );
149+ continue ;
150+ }
151+ buffer.resize (wouldPrint);
152+ break ;
153+ }
157154
158- } else {
155+ buffer. erase ( fixNumericLocale (buffer. begin (), buffer. end ()), buffer. end ());
159156
160- if (isnan (value)) {
161- len = snprintf (buffer, sizeof (buffer), useSpecialFloats ? " NaN" : " null" );
162- } else if (value < 0 ) {
163- len = snprintf (buffer, sizeof (buffer), useSpecialFloats ? " -Infinity" : " -1e+9999" );
164- } else {
165- len = snprintf (buffer, sizeof (buffer), useSpecialFloats ? " Infinity" : " 1e+9999" );
166- }
157+ // strip the zero padding from the right
158+ if (precisionType == PrecisionType::decimalPlaces) {
159+ buffer.erase (fixZerosInTheEnd (buffer.begin (), buffer.end ()), buffer.end ());
160+ }
161+
162+ // try to ensure we preserve the fact that this was given to us as a double on input
163+ if (buffer.find (' .' ) == buffer.npos && buffer.find (' e' ) == buffer.npos ) {
164+ buffer += " .0" ;
167165 }
168- assert (len >= 0 );
169166 return buffer;
170167}
171- }
168+ } // namespace
172169
173170JSONCPP_STRING valueToString (double value, unsigned int precision, PrecisionType precisionType) {
174171 return valueToString (value, false , precision, precisionType);
0 commit comments