Preface visitor methods with visit()

This commit is contained in:
John Keiser 2020-08-12 09:25:00 -07:00
parent 6ec98ee8b1
commit 15eb1ad922
2 changed files with 53 additions and 53 deletions

View File

@ -11,8 +11,8 @@ public:
dom_parser_implementation &dom_parser; dom_parser_implementation &dom_parser;
uint32_t depth{0}; uint32_t depth{0};
template<bool STREAMING, typename T> template<bool STREAMING, typename V>
SIMDJSON_WARN_UNUSED simdjson_really_inline error_code walk_document(T &visitor) noexcept; SIMDJSON_WARN_UNUSED simdjson_really_inline error_code walk_document(V &visitor) noexcept;
// Start a structural // Start a structural
simdjson_really_inline json_iterator(dom_parser_implementation &_dom_parser, size_t start_structural_index) simdjson_really_inline json_iterator(dom_parser_implementation &_dom_parser, size_t start_structural_index)
@ -62,15 +62,15 @@ public:
} }
}; };
template<bool STREAMING, typename T> template<bool STREAMING, typename V>
SIMDJSON_WARN_UNUSED simdjson_really_inline error_code json_iterator::walk_document(T &visitor) noexcept { SIMDJSON_WARN_UNUSED simdjson_really_inline error_code json_iterator::walk_document(V &visitor) noexcept {
logger::log_start(); logger::log_start();
// //
// Start the document // Start the document
// //
if (at_end()) { return EMPTY; } if (at_end()) { return EMPTY; }
SIMDJSON_TRY( visitor.start_document(*this) ); SIMDJSON_TRY( visitor.visit_document_start(*this) );
// //
// Read first value // Read first value
@ -96,9 +96,9 @@ SIMDJSON_WARN_UNUSED simdjson_really_inline error_code json_iterator::walk_docum
} }
switch (*value) { switch (*value) {
case '{': if (peek_next_char() == '}') { advance(); SIMDJSON_TRY( visitor.empty_object(*this) ); break; } goto object_begin; case '{': if (peek_next_char() == '}') { advance(); SIMDJSON_TRY( visitor.visit_empty_object(*this) ); break; } goto object_begin;
case '[': if (peek_next_char() == ']') { advance(); SIMDJSON_TRY( visitor.empty_array(*this) ); break; } goto array_begin; case '[': if (peek_next_char() == ']') { advance(); SIMDJSON_TRY( visitor.visit_empty_array(*this) ); break; } goto array_begin;
default: SIMDJSON_TRY( visitor.root_primitive(*this, value) ); break; default: SIMDJSON_TRY( visitor.visit_root_primitive(*this, value) ); break;
} }
} }
goto document_end; goto document_end;
@ -109,13 +109,13 @@ SIMDJSON_WARN_UNUSED simdjson_really_inline error_code json_iterator::walk_docum
object_begin: object_begin:
depth++; depth++;
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.visit_object_start(*this) );
{ {
auto key = advance(); auto key = advance();
if (*key != '"') { log_error("Object does not start with a key"); return TAPE_ERROR; } if (*key != '"') { log_error("Object does not start with a key"); return TAPE_ERROR; }
SIMDJSON_TRY( visitor.increment_count(*this) ); SIMDJSON_TRY( visitor.increment_count(*this) );
SIMDJSON_TRY( visitor.key(*this, key) ); SIMDJSON_TRY( visitor.visit_key(*this, key) );
} }
object_field: object_field:
@ -123,9 +123,9 @@ object_field:
{ {
auto value = advance(); auto value = advance();
switch (*value) { switch (*value) {
case '{': if (peek_next_char() == '}') { advance(); SIMDJSON_TRY( visitor.empty_object(*this) ); break; } goto object_begin; case '{': if (peek_next_char() == '}') { advance(); SIMDJSON_TRY( visitor.visit_empty_object(*this) ); break; } goto object_begin;
case '[': if (peek_next_char() == ']') { advance(); SIMDJSON_TRY( visitor.empty_array(*this) ); break; } goto array_begin; case '[': if (peek_next_char() == ']') { advance(); SIMDJSON_TRY( visitor.visit_empty_array(*this) ); break; } goto array_begin;
default: SIMDJSON_TRY( visitor.primitive(*this, value) ); break; default: SIMDJSON_TRY( visitor.visit_primitive(*this, value) ); break;
} }
} }
@ -136,10 +136,10 @@ object_continue:
{ {
auto key = advance(); auto key = advance();
if (simdjson_unlikely( *key != '"' )) { log_error("Key string missing at beginning of field in object"); return TAPE_ERROR; } if (simdjson_unlikely( *key != '"' )) { log_error("Key string missing at beginning of field in object"); return TAPE_ERROR; }
SIMDJSON_TRY( visitor.key(*this, key) ); SIMDJSON_TRY( visitor.visit_key(*this, key) );
} }
goto object_field; goto object_field;
case '}': SIMDJSON_TRY( visitor.end_object(*this) ); goto scope_end; case '}': SIMDJSON_TRY( visitor.visit_object_end(*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;
} }
@ -155,28 +155,28 @@ scope_end:
array_begin: array_begin:
depth++; depth++;
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_array(*this) ); SIMDJSON_TRY( visitor.visit_array_start(*this) );
SIMDJSON_TRY( visitor.increment_count(*this) ); SIMDJSON_TRY( visitor.increment_count(*this) );
array_value: array_value:
{ {
auto value = advance(); auto value = advance();
switch (*value) { switch (*value) {
case '{': if (peek_next_char() == '}') { advance(); SIMDJSON_TRY( visitor.empty_object(*this) ); break; } goto object_begin; case '{': if (peek_next_char() == '}') { advance(); SIMDJSON_TRY( visitor.visit_empty_object(*this) ); break; } goto object_begin;
case '[': if (peek_next_char() == ']') { advance(); SIMDJSON_TRY( visitor.empty_array(*this) ); break; } goto array_begin; case '[': if (peek_next_char() == ']') { advance(); SIMDJSON_TRY( visitor.visit_empty_array(*this) ); break; } goto array_begin;
default: SIMDJSON_TRY( visitor.primitive(*this, value) ); break; default: SIMDJSON_TRY( visitor.visit_primitive(*this, value) ); break;
} }
} }
array_continue: array_continue:
switch (*advance()) { switch (*advance()) {
case ',': SIMDJSON_TRY( visitor.increment_count(*this) ); goto array_value; case ',': SIMDJSON_TRY( visitor.increment_count(*this) ); goto array_value;
case ']': SIMDJSON_TRY( visitor.end_array(*this) ); goto scope_end; case ']': SIMDJSON_TRY( visitor.visit_array_end(*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;
} }
document_end: document_end:
SIMDJSON_TRY( visitor.end_document(*this) ); SIMDJSON_TRY( visitor.visit_document_end(*this) );
dom_parser.next_structural_index = uint32_t(next_structural - &dom_parser.structural_indexes[0]); dom_parser.next_structural_index = uint32_t(next_structural - &dom_parser.structural_indexes[0]);

View File

@ -17,81 +17,81 @@ struct tape_builder {
return iter.walk_document<STREAMING>(builder); return iter.walk_document<STREAMING>(builder);
} }
SIMDJSON_WARN_UNUSED simdjson_really_inline error_code root_primitive(json_iterator &iter, const uint8_t *value) { SIMDJSON_WARN_UNUSED simdjson_really_inline error_code visit_root_primitive(json_iterator &iter, const uint8_t *value) {
switch (*value) { switch (*value) {
case '"': return parse_string(iter, value); case '"': return visit_string(iter, value);
case 't': return parse_root_true_atom(iter, value); case 't': return visit_root_true_atom(iter, value);
case 'f': return parse_root_false_atom(iter, value); case 'f': return visit_root_false_atom(iter, value);
case 'n': return parse_root_null_atom(iter, value); case 'n': return visit_root_null_atom(iter, value);
case '-': case '-':
case '0': case '1': case '2': case '3': case '4': case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9': case '5': case '6': case '7': case '8': case '9':
return parse_root_number(iter, value); return visit_root_number(iter, value);
default: default:
iter.log_error("Document starts with a non-value character"); iter.log_error("Document starts with a non-value character");
return TAPE_ERROR; return TAPE_ERROR;
} }
} }
SIMDJSON_WARN_UNUSED simdjson_really_inline error_code primitive(json_iterator &iter, const uint8_t *value) { SIMDJSON_WARN_UNUSED simdjson_really_inline error_code visit_primitive(json_iterator &iter, const uint8_t *value) {
switch (*value) { switch (*value) {
case '"': return parse_string(iter, value); case '"': return visit_string(iter, value);
case 't': return parse_true_atom(iter, value); case 't': return visit_true_atom(iter, value);
case 'f': return parse_false_atom(iter, value); case 'f': return visit_false_atom(iter, value);
case 'n': return parse_null_atom(iter, value); case 'n': return visit_null_atom(iter, value);
case '-': case '-':
case '0': case '1': case '2': case '3': case '4': case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9': case '5': case '6': case '7': case '8': case '9':
return parse_number(iter, value); return visit_number(iter, value);
default: default:
iter.log_error("Non-value found when value was expected!"); iter.log_error("Non-value found when value was expected!");
return TAPE_ERROR; return TAPE_ERROR;
} }
} }
SIMDJSON_WARN_UNUSED simdjson_really_inline error_code empty_object(json_iterator &iter) { SIMDJSON_WARN_UNUSED simdjson_really_inline error_code visit_empty_object(json_iterator &iter) {
iter.log_value("empty object"); iter.log_value("empty object");
return empty_container(iter, internal::tape_type::START_OBJECT, internal::tape_type::END_OBJECT); return empty_container(iter, internal::tape_type::START_OBJECT, internal::tape_type::END_OBJECT);
} }
SIMDJSON_WARN_UNUSED simdjson_really_inline error_code empty_array(json_iterator &iter) { SIMDJSON_WARN_UNUSED simdjson_really_inline error_code visit_empty_array(json_iterator &iter) {
iter.log_value("empty array"); iter.log_value("empty array");
return empty_container(iter, internal::tape_type::START_ARRAY, internal::tape_type::END_ARRAY); return empty_container(iter, internal::tape_type::START_ARRAY, internal::tape_type::END_ARRAY);
} }
SIMDJSON_WARN_UNUSED simdjson_really_inline error_code start_document(json_iterator &iter) { SIMDJSON_WARN_UNUSED simdjson_really_inline error_code visit_document_start(json_iterator &iter) {
iter.log_start_value("document"); iter.log_start_value("document");
start_container(iter); start_container(iter);
iter.dom_parser.is_array[iter.depth] = false; iter.dom_parser.is_array[iter.depth] = false;
return SUCCESS; return SUCCESS;
} }
SIMDJSON_WARN_UNUSED simdjson_really_inline error_code start_object(json_iterator &iter) { SIMDJSON_WARN_UNUSED simdjson_really_inline error_code visit_object_start(json_iterator &iter) {
iter.log_start_value("object"); iter.log_start_value("object");
start_container(iter); start_container(iter);
iter.dom_parser.is_array[iter.depth] = false; iter.dom_parser.is_array[iter.depth] = false;
return SUCCESS; return SUCCESS;
} }
SIMDJSON_WARN_UNUSED simdjson_really_inline error_code start_array(json_iterator &iter) { SIMDJSON_WARN_UNUSED simdjson_really_inline error_code visit_array_start(json_iterator &iter) {
iter.log_start_value("array"); iter.log_start_value("array");
start_container(iter); start_container(iter);
iter.dom_parser.is_array[iter.depth] = true; iter.dom_parser.is_array[iter.depth] = true;
return SUCCESS; return SUCCESS;
} }
SIMDJSON_WARN_UNUSED simdjson_really_inline error_code end_object(json_iterator &iter) { SIMDJSON_WARN_UNUSED simdjson_really_inline error_code visit_object_end(json_iterator &iter) {
iter.log_end_value("object"); iter.log_end_value("object");
return end_container(iter, internal::tape_type::START_OBJECT, internal::tape_type::END_OBJECT); return end_container(iter, internal::tape_type::START_OBJECT, internal::tape_type::END_OBJECT);
} }
SIMDJSON_WARN_UNUSED simdjson_really_inline error_code end_array(json_iterator &iter) { SIMDJSON_WARN_UNUSED simdjson_really_inline error_code visit_array_end(json_iterator &iter) {
iter.log_end_value("array"); iter.log_end_value("array");
return end_container(iter, internal::tape_type::START_ARRAY, internal::tape_type::END_ARRAY); return end_container(iter, internal::tape_type::START_ARRAY, internal::tape_type::END_ARRAY);
} }
SIMDJSON_WARN_UNUSED simdjson_really_inline error_code end_document(json_iterator &iter) { SIMDJSON_WARN_UNUSED simdjson_really_inline error_code visit_document_end(json_iterator &iter) {
iter.log_end_value("document"); iter.log_end_value("document");
constexpr uint32_t start_tape_index = 0; constexpr uint32_t start_tape_index = 0;
tape.append(start_tape_index, internal::tape_type::ROOT); tape.append(start_tape_index, internal::tape_type::ROOT);
tape_writer::write(iter.dom_parser.doc->tape[start_tape_index], next_tape_index(iter), internal::tape_type::ROOT); tape_writer::write(iter.dom_parser.doc->tape[start_tape_index], next_tape_index(iter), internal::tape_type::ROOT);
return SUCCESS; return SUCCESS;
} }
SIMDJSON_WARN_UNUSED simdjson_really_inline error_code key(json_iterator &iter, const uint8_t *key) { SIMDJSON_WARN_UNUSED simdjson_really_inline error_code visit_key(json_iterator &iter, const uint8_t *key) {
return parse_string(iter, key, true); return visit_string(iter, key, true);
} }
// increment_count increments the count of keys in an object or values in an array. // increment_count increments the count of keys in an object or values in an array.
@ -111,7 +111,7 @@ private:
simdjson_really_inline tape_builder(dom::document &doc) noexcept : tape{doc.tape.get()}, current_string_buf_loc{doc.string_buf.get()} {} simdjson_really_inline tape_builder(dom::document &doc) noexcept : tape{doc.tape.get()}, current_string_buf_loc{doc.string_buf.get()} {}
SIMDJSON_WARN_UNUSED simdjson_really_inline error_code parse_string(json_iterator &iter, const uint8_t *value, bool key = false) { SIMDJSON_WARN_UNUSED simdjson_really_inline error_code visit_string(json_iterator &iter, const uint8_t *value, bool key = false) {
iter.log_value(key ? "key" : "string"); iter.log_value(key ? "key" : "string");
uint8_t *dst = on_start_string(iter); uint8_t *dst = on_start_string(iter);
dst = stringparsing::parse_string(value, dst); dst = stringparsing::parse_string(value, dst);
@ -123,13 +123,13 @@ private:
return SUCCESS; return SUCCESS;
} }
SIMDJSON_WARN_UNUSED simdjson_really_inline error_code parse_number(json_iterator &iter, const uint8_t *value) { SIMDJSON_WARN_UNUSED simdjson_really_inline error_code visit_number(json_iterator &iter, const uint8_t *value) {
iter.log_value("number"); iter.log_value("number");
if (!numberparsing::parse_number(value, tape)) { iter.log_error("Invalid number"); return NUMBER_ERROR; } if (!numberparsing::parse_number(value, tape)) { iter.log_error("Invalid number"); return NUMBER_ERROR; }
return SUCCESS; return SUCCESS;
} }
SIMDJSON_WARN_UNUSED simdjson_really_inline error_code parse_root_number(json_iterator &iter, const uint8_t *value) { SIMDJSON_WARN_UNUSED simdjson_really_inline error_code visit_root_number(json_iterator &iter, const uint8_t *value) {
// //
// We need to make a copy to make sure that the string is space terminated. // We need to make a copy to make sure that the string is space terminated.
// This is not about padding the input, which should already padded up // This is not about padding the input, which should already padded up
@ -149,47 +149,47 @@ private:
} }
memcpy(copy, value, iter.remaining_len()); memcpy(copy, value, iter.remaining_len());
memset(copy + iter.remaining_len(), ' ', SIMDJSON_PADDING); memset(copy + iter.remaining_len(), ' ', SIMDJSON_PADDING);
error_code error = parse_number(iter, copy); error_code error = visit_number(iter, copy);
free(copy); free(copy);
return error; return error;
} }
SIMDJSON_WARN_UNUSED simdjson_really_inline error_code parse_true_atom(json_iterator &iter, const uint8_t *value) { SIMDJSON_WARN_UNUSED simdjson_really_inline error_code visit_true_atom(json_iterator &iter, const uint8_t *value) {
iter.log_value("true"); iter.log_value("true");
if (!atomparsing::is_valid_true_atom(value)) { return T_ATOM_ERROR; } if (!atomparsing::is_valid_true_atom(value)) { return T_ATOM_ERROR; }
tape.append(0, internal::tape_type::TRUE_VALUE); tape.append(0, internal::tape_type::TRUE_VALUE);
return SUCCESS; return SUCCESS;
} }
SIMDJSON_WARN_UNUSED simdjson_really_inline error_code parse_root_true_atom(json_iterator &iter, const uint8_t *value) { SIMDJSON_WARN_UNUSED simdjson_really_inline error_code visit_root_true_atom(json_iterator &iter, const uint8_t *value) {
iter.log_value("true"); iter.log_value("true");
if (!atomparsing::is_valid_true_atom(value, iter.remaining_len())) { return T_ATOM_ERROR; } if (!atomparsing::is_valid_true_atom(value, iter.remaining_len())) { return T_ATOM_ERROR; }
tape.append(0, internal::tape_type::TRUE_VALUE); tape.append(0, internal::tape_type::TRUE_VALUE);
return SUCCESS; return SUCCESS;
} }
SIMDJSON_WARN_UNUSED simdjson_really_inline error_code parse_false_atom(json_iterator &iter, const uint8_t *value) { SIMDJSON_WARN_UNUSED simdjson_really_inline error_code visit_false_atom(json_iterator &iter, const uint8_t *value) {
iter.log_value("false"); iter.log_value("false");
if (!atomparsing::is_valid_false_atom(value)) { return F_ATOM_ERROR; } if (!atomparsing::is_valid_false_atom(value)) { return F_ATOM_ERROR; }
tape.append(0, internal::tape_type::FALSE_VALUE); tape.append(0, internal::tape_type::FALSE_VALUE);
return SUCCESS; return SUCCESS;
} }
SIMDJSON_WARN_UNUSED simdjson_really_inline error_code parse_root_false_atom(json_iterator &iter, const uint8_t *value) { SIMDJSON_WARN_UNUSED simdjson_really_inline error_code visit_root_false_atom(json_iterator &iter, const uint8_t *value) {
iter.log_value("false"); iter.log_value("false");
if (!atomparsing::is_valid_false_atom(value, iter.remaining_len())) { return F_ATOM_ERROR; } if (!atomparsing::is_valid_false_atom(value, iter.remaining_len())) { return F_ATOM_ERROR; }
tape.append(0, internal::tape_type::FALSE_VALUE); tape.append(0, internal::tape_type::FALSE_VALUE);
return SUCCESS; return SUCCESS;
} }
SIMDJSON_WARN_UNUSED simdjson_really_inline error_code parse_null_atom(json_iterator &iter, const uint8_t *value) { SIMDJSON_WARN_UNUSED simdjson_really_inline error_code visit_null_atom(json_iterator &iter, const uint8_t *value) {
iter.log_value("null"); iter.log_value("null");
if (!atomparsing::is_valid_null_atom(value)) { return N_ATOM_ERROR; } if (!atomparsing::is_valid_null_atom(value)) { return N_ATOM_ERROR; }
tape.append(0, internal::tape_type::NULL_VALUE); tape.append(0, internal::tape_type::NULL_VALUE);
return SUCCESS; return SUCCESS;
} }
SIMDJSON_WARN_UNUSED simdjson_really_inline error_code parse_root_null_atom(json_iterator &iter, const uint8_t *value) { SIMDJSON_WARN_UNUSED simdjson_really_inline error_code visit_root_null_atom(json_iterator &iter, const uint8_t *value) {
iter.log_value("null"); iter.log_value("null");
if (!atomparsing::is_valid_null_atom(value, iter.remaining_len())) { return N_ATOM_ERROR; } if (!atomparsing::is_valid_null_atom(value, iter.remaining_len())) { return N_ATOM_ERROR; }
tape.append(0, internal::tape_type::NULL_VALUE); tape.append(0, internal::tape_type::NULL_VALUE);