Skip to content

Commit 74c4799

Browse files
committed
Document json_iterator
1 parent 24f5936 commit 74c4799

File tree

1 file changed

+85
-13
lines changed

1 file changed

+85
-13
lines changed

src/generic/stage2/json_iterator.h

Lines changed: 85 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -11,22 +11,94 @@ class json_iterator {
1111
dom_parser_implementation &dom_parser;
1212
uint32_t depth{0};
1313

14+
/**
15+
* Walk the JSON document.
16+
*
17+
* The visitor receives callbacks when values are encountered. All callbacks pass the iterator as
18+
* the first parameter; some callbacks have other parameters as well:
19+
*
20+
* - visit_document_start() - at the beginning.
21+
* - visit_document_end() - at the end (if things were successful).
22+
*
23+
* - visit_array_start() - at the start `[` of a non-empty array.
24+
* - visit_array_end() - at the end `]` of a non-empty array.
25+
* - visit_empty_array() - when an empty array is encountered.
26+
*
27+
* - visit_object_end() - at the start `]` of a non-empty object.
28+
* - visit_object_start() - at the end `]` of a non-empty object.
29+
* - visit_empty_object() - when an empty object is encountered.
30+
* - visit_key(const uint8_t *key) - when a key in an object field is encountered. key is
31+
* guaranteed to point at the first quote of the string (`"key"`).
32+
* - visit_primitive(const uint8_t *value) - when a value is a string, number, boolean or null.
33+
* - visit_root_primitive(iter, uint8_t *value) - when the top-level value is a string, number, boolean or null.
34+
*
35+
* - increment_count(iter) - each time a value is found in an array or object.
36+
*/
1437
template<bool STREAMING, typename V>
1538
SIMDJSON_WARN_UNUSED simdjson_really_inline error_code walk_document(V &visitor) noexcept;
1639

40+
/**
41+
* Create an iterator capable of walking a JSON document.
42+
*
43+
* The document must have already passed through stage 1.
44+
*/
1745
simdjson_really_inline json_iterator(dom_parser_implementation &_dom_parser, size_t start_structural_index);
1846

19-
// Get the buffer position of the current structural character
20-
simdjson_really_inline char peek_next_char() const noexcept;
47+
/**
48+
* Look at the next token.
49+
*
50+
* Tokens can be strings, numbers, booleans, null, or operators (`[{]},:`)).
51+
*
52+
* They may include invalid JSON as well (such as `1.2.3` or `ture`).
53+
*/
54+
simdjson_really_inline const uint8_t *peek() const noexcept;
55+
/**
56+
* Advance to the next token.
57+
*
58+
* Tokens can be strings, numbers, booleans, null, or operators (`[{]},:`)).
59+
*
60+
* They may include invalid JSON as well (such as `1.2.3` or `ture`).
61+
*/
2162
simdjson_really_inline const uint8_t *advance() noexcept;
63+
/**
64+
* Get the remaining length of the document, from the start of the current token.
65+
*/
2266
simdjson_really_inline size_t remaining_len() const noexcept;
23-
simdjson_really_inline bool at_end() const noexcept;
67+
/**
68+
* Check if we are at the end of the document.
69+
*
70+
* If this is true, there are no more tokens.
71+
*/
72+
simdjson_really_inline bool at_eof() const noexcept;
73+
/**
74+
* Check if we are at the beginning of the document.
75+
*/
2476
simdjson_really_inline bool at_beginning() const noexcept;
2577
simdjson_really_inline uint8_t last_structural() const noexcept;
2678

79+
/**
80+
* Log that a value has been found.
81+
*
82+
* Set ENABLE_LOGGING=true in logger.h to see logging.
83+
*/
2784
simdjson_really_inline void log_value(const char *type) const noexcept;
85+
/**
86+
* Log the start of a multipart value.
87+
*
88+
* Set ENABLE_LOGGING=true in logger.h to see logging.
89+
*/
2890
simdjson_really_inline void log_start_value(const char *type) const noexcept;
91+
/**
92+
* Log the end of a multipart value.
93+
*
94+
* Set ENABLE_LOGGING=true in logger.h to see logging.
95+
*/
2996
simdjson_really_inline void log_end_value(const char *type) const noexcept;
97+
/**
98+
* Log an error.
99+
*
100+
* Set ENABLE_LOGGING=true in logger.h to see logging.
101+
*/
30102
simdjson_really_inline void log_error(const char *error) const noexcept;
31103
};
32104

@@ -37,7 +109,7 @@ SIMDJSON_WARN_UNUSED simdjson_really_inline error_code json_iterator::walk_docum
37109
//
38110
// Start the document
39111
//
40-
if (at_end()) { return EMPTY; }
112+
if (at_eof()) { return EMPTY; }
41113
SIMDJSON_TRY( visitor.visit_document_start(*this) );
42114

43115
//
@@ -64,8 +136,8 @@ SIMDJSON_WARN_UNUSED simdjson_really_inline error_code json_iterator::walk_docum
64136
}
65137

66138
switch (*value) {
67-
case '{': if (peek_next_char() == '}') { advance(); SIMDJSON_TRY( visitor.visit_empty_object(*this) ); break; } goto object_begin;
68-
case '[': if (peek_next_char() == ']') { advance(); SIMDJSON_TRY( visitor.visit_empty_array(*this) ); break; } goto array_begin;
139+
case '{': if (*peek() == '}') { advance(); SIMDJSON_TRY( visitor.visit_empty_object(*this) ); break; } goto object_begin;
140+
case '[': if (*peek() == ']') { advance(); SIMDJSON_TRY( visitor.visit_empty_array(*this) ); break; } goto array_begin;
69141
default: SIMDJSON_TRY( visitor.visit_root_primitive(*this, value) ); break;
70142
}
71143
}
@@ -92,8 +164,8 @@ SIMDJSON_WARN_UNUSED simdjson_really_inline error_code json_iterator::walk_docum
92164
{
93165
auto value = advance();
94166
switch (*value) {
95-
case '{': if (peek_next_char() == '}') { advance(); SIMDJSON_TRY( visitor.visit_empty_object(*this) ); break; } goto object_begin;
96-
case '[': if (peek_next_char() == ']') { advance(); SIMDJSON_TRY( visitor.visit_empty_array(*this) ); break; } goto array_begin;
167+
case '{': if (*peek() == '}') { advance(); SIMDJSON_TRY( visitor.visit_empty_object(*this) ); break; } goto object_begin;
168+
case '[': if (*peek() == ']') { advance(); SIMDJSON_TRY( visitor.visit_empty_array(*this) ); break; } goto array_begin;
97169
default: SIMDJSON_TRY( visitor.visit_primitive(*this, value) ); break;
98170
}
99171
}
@@ -132,8 +204,8 @@ SIMDJSON_WARN_UNUSED simdjson_really_inline error_code json_iterator::walk_docum
132204
{
133205
auto value = advance();
134206
switch (*value) {
135-
case '{': if (peek_next_char() == '}') { advance(); SIMDJSON_TRY( visitor.visit_empty_object(*this) ); break; } goto object_begin;
136-
case '[': if (peek_next_char() == ']') { advance(); SIMDJSON_TRY( visitor.visit_empty_array(*this) ); break; } goto array_begin;
207+
case '{': if (*peek() == '}') { advance(); SIMDJSON_TRY( visitor.visit_empty_object(*this) ); break; } goto object_begin;
208+
case '[': if (*peek() == ']') { advance(); SIMDJSON_TRY( visitor.visit_empty_array(*this) ); break; } goto array_begin;
137209
default: SIMDJSON_TRY( visitor.visit_primitive(*this, value) ); break;
138210
}
139211
}
@@ -166,8 +238,8 @@ simdjson_really_inline json_iterator::json_iterator(dom_parser_implementation &_
166238
dom_parser{_dom_parser} {
167239
}
168240

169-
simdjson_really_inline char json_iterator::peek_next_char() const noexcept {
170-
return buf[*(next_structural)];
241+
simdjson_really_inline const uint8_t *json_iterator::peek() const noexcept {
242+
return &buf[*(next_structural)];
171243
}
172244
simdjson_really_inline const uint8_t *json_iterator::advance() noexcept {
173245
return &buf[*(next_structural++)];
@@ -176,7 +248,7 @@ simdjson_really_inline size_t json_iterator::remaining_len() const noexcept {
176248
return dom_parser.len - *(next_structural-1);
177249
}
178250

179-
simdjson_really_inline bool json_iterator::at_end() const noexcept {
251+
simdjson_really_inline bool json_iterator::at_eof() const noexcept {
180252
return next_structural == &dom_parser.structural_indexes[dom_parser.n_structural_indexes];
181253
}
182254
simdjson_really_inline bool json_iterator::at_beginning() const noexcept {

0 commit comments

Comments
 (0)