@@ -10,7 +10,6 @@ class json_iterator {
10
10
uint32_t *next_structural;
11
11
dom_parser_implementation &dom_parser;
12
12
uint32_t depth{0 };
13
- const uint8_t *value{}; // Used to keep a value around between states
14
13
15
14
template <bool STREAMING, typename T>
16
15
SIMDJSON_WARN_UNUSED simdjson_really_inline error_code walk_document (T &visitor) noexcept ;
@@ -26,9 +25,8 @@ class json_iterator {
26
25
simdjson_really_inline char peek_next_char () {
27
26
return buf[*(next_structural)];
28
27
}
29
- simdjson_really_inline char advance () {
30
- value = &buf[*(next_structural++)];
31
- return *value;
28
+ simdjson_really_inline const uint8_t *advance () {
29
+ return &buf[*(next_structural++)];
32
30
}
33
31
simdjson_really_inline size_t remaining_len () {
34
32
return dom_parser.len - *(next_structural-1 );
@@ -97,30 +95,32 @@ SIMDJSON_WARN_UNUSED simdjson_really_inline error_code json_iterator::walk_docum
97
95
//
98
96
// Read first value
99
97
//
100
- advance ();
98
+ {
99
+ auto value = advance ();
100
+
101
+ // Make sure the outer hash or array is closed before continuing; otherwise, there are ways we
102
+ // could get into memory corruption. See https://github.com/simdjson/simdjson/issues/906
103
+ if (!STREAMING) {
104
+ switch (*value) {
105
+ case ' {' :
106
+ if (last_structural () != ' }' ) {
107
+ return TAPE_ERROR;
108
+ }
109
+ break ;
110
+ case ' [' :
111
+ if (last_structural () != ' ]' ) {
112
+ return TAPE_ERROR;
113
+ }
114
+ break ;
115
+ }
116
+ }
101
117
102
- // Make sure the outer hash or array is closed before continuing; otherwise, there are ways we
103
- // could get into memory corruption. See https://github.com/simdjson/simdjson/issues/906
104
- if (!STREAMING) {
105
118
switch (*value) {
106
- case ' {' :
107
- if (last_structural () != ' }' ) {
108
- return TAPE_ERROR;
109
- }
110
- break ;
111
- case ' [' :
112
- if (last_structural () != ' ]' ) {
113
- return TAPE_ERROR;
114
- }
115
- break ;
119
+ case ' {' : if (!empty_object (visitor)) { goto object_begin; }; break ;
120
+ case ' [' : if (!empty_array (visitor)) { goto array_begin; }; break ;
121
+ default : SIMDJSON_TRY ( visitor.root_primitive (*this , value) ); break ;
116
122
}
117
123
}
118
-
119
- switch (*value) {
120
- case ' {' : if (!empty_object (visitor)) { goto object_begin; }; break ;
121
- case ' [' : if (!empty_array (visitor)) { goto array_begin; }; break ;
122
- default : SIMDJSON_TRY ( visitor.root_primitive (*this , value) ); break ;
123
- }
124
124
goto document_end;
125
125
126
126
//
@@ -131,24 +131,33 @@ SIMDJSON_WARN_UNUSED simdjson_really_inline error_code json_iterator::walk_docum
131
131
if (depth >= dom_parser.max_depth ()) { log_error (" Exceeded max depth!" ); return DEPTH_ERROR; }
132
132
SIMDJSON_TRY ( visitor.start_object (*this ) );
133
133
134
- if (advance () != ' "' ) { log_error (" Object does not start with a key" ); return TAPE_ERROR; }
135
- visitor.increment_count (*this );
136
- SIMDJSON_TRY ( visitor.key (*this , value) );
134
+ {
135
+ auto key = advance ();
136
+ if (*key != ' "' ) { log_error (" Object does not start with a key" ); return TAPE_ERROR; }
137
+ visitor.increment_count (*this );
138
+ SIMDJSON_TRY ( visitor.key (*this , key) );
139
+ }
137
140
138
141
object_field:
139
- if (simdjson_unlikely ( advance () != ' :' )) { log_error (" Missing colon after key in object" ); return TAPE_ERROR; }
140
- switch (advance ()) {
141
- case ' {' : if (!empty_object (visitor)) { goto object_begin; }; break ;
142
- case ' [' : if (!empty_array (visitor)) { goto array_begin; }; break ;
143
- default : SIMDJSON_TRY ( visitor.primitive (*this , value) ); break ;
142
+ if (simdjson_unlikely ( *advance () != ' :' )) { log_error (" Missing colon after key in object" ); return TAPE_ERROR; }
143
+ {
144
+ auto value = advance ();
145
+ switch (*value) {
146
+ case ' {' : if (!empty_object (visitor)) { goto object_begin; }; break ;
147
+ case ' [' : if (!empty_array (visitor)) { goto array_begin; }; break ;
148
+ default : SIMDJSON_TRY ( visitor.primitive (*this , value) ); break ;
149
+ }
144
150
}
145
151
146
152
object_continue:
147
- switch (advance ()) {
153
+ switch (* advance ()) {
148
154
case ' ,' :
149
155
visitor.increment_count (*this );
150
- if (simdjson_unlikely ( advance () != ' "' )) { log_error (" Key string missing at beginning of field in object" ); return TAPE_ERROR; }
151
- SIMDJSON_TRY ( visitor.key (*this , value) );
156
+ {
157
+ auto key = advance ();
158
+ if (simdjson_unlikely ( *key != ' "' )) { log_error (" Key string missing at beginning of field in object" ); return TAPE_ERROR; }
159
+ SIMDJSON_TRY ( visitor.key (*this , key) );
160
+ }
152
161
goto object_field;
153
162
case ' }' : SIMDJSON_TRY ( visitor.end_object (*this ) ); goto scope_end;
154
163
default : log_error (" No comma between object fields" ); return TAPE_ERROR;
@@ -170,14 +179,17 @@ SIMDJSON_WARN_UNUSED simdjson_really_inline error_code json_iterator::walk_docum
170
179
visitor.increment_count (*this );
171
180
172
181
array_value:
173
- switch (advance ()) {
174
- case ' {' : if (!empty_object (visitor)) { goto object_begin; }; break ;
175
- case ' [' : if (!empty_array (visitor)) { goto array_begin; }; break ;
176
- default : SIMDJSON_TRY ( visitor.primitive (*this , value) ); break ;
182
+ {
183
+ auto value = advance ();
184
+ switch (*value) {
185
+ case ' {' : if (!empty_object (visitor)) { goto object_begin; }; break ;
186
+ case ' [' : if (!empty_array (visitor)) { goto array_begin; }; break ;
187
+ default : SIMDJSON_TRY ( visitor.primitive (*this , value) ); break ;
188
+ }
177
189
}
178
190
179
191
array_continue:
180
- switch (advance ()) {
192
+ switch (* advance ()) {
181
193
case ' ,' : visitor.increment_count (*this ); goto array_value;
182
194
case ' ]' : SIMDJSON_TRY ( visitor.end_array (*this ) ); goto scope_end;
183
195
default : log_error (" Missing comma between array values" ); return TAPE_ERROR;
0 commit comments