@@ -7,12 +7,12 @@ namespace stage2 {
7
7
namespace numberparsing {
8
8
9
9
#ifdef JSON_TEST_NUMBERS
10
- #define INVALID_NUMBER (SRC ) (found_invalid_number((SRC)), false )
10
+ #define INVALID_NUMBER (SRC ) (found_invalid_number((SRC)), NUMBER_ERROR )
11
11
#define WRITE_INTEGER (VALUE, SRC, WRITER ) (found_integer((VALUE), (SRC)), writer.append_s64((VALUE)))
12
12
#define WRITE_UNSIGNED (VALUE, SRC, WRITER ) (found_unsigned_integer((VALUE), (SRC)), writer.append_u64((VALUE)))
13
13
#define WRITE_DOUBLE (VALUE, SRC, WRITER ) (found_float((VALUE), (SRC)), writer.append_double((VALUE)))
14
14
#else
15
- #define INVALID_NUMBER (SRC ) (false )
15
+ #define INVALID_NUMBER (SRC ) (NUMBER_ERROR )
16
16
#define WRITE_INTEGER (VALUE, SRC, WRITER ) writer.append_s64((VALUE))
17
17
#define WRITE_UNSIGNED (VALUE, SRC, WRITER ) writer.append_u64((VALUE))
18
18
#define WRITE_DOUBLE (VALUE, SRC, WRITER ) writer.append_double((VALUE))
@@ -252,11 +252,11 @@ simdjson_really_inline bool is_made_of_eight_digits_fast(const uint8_t *chars) {
252
252
}
253
253
254
254
template <typename W>
255
- bool slow_float_parsing (SIMDJSON_UNUSED const uint8_t * src, W writer) {
255
+ error_code slow_float_parsing (SIMDJSON_UNUSED const uint8_t * src, W writer) {
256
256
double d;
257
257
if (parse_float_strtod (src, &d)) {
258
258
WRITE_DOUBLE (d, src, writer);
259
- return true ;
259
+ return SUCCESS ;
260
260
}
261
261
return INVALID_NUMBER (src);
262
262
}
@@ -273,7 +273,7 @@ simdjson_really_inline bool parse_digit(const uint8_t c, I &i) {
273
273
return true ;
274
274
}
275
275
276
- simdjson_really_inline bool parse_decimal (SIMDJSON_UNUSED const uint8_t *const src, const uint8_t *&p, uint64_t &i, int64_t &exponent) {
276
+ simdjson_really_inline error_code parse_decimal (SIMDJSON_UNUSED const uint8_t *const src, const uint8_t *&p, uint64_t &i, int64_t &exponent) {
277
277
// we continue with the fiction that we have an integer. If the
278
278
// floating point number is representable as x * 10^z for some integer
279
279
// z that fits in 53 bits, then we will be able to convert back the
@@ -296,10 +296,10 @@ simdjson_really_inline bool parse_decimal(SIMDJSON_UNUSED const uint8_t *const s
296
296
if (exponent == 0 ) {
297
297
return INVALID_NUMBER (src);
298
298
}
299
- return true ;
299
+ return SUCCESS ;
300
300
}
301
301
302
- simdjson_really_inline bool parse_exponent (SIMDJSON_UNUSED const uint8_t *const src, const uint8_t *&p, int64_t &exponent) {
302
+ simdjson_really_inline error_code parse_exponent (SIMDJSON_UNUSED const uint8_t *const src, const uint8_t *&p, int64_t &exponent) {
303
303
// Exp Sign: -123.456e[-]78
304
304
bool neg_exp = (' -' == *p);
305
305
if (neg_exp || ' +' == *p) { p++; } // Skip + as well
@@ -347,11 +347,11 @@ simdjson_really_inline bool parse_exponent(SIMDJSON_UNUSED const uint8_t *const
347
347
// is bounded in magnitude by the size of the JSON input, we are fine in this universe.
348
348
// To sum it up: the next line should never overflow.
349
349
exponent += (neg_exp ? -exp_number : exp_number);
350
- return true ;
350
+ return SUCCESS ;
351
351
}
352
352
353
353
template <typename W>
354
- simdjson_really_inline bool write_float (const uint8_t *const src, bool negative, uint64_t i, const uint8_t * start_digits, int digit_count, int64_t exponent, W &writer) {
354
+ simdjson_really_inline error_code write_float (const uint8_t *const src, bool negative, uint64_t i, const uint8_t * start_digits, int digit_count, int64_t exponent, W &writer) {
355
355
// If we frequently had to deal with long strings of digits,
356
356
// we could extend our code by using a 128-bit integer instead
357
357
// of a 64-bit integer. However, this is uncommon in practice.
@@ -373,11 +373,11 @@ simdjson_really_inline bool write_float(const uint8_t *const src, bool negative,
373
373
// 10000000000000000000000000000000000000000000e+308
374
374
// 3.1415926535897932384626433832795028841971693993751
375
375
//
376
- bool success = slow_float_parsing (src, writer);
376
+ error_code error = slow_float_parsing (src, writer);
377
377
// The number was already written, but we made a copy of the writer
378
378
// when we passed it to the parse_large_integer() function, so
379
379
writer.skip_double ();
380
- return success ;
380
+ return error ;
381
381
}
382
382
}
383
383
// NOTE: it's weird that the simdjson_unlikely() only wraps half the if, but it seems to get slower any other
@@ -386,11 +386,11 @@ simdjson_really_inline bool write_float(const uint8_t *const src, bool negative,
386
386
if (simdjson_unlikely (exponent < FASTFLOAT_SMALLEST_POWER) || (exponent > FASTFLOAT_LARGEST_POWER)) {
387
387
// this is almost never going to get called!!!
388
388
// we start anew, going slowly!!!
389
- bool success = slow_float_parsing (src, writer);
389
+ error_code error = slow_float_parsing (src, writer);
390
390
// The number was already written, but we made a copy of the writer when we passed it to the
391
391
// slow_float_parsing() function, so we have to skip those tape spots now that we've returned
392
392
writer.skip_double ();
393
- return success ;
393
+ return error ;
394
394
}
395
395
bool success = true ;
396
396
double d = compute_float_64 (exponent, i, negative, &success);
@@ -399,16 +399,16 @@ simdjson_really_inline bool write_float(const uint8_t *const src, bool negative,
399
399
if (!parse_float_strtod (src, &d)) { return INVALID_NUMBER (src); }
400
400
}
401
401
WRITE_DOUBLE (d, src, writer);
402
- return true ;
402
+ return SUCCESS ;
403
403
}
404
404
405
405
// for performance analysis, it is sometimes useful to skip parsing
406
406
#ifdef SIMDJSON_SKIPNUMBERPARSING
407
407
408
408
template <typename W>
409
- simdjson_really_inline bool parse_number (const uint8_t *const , W &writer) {
409
+ simdjson_really_inline error_code parse_number (const uint8_t *const , W &writer) {
410
410
writer.append_s64 (0 ); // always write zero
411
- return true ; // always succeeds
411
+ return SUCCESS; // always succeeds
412
412
}
413
413
414
414
#else
@@ -423,7 +423,7 @@ simdjson_really_inline bool parse_number(const uint8_t *const, W &writer) {
423
423
//
424
424
// Our objective is accurate parsing (ULP of 0) at high speed.
425
425
template <typename W>
426
- simdjson_really_inline bool parse_number (const uint8_t *const src, W &writer) {
426
+ simdjson_really_inline error_code parse_number (const uint8_t *const src, W &writer) {
427
427
428
428
//
429
429
// Check for minus sign
@@ -451,17 +451,19 @@ simdjson_really_inline bool parse_number(const uint8_t *const src, W &writer) {
451
451
if (' .' == *p) {
452
452
is_float = true ;
453
453
++p;
454
- if (! parse_decimal (src, p, i, exponent)) { return false ; }
454
+ SIMDJSON_TRY ( parse_decimal (src, p, i, exponent) );
455
455
digit_count = int (p - start_digits); // used later to guard against overflows
456
456
}
457
457
if ((' e' == *p) || (' E' == *p)) {
458
458
is_float = true ;
459
459
++p;
460
- if (! parse_exponent (src, p, exponent)) { return false ; }
460
+ SIMDJSON_TRY ( parse_exponent (src, p, exponent) );
461
461
}
462
462
if (is_float) {
463
463
const bool clean_end = is_structural_or_whitespace (*p);
464
- return write_float (src, negative, i, start_digits, digit_count, exponent, writer) && clean_end;
464
+ SIMDJSON_TRY ( write_float (src, negative, i, start_digits, digit_count, exponent, writer) );
465
+ if (!clean_end) { return INVALID_NUMBER (src); }
466
+ return SUCCESS;
465
467
}
466
468
467
469
// The longest negative 64-bit number is 19 digits.
@@ -470,13 +472,12 @@ simdjson_really_inline bool parse_number(const uint8_t *const src, W &writer) {
470
472
int longest_digit_count = negative ? 19 : 20 ;
471
473
if (digit_count > longest_digit_count) { return INVALID_NUMBER (src); }
472
474
if (digit_count == longest_digit_count) {
473
- if (negative) {
475
+ if (negative) {
474
476
// Anything negative above INT64_MAX+1 is invalid
475
- if (i > uint64_t (INT64_MAX)+1 ) {
476
- return INVALID_NUMBER (src);
477
- }
477
+ if (i > uint64_t (INT64_MAX)+1 ) { return INVALID_NUMBER (src); }
478
478
WRITE_INTEGER (~i+1 , src, writer);
479
- return is_structural_or_whitespace (*p);
479
+ if (!is_structural_or_whitespace (*p)) { return INVALID_NUMBER (src); }
480
+ return SUCCESS;
480
481
// Positive overflow check:
481
482
// - A 20 digit number starting with 2-9 is overflow, because 18,446,744,073,709,551,615 is the
482
483
// biggest uint64_t.
@@ -498,7 +499,8 @@ simdjson_really_inline bool parse_number(const uint8_t *const src, W &writer) {
498
499
} else {
499
500
WRITE_INTEGER (negative ? (~i+1 ) : i, src, writer);
500
501
}
501
- return is_structural_or_whitespace (*p);
502
+ if (!is_structural_or_whitespace (*p)) { return INVALID_NUMBER (src); }
503
+ return SUCCESS;
502
504
}
503
505
504
506
// SAX functions
0 commit comments