Don't use padding parsing booleans

This commit is contained in:
John Keiser
2021-06-06 15:57:44 -07:00
parent da4de2e0b8
commit b02aedb5bb
2 changed files with 33 additions and 19 deletions
@@ -441,15 +441,39 @@ simdjson_warn_unused simdjson_really_inline simdjson_result<double> value_iterat
return numberparsing::parse_double(advance_non_root_scalar("double"));
}
simdjson_warn_unused simdjson_really_inline simdjson_result<bool> value_iterator::get_bool() noexcept {
auto json = advance_non_root_scalar("bool");
return parse_bool(peek_start_length(), advance_non_root_scalar("bool"));
}
simdjson_really_inline simdjson_result<bool> value_iterator::parse_bool(uint32_t max_len, const uint8_t *json) const noexcept {
// If we're almost at the end of the document, we can't do our special algorithm
if (simdjson_unlikely(max_len <= 5)) {
if (max_len >= 4) {
if (!atomparsing::str4ncmp(json, "fals") && (max_len == 5 && json[4] == 'e')) {
return simdjson_result<bool>(false);
}
if (!atomparsing::str4ncmp(json, "true") && (max_len == 4 || jsoncharutils::is_structural_or_whitespace(json[4]))) {
return simdjson_result<bool>(true);
}
}
return incorrect_type_error("Not a boolean");
}
// Otherwise we use a less branchy algorithm
auto not_true = atomparsing::str4ncmp(json, "true");
auto not_false = atomparsing::str4ncmp(json, "fals") | (json[4] ^ 'e');
bool error = (not_true && not_false) || jsoncharutils::is_not_structural_or_whitespace(json[not_true ? 5 : 4]);
if (error) { return incorrect_type_error("Not a boolean"); }
if ((not_true && not_false) || jsoncharutils::is_not_structural_or_whitespace(json[not_true ? 5 : 4])) {
return incorrect_type_error("Not a boolean");
}
return simdjson_result<bool>(!not_true);
}
simdjson_really_inline bool value_iterator::is_null() noexcept {
auto json = advance_non_root_scalar("null");
return parse_null(peek_start_length(), advance_non_root_scalar("null"));
}
simdjson_really_inline bool value_iterator::parse_null(uint32_t max_len, const uint8_t *json) const noexcept {
if (simdjson_unlikely(max_len <= 4)) {
return max_len == 4 && !atomparsing::str4ncmp(json, "null");
}
return !atomparsing::str4ncmp(json, "null") && jsoncharutils::is_structural_or_whitespace(json[4]);
}
@@ -477,23 +501,10 @@ simdjson_warn_unused simdjson_really_inline simdjson_result<double> value_iterat
return numberparsing::parse_double(json, json+max_len);
}
simdjson_warn_unused simdjson_really_inline simdjson_result<bool> value_iterator::get_root_bool() noexcept {
auto max_len = peek_start_length();
auto json = advance_root_scalar("bool");
if (max_len >= 4 && !atomparsing::str4ncmp(json, "true") &&
(max_len == 4 || jsoncharutils::is_structural_or_whitespace(json[4]))) {
return simdjson_result<bool>(true);
}
if (max_len >= 5 && !atomparsing::str4ncmp(json, "fals") && json[4] == 'e' &&
(max_len == 5 || jsoncharutils::is_structural_or_whitespace(json[5]))) {
return simdjson_result<bool>(false);
}
return incorrect_type_error("Not a boolean");
return parse_bool(peek_start_length(), advance_root_scalar("bool"));
}
simdjson_really_inline bool value_iterator::is_root_null() noexcept {
auto max_len = peek_start_length();
auto json = advance_root_scalar("null");
return max_len >= 4 && !atomparsing::str4ncmp(json, "null") &&
(max_len == 4 || jsoncharutils::is_structural_or_whitespace(json[4]));
return parse_null(peek_start_length(), advance_root_scalar("null"));
}
simdjson_warn_unused simdjson_really_inline error_code value_iterator::skip_child() noexcept {
@@ -289,6 +289,9 @@ protected:
inline std::string to_string() const noexcept;
simdjson_really_inline value_iterator(json_iterator *json_iter, depth_t depth, token_position start_index) noexcept;
simdjson_really_inline bool parse_null(uint32_t max_len, const uint8_t *json) const noexcept;
simdjson_really_inline simdjson_result<bool> parse_bool(uint32_t max_len, const uint8_t *json) const noexcept;
simdjson_really_inline const uint8_t *peek_start() const noexcept;
simdjson_really_inline uint32_t peek_start_length() const noexcept;
simdjson_really_inline const uint8_t *advance_start(const char *type) noexcept;