Cache string value locally
This commit is contained in:
parent
abd1399a7f
commit
57eb55446f
|
@ -10,7 +10,6 @@ public:
|
||||||
uint32_t *next_structural;
|
uint32_t *next_structural;
|
||||||
dom_parser_implementation &dom_parser;
|
dom_parser_implementation &dom_parser;
|
||||||
uint32_t depth{0};
|
uint32_t depth{0};
|
||||||
const uint8_t *value{}; // Used to keep a value around between states
|
|
||||||
|
|
||||||
template<bool STREAMING, typename T>
|
template<bool STREAMING, typename T>
|
||||||
SIMDJSON_WARN_UNUSED simdjson_really_inline error_code walk_document(T &visitor) noexcept;
|
SIMDJSON_WARN_UNUSED simdjson_really_inline error_code walk_document(T &visitor) noexcept;
|
||||||
|
@ -26,9 +25,8 @@ public:
|
||||||
simdjson_really_inline char peek_next_char() {
|
simdjson_really_inline char peek_next_char() {
|
||||||
return buf[*(next_structural)];
|
return buf[*(next_structural)];
|
||||||
}
|
}
|
||||||
simdjson_really_inline char advance() {
|
simdjson_really_inline const uint8_t *advance() {
|
||||||
value = &buf[*(next_structural++)];
|
return &buf[*(next_structural++)];
|
||||||
return *value;
|
|
||||||
}
|
}
|
||||||
simdjson_really_inline size_t remaining_len() {
|
simdjson_really_inline size_t remaining_len() {
|
||||||
return dom_parser.len - *(next_structural-1);
|
return dom_parser.len - *(next_structural-1);
|
||||||
|
@ -97,29 +95,31 @@ SIMDJSON_WARN_UNUSED simdjson_really_inline error_code json_iterator::walk_docum
|
||||||
//
|
//
|
||||||
// Read first value
|
// Read first value
|
||||||
//
|
//
|
||||||
advance();
|
{
|
||||||
|
auto value = advance();
|
||||||
|
|
||||||
// Make sure the outer hash or array is closed before continuing; otherwise, there are ways we
|
// Make sure the outer hash or array is closed before continuing; otherwise, there are ways we
|
||||||
// could get into memory corruption. See https://github.com/simdjson/simdjson/issues/906
|
// could get into memory corruption. See https://github.com/simdjson/simdjson/issues/906
|
||||||
if (!STREAMING) {
|
if (!STREAMING) {
|
||||||
switch (*value) {
|
switch (*value) {
|
||||||
case '{':
|
case '{':
|
||||||
if (last_structural() != '}') {
|
if (last_structural() != '}') {
|
||||||
return TAPE_ERROR;
|
return TAPE_ERROR;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case '[':
|
case '[':
|
||||||
if (last_structural() != ']') {
|
if (last_structural() != ']') {
|
||||||
return TAPE_ERROR;
|
return TAPE_ERROR;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
switch (*value) {
|
switch (*value) {
|
||||||
case '{': if (!empty_object(visitor)) { goto object_begin; }; break;
|
case '{': if (!empty_object(visitor)) { goto object_begin; }; break;
|
||||||
case '[': if (!empty_array(visitor)) { goto array_begin; }; break;
|
case '[': if (!empty_array(visitor)) { goto array_begin; }; break;
|
||||||
default: SIMDJSON_TRY( visitor.root_primitive(*this, value) ); break;
|
default: SIMDJSON_TRY( visitor.root_primitive(*this, value) ); break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
goto document_end;
|
goto document_end;
|
||||||
|
|
||||||
|
@ -131,24 +131,33 @@ object_begin:
|
||||||
if (depth >= dom_parser.max_depth()) { log_error("Exceeded max depth!"); return DEPTH_ERROR; }
|
if (depth >= dom_parser.max_depth()) { log_error("Exceeded max depth!"); return DEPTH_ERROR; }
|
||||||
SIMDJSON_TRY( visitor.start_object(*this) );
|
SIMDJSON_TRY( visitor.start_object(*this) );
|
||||||
|
|
||||||
if (advance() != '"') { log_error("Object does not start with a key"); return TAPE_ERROR; }
|
{
|
||||||
visitor.increment_count(*this);
|
auto key = advance();
|
||||||
SIMDJSON_TRY( visitor.key(*this, value) );
|
if (*key != '"') { log_error("Object does not start with a key"); return TAPE_ERROR; }
|
||||||
|
visitor.increment_count(*this);
|
||||||
|
SIMDJSON_TRY( visitor.key(*this, key) );
|
||||||
|
}
|
||||||
|
|
||||||
object_field:
|
object_field:
|
||||||
if (simdjson_unlikely( advance() != ':' )) { log_error("Missing colon after key in object"); return TAPE_ERROR; }
|
if (simdjson_unlikely( *advance() != ':' )) { log_error("Missing colon after key in object"); return TAPE_ERROR; }
|
||||||
switch (advance()) {
|
{
|
||||||
case '{': if (!empty_object(visitor)) { goto object_begin; }; break;
|
auto value = advance();
|
||||||
case '[': if (!empty_array(visitor)) { goto array_begin; }; break;
|
switch (*value) {
|
||||||
default: SIMDJSON_TRY( visitor.primitive(*this, value) ); break;
|
case '{': if (!empty_object(visitor)) { goto object_begin; }; break;
|
||||||
|
case '[': if (!empty_array(visitor)) { goto array_begin; }; break;
|
||||||
|
default: SIMDJSON_TRY( visitor.primitive(*this, value) ); break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
object_continue:
|
object_continue:
|
||||||
switch (advance()) {
|
switch (*advance()) {
|
||||||
case ',':
|
case ',':
|
||||||
visitor.increment_count(*this);
|
visitor.increment_count(*this);
|
||||||
if (simdjson_unlikely( advance() != '"' )) { log_error("Key string missing at beginning of field in object"); return TAPE_ERROR; }
|
{
|
||||||
SIMDJSON_TRY( visitor.key(*this, value) );
|
auto key = advance();
|
||||||
|
if (simdjson_unlikely( *key != '"' )) { log_error("Key string missing at beginning of field in object"); return TAPE_ERROR; }
|
||||||
|
SIMDJSON_TRY( visitor.key(*this, key) );
|
||||||
|
}
|
||||||
goto object_field;
|
goto object_field;
|
||||||
case '}': SIMDJSON_TRY( visitor.end_object(*this) ); goto scope_end;
|
case '}': SIMDJSON_TRY( visitor.end_object(*this) ); goto scope_end;
|
||||||
default: log_error("No comma between object fields"); return TAPE_ERROR;
|
default: log_error("No comma between object fields"); return TAPE_ERROR;
|
||||||
|
@ -170,14 +179,17 @@ array_begin:
|
||||||
visitor.increment_count(*this);
|
visitor.increment_count(*this);
|
||||||
|
|
||||||
array_value:
|
array_value:
|
||||||
switch (advance()) {
|
{
|
||||||
case '{': if (!empty_object(visitor)) { goto object_begin; }; break;
|
auto value = advance();
|
||||||
case '[': if (!empty_array(visitor)) { goto array_begin; }; break;
|
switch (*value) {
|
||||||
default: SIMDJSON_TRY( visitor.primitive(*this, value) ); break;
|
case '{': if (!empty_object(visitor)) { goto object_begin; }; break;
|
||||||
|
case '[': if (!empty_array(visitor)) { goto array_begin; }; break;
|
||||||
|
default: SIMDJSON_TRY( visitor.primitive(*this, value) ); break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
array_continue:
|
array_continue:
|
||||||
switch (advance()) {
|
switch (*advance()) {
|
||||||
case ',': visitor.increment_count(*this); goto array_value;
|
case ',': visitor.increment_count(*this); goto array_value;
|
||||||
case ']': SIMDJSON_TRY( visitor.end_array(*this) ); goto scope_end;
|
case ']': SIMDJSON_TRY( visitor.end_array(*this) ); goto scope_end;
|
||||||
default: log_error("Missing comma between array values"); return TAPE_ERROR;
|
default: log_error("Missing comma between array values"); return TAPE_ERROR;
|
||||||
|
|
Loading…
Reference in New Issue