@@ -53,6 +53,41 @@ inline bool value_isNegativeInf(T v)
53
53
extern " C"
54
54
{
55
55
56
+ inline long value_convert_int_str (const char *str, int n, bool *ok)
57
+ {
58
+ if (ok)
59
+ *ok = false ;
60
+
61
+ const char *begin = str;
62
+ const char *end = begin + n;
63
+
64
+ bool isNegative = false ;
65
+ long ret = 0 ;
66
+
67
+ if (*str == ' -' || *str == ' +' ) {
68
+ isNegative = (*str == ' -' );
69
+ ++str;
70
+
71
+ if (str == begin + n)
72
+ return 0 ;
73
+ }
74
+
75
+ while (str < end) {
76
+ if (*str < ' 0' || *str > ' 9' )
77
+ return 0 ;
78
+
79
+ ret = ret * 10 + (*str++ - ' 0' );
80
+ }
81
+
82
+ if (ok)
83
+ *ok = true ;
84
+
85
+ if (isNegative)
86
+ return -ret;
87
+ else
88
+ return ret;
89
+ }
90
+
56
91
inline size_t value_getSize (size_t x)
57
92
{
58
93
if (x == 0 )
@@ -197,44 +232,40 @@ extern "C"
197
232
if (ok)
198
233
*ok = false ;
199
234
200
- const size_t len = strlen (s);
201
-
202
- if (strlen (s) == 0 ) {
235
+ if (!s || *s == ' \0 ' ) {
203
236
if (ok)
204
237
*ok = true ;
205
238
206
239
return 0 ;
207
240
}
208
241
242
+ const size_t len = strlen (s);
209
243
const char *begin = s;
210
- const char *strEnd = s + len;
211
- const char *end = strEnd;
244
+ const char *end = s + len;
212
245
213
246
// Trim leading spaces
214
247
while (begin < end && IS_SPACE (*begin))
215
248
++begin;
216
249
217
- end = begin + 1 ;
218
-
219
250
// Trim trailing spaces
220
- while (end < strEnd && !IS_SPACE (*(end)))
221
- ++end;
222
-
223
- // Only whitespace can be after the end
224
- const char *p = end;
251
+ while (end > begin && IS_SPACE (*(end - 1 )))
252
+ --end;
225
253
226
- while (p < strEnd) {
227
- if (!IS_SPACE (*p))
228
- return 0 ;
229
-
230
- p++;
254
+ if (begin == end) { // All spaces case
255
+ if (ok)
256
+ *ok = true ;
257
+ return 0.0 ;
231
258
}
232
259
233
- if (end - begin <= 0 || end > strEnd) {
260
+ // Try to convert integer early
261
+ bool isInt = false ;
262
+ double ret = value_convert_int_str (begin, end - begin, &isInt);
263
+
264
+ if (isInt) {
234
265
if (ok)
235
266
*ok = true ;
236
267
237
- return 0 ;
268
+ return ret ;
238
269
}
239
270
240
271
char *copy = nullptr ;
@@ -315,7 +346,6 @@ extern "C"
315
346
return 0 ;
316
347
}
317
348
318
- double ret = 0 ;
319
349
auto [ptr, ec] = fast_float::from_chars (begin, end, ret, fast_float::chars_format::json);
320
350
321
351
if (copy)
@@ -330,15 +360,15 @@ extern "C"
330
360
return 0 ;
331
361
332
362
// Special values
333
- if (strcmp (s, " Infinity" ) == 0 ) {
363
+ if (strncmp (s, " Infinity" , len ) == 0 ) {
334
364
if (ok)
335
365
*ok = true ;
336
366
return std::numeric_limits<double >::infinity ();
337
- } else if (strcmp (s, " -Infinity" ) == 0 ) {
367
+ } else if (strncmp (s, " -Infinity" , len ) == 0 ) {
338
368
if (ok)
339
369
*ok = true ;
340
370
return -std::numeric_limits<double >::infinity ();
341
- } else if (strcmp (s, " NaN" ) == 0 ) {
371
+ } else if (strncmp (s, " NaN" , len ) == 0 ) {
342
372
if (ok)
343
373
*ok = true ;
344
374
return std::numeric_limits<double >::quiet_NaN ();
0 commit comments