@@ -11,22 +11,94 @@ class json_iterator {
11
11
dom_parser_implementation &dom_parser;
12
12
uint32_t depth{0 };
13
13
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
+ */
14
37
template <bool STREAMING, typename V>
15
38
SIMDJSON_WARN_UNUSED simdjson_really_inline error_code walk_document (V &visitor) noexcept ;
16
39
40
+ /* *
41
+ * Create an iterator capable of walking a JSON document.
42
+ *
43
+ * The document must have already passed through stage 1.
44
+ */
17
45
simdjson_really_inline json_iterator (dom_parser_implementation &_dom_parser, size_t start_structural_index);
18
46
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
+ */
21
62
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
+ */
22
66
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
+ */
24
76
simdjson_really_inline bool at_beginning () const noexcept ;
25
77
simdjson_really_inline uint8_t last_structural () const noexcept ;
26
78
79
+ /* *
80
+ * Log that a value has been found.
81
+ *
82
+ * Set ENABLE_LOGGING=true in logger.h to see logging.
83
+ */
27
84
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
+ */
28
90
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
+ */
29
96
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
+ */
30
102
simdjson_really_inline void log_error (const char *error) const noexcept ;
31
103
};
32
104
@@ -37,7 +109,7 @@ SIMDJSON_WARN_UNUSED simdjson_really_inline error_code json_iterator::walk_docum
37
109
//
38
110
// Start the document
39
111
//
40
- if (at_end ()) { return EMPTY; }
112
+ if (at_eof ()) { return EMPTY; }
41
113
SIMDJSON_TRY ( visitor.visit_document_start (*this ) );
42
114
43
115
//
@@ -64,8 +136,8 @@ SIMDJSON_WARN_UNUSED simdjson_really_inline error_code json_iterator::walk_docum
64
136
}
65
137
66
138
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;
69
141
default : SIMDJSON_TRY ( visitor.visit_root_primitive (*this , value) ); break ;
70
142
}
71
143
}
@@ -92,8 +164,8 @@ SIMDJSON_WARN_UNUSED simdjson_really_inline error_code json_iterator::walk_docum
92
164
{
93
165
auto value = advance ();
94
166
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;
97
169
default : SIMDJSON_TRY ( visitor.visit_primitive (*this , value) ); break ;
98
170
}
99
171
}
@@ -132,8 +204,8 @@ SIMDJSON_WARN_UNUSED simdjson_really_inline error_code json_iterator::walk_docum
132
204
{
133
205
auto value = advance ();
134
206
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;
137
209
default : SIMDJSON_TRY ( visitor.visit_primitive (*this , value) ); break ;
138
210
}
139
211
}
@@ -166,8 +238,8 @@ simdjson_really_inline json_iterator::json_iterator(dom_parser_implementation &_
166
238
dom_parser{_dom_parser} {
167
239
}
168
240
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)];
171
243
}
172
244
simdjson_really_inline const uint8_t *json_iterator::advance () noexcept {
173
245
return &buf[*(next_structural++)];
@@ -176,7 +248,7 @@ simdjson_really_inline size_t json_iterator::remaining_len() const noexcept {
176
248
return dom_parser.len - *(next_structural-1 );
177
249
}
178
250
179
- simdjson_really_inline bool json_iterator::at_end () const noexcept {
251
+ simdjson_really_inline bool json_iterator::at_eof () const noexcept {
180
252
return next_structural == &dom_parser.structural_indexes [dom_parser.n_structural_indexes ];
181
253
}
182
254
simdjson_really_inline bool json_iterator::at_beginning () const noexcept {
0 commit comments