mirror of
https://github.com/simdjson/simdjson
synced 2026-06-08 17:27:07 +00:00
* add compile option 'SIMDJSON_ENABLE_NAN_INF' but disable by default * extend parser to support NaN/Infinity when SIMDJSON_ENABLE_NAN_INF=1 * update tests to check parsing of NaN/Infinity, when enabled * update minefield tests: mark nan/inf tests as passing when nan/inf is ON * update CI/CD to run tests with extensions for NaN/Infinity enabled
This commit is contained in:
committed by
GitHub
parent
f902769b35
commit
b9b20be80e
@@ -291,7 +291,20 @@ simdjson_warn_unused simdjson_inline error_code json_iterator::visit_root_primit
|
||||
case '"': return visitor.visit_root_string(*this, value);
|
||||
case 't': return visitor.visit_root_true_atom(*this, value);
|
||||
case 'f': return visitor.visit_root_false_atom(*this, value);
|
||||
#if SIMDJSON_ENABLE_NAN_INF
|
||||
case 'n': {
|
||||
auto err = visitor.visit_root_null_atom(*this, value);
|
||||
if (err == SUCCESS) { return err; }
|
||||
// propagate the error value returned by a bad 'null' atom if parsing 'nan' fails
|
||||
return visitor.visit_root_nan_atom(*this, value, err);
|
||||
}
|
||||
// 'N' isn't a canonically recognized atom, so we return a TAPE_ERROR if failure occurs
|
||||
case 'N': return visitor.visit_root_nan_atom(*this, value, TAPE_ERROR);
|
||||
case 'i':
|
||||
case 'I': return visitor.visit_root_inf_atom(*this, value);
|
||||
#else
|
||||
case 'n': return visitor.visit_root_null_atom(*this, value);
|
||||
#endif
|
||||
case '-':
|
||||
case '0': case '1': case '2': case '3': case '4':
|
||||
case '5': case '6': case '7': case '8': case '9':
|
||||
@@ -313,7 +326,20 @@ simdjson_warn_unused simdjson_inline error_code json_iterator::visit_primitive(V
|
||||
switch (*value) {
|
||||
case 't': return visitor.visit_true_atom(*this, value);
|
||||
case 'f': return visitor.visit_false_atom(*this, value);
|
||||
#if SIMDJSON_ENABLE_NAN_INF
|
||||
case 'n': {
|
||||
auto err = visitor.visit_null_atom(*this, value);
|
||||
if (err == SUCCESS) { return err; }
|
||||
// propagate the error value returned by a bad 'null' atom if parsing 'nan' fails
|
||||
return visitor.visit_nan_atom(*this, value, err);
|
||||
}
|
||||
// 'N' isn't a canonically recognized atom, so we return a TAPE_ERROR if failure occurs
|
||||
case 'N': return visitor.visit_nan_atom(*this, value, TAPE_ERROR);
|
||||
case 'i':
|
||||
case 'I': return visitor.visit_inf_atom(*this, value);
|
||||
#else
|
||||
case 'n': return visitor.visit_null_atom(*this, value);
|
||||
#endif
|
||||
default:
|
||||
log_error("Non-value found when value was expected!");
|
||||
return TAPE_ERROR;
|
||||
@@ -325,4 +351,4 @@ simdjson_warn_unused simdjson_inline error_code json_iterator::visit_primitive(V
|
||||
} // namespace SIMDJSON_IMPLEMENTATION
|
||||
} // namespace simdjson
|
||||
|
||||
#endif // SIMDJSON_SRC_GENERIC_STAGE2_JSON_ITERATOR_H
|
||||
#endif // SIMDJSON_SRC_GENERIC_STAGE2_JSON_ITERATOR_H
|
||||
|
||||
@@ -76,6 +76,15 @@ struct tape_builder {
|
||||
simdjson_warn_unused simdjson_inline error_code visit_root_false_atom(json_iterator &iter, const uint8_t *value) noexcept;
|
||||
simdjson_warn_unused simdjson_inline error_code visit_root_null_atom(json_iterator &iter, const uint8_t *value) noexcept;
|
||||
|
||||
#if SIMDJSON_ENABLE_NAN_INF
|
||||
simdjson_warn_unused simdjson_inline error_code visit_nan_atom(json_iterator &iter, const uint8_t *value, error_code errc) noexcept;
|
||||
simdjson_warn_unused simdjson_inline error_code visit_root_nan_atom(json_iterator &iter, const uint8_t *value, error_code errc) noexcept;
|
||||
// Attempts to parse 'inf' or 'infinity' (case insensitive). Because neither are canonical atoms,
|
||||
// this returns a tape error on failure.
|
||||
simdjson_warn_unused simdjson_inline error_code visit_inf_atom(json_iterator &iter, const uint8_t *value) noexcept;
|
||||
simdjson_warn_unused simdjson_inline error_code visit_root_inf_atom(json_iterator &iter, const uint8_t *value) noexcept;
|
||||
#endif
|
||||
|
||||
/** Called each time a new field or element in an array or object is found. */
|
||||
simdjson_warn_unused simdjson_inline error_code increment_count(json_iterator &iter) noexcept;
|
||||
|
||||
@@ -255,6 +264,38 @@ simdjson_warn_unused simdjson_inline error_code tape_builder::visit_root_null_at
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
#if SIMDJSON_ENABLE_NAN_INF
|
||||
simdjson_warn_unused simdjson_inline error_code tape_builder::visit_nan_atom(json_iterator &iter, const uint8_t *value, error_code errc) noexcept {
|
||||
iter.log_value("nan");
|
||||
if (!atomparsing::is_valid_nan_atom(value)) { return errc; }
|
||||
tape.append_double(std::numeric_limits<double>::quiet_NaN());
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
simdjson_warn_unused simdjson_inline error_code tape_builder::visit_root_nan_atom(json_iterator &iter, const uint8_t *value, error_code errc) noexcept {
|
||||
iter.log_value("nan");
|
||||
if (!atomparsing::is_valid_nan_atom(value, iter.remaining_len())) { return errc; }
|
||||
tape.append_double(std::numeric_limits<double>::quiet_NaN());
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
simdjson_warn_unused simdjson_inline error_code tape_builder::visit_inf_atom(json_iterator &iter, const uint8_t *value) noexcept {
|
||||
iter.log_value("inf");
|
||||
// Because 'inf' is an extension, non a canonical atom, a tape error should be returned on failure
|
||||
if (!atomparsing::is_valid_inf_atom(value)) { return TAPE_ERROR; }
|
||||
tape.append_double(std::numeric_limits<double>::infinity());
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
simdjson_warn_unused simdjson_inline error_code tape_builder::visit_root_inf_atom(json_iterator &iter, const uint8_t *value) noexcept {
|
||||
iter.log_value("inf");
|
||||
// Because 'inf' is an extension, non a canonical atom, a tape error should be returned on failure
|
||||
if (!atomparsing::is_valid_inf_atom(value, iter.remaining_len())) { return TAPE_ERROR; }
|
||||
tape.append_double(std::numeric_limits<double>::infinity());
|
||||
return SUCCESS;
|
||||
}
|
||||
#endif // SIMDJSON_ENABLE_NAN_INF
|
||||
|
||||
// private:
|
||||
|
||||
simdjson_inline uint32_t tape_builder::next_tape_index(json_iterator &iter) const noexcept {
|
||||
@@ -310,4 +351,4 @@ simdjson_inline void tape_builder::on_end_string(uint8_t *dst) noexcept {
|
||||
} // namespace SIMDJSON_IMPLEMENTATION
|
||||
} // namespace simdjson
|
||||
|
||||
#endif // SIMDJSON_SRC_GENERIC_STAGE2_TAPE_BUILDER_H
|
||||
#endif // SIMDJSON_SRC_GENERIC_STAGE2_TAPE_BUILDER_H
|
||||
|
||||
Reference in New Issue
Block a user