Cache string value locally
This commit is contained in:
parent
abd1399a7f
commit
57eb55446f
|
@ -10,7 +10,6 @@ public:
|
|||
uint32_t *next_structural;
|
||||
dom_parser_implementation &dom_parser;
|
||||
uint32_t depth{0};
|
||||
const uint8_t *value{}; // Used to keep a value around between states
|
||||
|
||||
template<bool STREAMING, typename T>
|
||||
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() {
|
||||
return buf[*(next_structural)];
|
||||
}
|
||||
simdjson_really_inline char advance() {
|
||||
value = &buf[*(next_structural++)];
|
||||
return *value;
|
||||
simdjson_really_inline const uint8_t *advance() {
|
||||
return &buf[*(next_structural++)];
|
||||
}
|
||||
simdjson_really_inline size_t remaining_len() {
|
||||
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
|
||||
//
|
||||
advance();
|
||||
{
|
||||
auto value = advance();
|
||||
|
||||
// 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
|
||||
if (!STREAMING) {
|
||||
switch (*value) {
|
||||
case '{':
|
||||
if (last_structural() != '}') {
|
||||
return TAPE_ERROR;
|
||||
}
|
||||
break;
|
||||
case '[':
|
||||
if (last_structural() != ']') {
|
||||
return TAPE_ERROR;
|
||||
}
|
||||
break;
|
||||
// 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
|
||||
if (!STREAMING) {
|
||||
switch (*value) {
|
||||
case '{':
|
||||
if (last_structural() != '}') {
|
||||
return TAPE_ERROR;
|
||||
}
|
||||
break;
|
||||
case '[':
|
||||
if (last_structural() != ']') {
|
||||
return TAPE_ERROR;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
switch (*value) {
|
||||
case '{': if (!empty_object(visitor)) { goto object_begin; }; break;
|
||||
case '[': if (!empty_array(visitor)) { goto array_begin; }; break;
|
||||
default: SIMDJSON_TRY( visitor.root_primitive(*this, value) ); break;
|
||||
switch (*value) {
|
||||
case '{': if (!empty_object(visitor)) { goto object_begin; }; break;
|
||||
case '[': if (!empty_array(visitor)) { goto array_begin; }; break;
|
||||
default: SIMDJSON_TRY( visitor.root_primitive(*this, value) ); break;
|
||||
}
|
||||
}
|
||||
goto document_end;
|
||||
|
||||
|
@ -131,24 +131,33 @@ object_begin:
|
|||
if (depth >= dom_parser.max_depth()) { log_error("Exceeded max depth!"); return DEPTH_ERROR; }
|
||||
SIMDJSON_TRY( visitor.start_object(*this) );
|
||||
|
||||
if (advance() != '"') { log_error("Object does not start with a key"); return TAPE_ERROR; }
|
||||
visitor.increment_count(*this);
|
||||
SIMDJSON_TRY( visitor.key(*this, value) );
|
||||
{
|
||||
auto key = advance();
|
||||
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:
|
||||
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;
|
||||
case '[': if (!empty_array(visitor)) { goto array_begin; }; break;
|
||||
default: SIMDJSON_TRY( visitor.primitive(*this, value) ); break;
|
||||
if (simdjson_unlikely( *advance() != ':' )) { log_error("Missing colon after key in object"); return TAPE_ERROR; }
|
||||
{
|
||||
auto value = advance();
|
||||
switch (*value) {
|
||||
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:
|
||||
switch (advance()) {
|
||||
switch (*advance()) {
|
||||
case ',':
|
||||
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;
|
||||
case '}': SIMDJSON_TRY( visitor.end_object(*this) ); goto scope_end;
|
||||
default: log_error("No comma between object fields"); return TAPE_ERROR;
|
||||
|
@ -170,14 +179,17 @@ array_begin:
|
|||
visitor.increment_count(*this);
|
||||
|
||||
array_value:
|
||||
switch (advance()) {
|
||||
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;
|
||||
{
|
||||
auto value = advance();
|
||||
switch (*value) {
|
||||
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:
|
||||
switch (advance()) {
|
||||
switch (*advance()) {
|
||||
case ',': visitor.increment_count(*this); goto array_value;
|
||||
case ']': SIMDJSON_TRY( visitor.end_array(*this) ); goto scope_end;
|
||||
default: log_error("Missing comma between array values"); return TAPE_ERROR;
|
||||
|
|
Loading…
Reference in New Issue