@@ -127,48 +127,45 @@ JSONCPP_STRING valueToString(UInt value) {
127
127
128
128
namespace {
129
129
JSONCPP_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
-
142
130
// Print into the buffer. We need not request the alternative representation
143
131
// that always has a decimal point because JSON doesn't distinguish the
144
132
// 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
+ }
152
139
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 (size_t (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
+ }
157
154
158
- } else {
155
+ buffer. erase ( fixNumericLocale (buffer. begin (), buffer. end ()), buffer. end ());
159
156
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" ;
167
165
}
168
- assert (len >= 0 );
169
166
return buffer;
170
167
}
171
- }
168
+ } // namespace
172
169
173
170
JSONCPP_STRING valueToString (double value, unsigned int precision, PrecisionType precisionType) {
174
171
return valueToString (value, false , precision, precisionType);
0 commit comments