@@ -30,31 +30,28 @@ struct number_writer {
30
30
31
31
struct structural_parser {
32
32
structural_iterator structurals;
33
- parser &doc_parser;
34
33
uint32_t depth;
35
34
36
35
really_inline structural_parser (
37
- const uint8_t *buf,
38
36
size_t len,
39
- parser &_doc_parser,
40
- size_t &next_structural
41
- ) : structurals(buf, len, _doc_parser.structural_indexes.get(), next_structural),
42
- doc_parser{_doc_parser},
43
- depth{0 } {
44
- }
37
+ parser &_doc_parser
38
+ ) : structurals(_doc_parser, len), depth{0 } {}
45
39
46
40
really_inline structural_parser (
47
- const uint8_t *buf,
48
41
parser &_doc_parser,
49
- size_t &next_structural,
50
42
uint32_t _depth
51
- ) : structurals(buf, 0 , _doc_parser.structural_indexes.get(), next_structural),
52
- doc_parser{_doc_parser},
53
- depth{_depth} {
43
+ ) : structurals(_doc_parser, 0 ), depth{_depth} {}
44
+
45
+ really_inline parser &doc_parser () {
46
+ return structurals.doc_parser ;
47
+ }
48
+
49
+ really_inline document &doc () {
50
+ return doc_parser ().doc ;
54
51
}
55
52
56
53
WARN_UNUSED really_inline bool start_scope (internal::tape_type type) {
57
- bool exceeded_max_depth = depth >= doc_parser.max_depth ();
54
+ bool exceeded_max_depth = depth >= doc_parser () .max_depth ();
58
55
if (exceeded_max_depth) { log_error (" Exceeded max depth!" ); return true ; }
59
56
write_tape (0 , type); // if the document is correct, this gets rewritten later
60
57
return false ;
@@ -84,7 +81,7 @@ struct structural_parser {
84
81
// the convention being that a cnt of 0xffffff or more is undetermined in value (>= 0xffffff).
85
82
const uint32_t cntsat = count > 0xFFFFFF ? 0xFFFFFF : count;
86
83
// This is a load and an OR. It would be possible to just write once at doc.tape[d.tape_index]
87
- doc_parser. doc .tape [start_loc] |= doc_parser.current_loc | (uint64_t (cntsat) << 32 );
84
+ doc () .tape [start_loc] |= doc_parser () .current_loc | (uint64_t (cntsat) << 32 );
88
85
}
89
86
90
87
really_inline void end_object (uint32_t start_loc, uint32_t count) {
@@ -101,25 +98,25 @@ struct structural_parser {
101
98
}
102
99
103
100
really_inline void write_tape (uint64_t val, internal::tape_type t) noexcept {
104
- doc_parser. doc .tape [doc_parser.current_loc ++] = val | ((uint64_t (char (t))) << 56 );
101
+ doc () .tape [doc_parser () .current_loc ++] = val | ((uint64_t (char (t))) << 56 );
105
102
}
106
103
107
104
really_inline uint8_t *on_start_string () noexcept {
108
105
// we advance the point, accounting for the fact that we have a NULL termination
109
- write_tape (doc_parser.current_string_buf_loc - doc_parser. doc .string_buf .get (), internal::tape_type::STRING);
110
- return doc_parser.current_string_buf_loc + sizeof (uint32_t );
106
+ write_tape (doc_parser () .current_string_buf_loc - doc () .string_buf .get (), internal::tape_type::STRING);
107
+ return doc_parser () .current_string_buf_loc + sizeof (uint32_t );
111
108
}
112
109
113
110
really_inline void on_end_string (uint8_t *dst) noexcept {
114
- uint32_t str_length = uint32_t (dst - (doc_parser.current_string_buf_loc + sizeof (uint32_t )));
111
+ uint32_t str_length = uint32_t (dst - (doc_parser () .current_string_buf_loc + sizeof (uint32_t )));
115
112
// TODO check for overflow in case someone has a crazy string (>=4GB?)
116
113
// But only add the overflow check when the document itself exceeds 4GB
117
114
// Currently unneeded because we refuse to parse docs larger or equal to 4GB.
118
- memcpy (doc_parser.current_string_buf_loc , &str_length, sizeof (uint32_t ));
115
+ memcpy (doc_parser () .current_string_buf_loc , &str_length, sizeof (uint32_t ));
119
116
// NULL termination is still handy if you expect all your strings to
120
117
// be NULL terminated? It comes at a small cost
121
118
*dst = 0 ;
122
- doc_parser.current_string_buf_loc = dst + 1 ;
119
+ doc_parser () .current_string_buf_loc = dst + 1 ;
123
120
}
124
121
125
122
WARN_UNUSED really_inline bool parse_string (bool key = false ) {
@@ -136,7 +133,7 @@ struct structural_parser {
136
133
137
134
WARN_UNUSED really_inline bool parse_number (const uint8_t *src, bool found_minus) {
138
135
log_value (" number" );
139
- number_writer writer{doc_parser};
136
+ number_writer writer{doc_parser () };
140
137
bool succeeded = numberparsing::parse_number (src, found_minus, writer);
141
138
if (!succeeded) { log_error (" Invalid number" ); }
142
139
return !succeeded;
@@ -244,22 +241,16 @@ struct structural_parser {
244
241
}
245
242
246
243
WARN_UNUSED really_inline bool parse_object () {
247
- return parse_object (structurals. buf , doc_parser, structurals. next_structural , depth+1 );
244
+ return parse_object (doc_parser () , depth+1 );
248
245
}
249
246
250
- WARN_UNUSED static bool parse_object (
251
- const uint8_t *buf,
252
- parser &doc_parser,
253
- size_t &next_structural,
254
- uint32_t depth) {
255
- structural_parser parser (buf, doc_parser, next_structural, depth);
256
- bool result = parser.parse_object_inline ();
257
- next_structural = parser.structurals .next_structural ;
258
- return result;
247
+ WARN_UNUSED static bool parse_object (parser &doc_parser, uint32_t depth) {
248
+ structural_parser parser (doc_parser, depth);
249
+ return parser.parse_object_inline ();
259
250
}
260
251
261
252
WARN_UNUSED really_inline bool parse_object_inline () {
262
- uint32_t start_loc = doc_parser.current_loc ;
253
+ uint32_t start_loc = doc_parser () .current_loc ;
263
254
if (start_object ()) { return true ; }
264
255
switch (advance_char ()) {
265
256
case ' "' :
@@ -302,22 +293,16 @@ struct structural_parser {
302
293
}
303
294
304
295
WARN_UNUSED really_inline bool parse_array () {
305
- return parse_array (structurals. buf , doc_parser, structurals. next_structural , depth+1 );
296
+ return parse_array (doc_parser () , depth+1 );
306
297
}
307
298
308
- WARN_UNUSED static bool parse_array (
309
- const uint8_t *buf,
310
- parser &doc_parser,
311
- size_t &next_structural,
312
- uint32_t depth) {
313
- structural_parser parser (buf, doc_parser, next_structural, depth);
314
- bool result = parser.parse_array_inline ();
315
- next_structural = parser.structurals .next_structural ;
316
- return result;
299
+ WARN_UNUSED static bool parse_array (parser &doc_parser, uint32_t depth) {
300
+ structural_parser parser (doc_parser, depth);
301
+ return parser.parse_array_inline ();
317
302
}
318
303
319
304
WARN_UNUSED really_inline bool parse_array_inline () {
320
- uint32_t start_loc = doc_parser.current_loc ;
305
+ uint32_t start_loc = doc_parser () .current_loc ;
321
306
if (start_array ()) { return true ; }
322
307
323
308
if (advance_char () == ' ]' ) {
@@ -346,7 +331,7 @@ struct structural_parser {
346
331
347
332
WARN_UNUSED really_inline error_code finish () {
348
333
// the string might not be NULL terminated.
349
- if ( !structurals.at_end (doc_parser.n_structural_indexes ) ) {
334
+ if ( !structurals.at_end (doc_parser () .n_structural_indexes ) ) {
350
335
log_error (" More than one JSON value at the root of the document, or extra characters at the end of the JSON!" );
351
336
return on_error (TAPE_ERROR);
352
337
}
@@ -356,27 +341,27 @@ struct structural_parser {
356
341
}
357
342
358
343
really_inline error_code on_error (error_code new_error_code) noexcept {
359
- doc_parser.error = new_error_code;
344
+ doc_parser () .error = new_error_code;
360
345
return new_error_code;
361
346
}
362
347
really_inline error_code on_success (error_code success_code) noexcept {
363
- doc_parser.error = success_code;
364
- doc_parser.valid = true ;
348
+ doc_parser () .error = success_code;
349
+ doc_parser () .valid = true ;
365
350
return success_code;
366
351
}
367
352
368
353
WARN_UNUSED really_inline error_code error () {
369
- /* We do not need the next line because this is done by doc_parser.init_stage2(),
354
+ /* We do not need the next line because this is done by doc_parser() .init_stage2(),
370
355
* pessimistically.
371
- * doc_parser.is_valid = false;
356
+ * doc_parser() .is_valid = false;
372
357
* At this point in the code, we have all the time in the world.
373
358
* Note that we know exactly where we are in the document so we could,
374
359
* without any overhead on the processing code, report a specific
375
360
* location.
376
361
* We could even trigger special code paths to assess what happened
377
362
* carefully,
378
363
* all without any added cost. */
379
- if (depth >= doc_parser.max_depth ()) {
364
+ if (depth >= doc_parser () .max_depth ()) {
380
365
return on_error (DEPTH_ERROR);
381
366
}
382
367
switch (structurals.current_char ()) {
@@ -406,16 +391,16 @@ struct structural_parser {
406
391
}
407
392
408
393
really_inline void init () {
409
- doc_parser.current_string_buf_loc = doc_parser. doc .string_buf .get ();
410
- doc_parser.current_loc = 0 ;
411
- doc_parser.valid = false ;
412
- doc_parser.error = UNINITIALIZED;
394
+ doc_parser () .current_string_buf_loc = doc () .string_buf .get ();
395
+ doc_parser () .current_loc = 0 ;
396
+ doc_parser () .valid = false ;
397
+ doc_parser () .error = UNINITIALIZED;
413
398
}
414
399
415
400
WARN_UNUSED really_inline error_code start (size_t len) {
416
401
log_start ();
417
402
init (); // sets is_valid to false
418
- if (len > doc_parser.capacity ()) {
403
+ if (len > doc_parser () .capacity ()) {
419
404
return CAPACITY;
420
405
}
421
406
// Advance to the first character as soon as possible
@@ -461,8 +446,9 @@ struct structural_parser {
461
446
* for documentation.
462
447
***********/
463
448
WARN_UNUSED error_code implementation::stage2 (const uint8_t *buf, size_t len, parser &doc_parser) const noexcept {
464
- size_t next_structural = 0 ;
465
- stage2::structural_parser parser (buf, len, doc_parser, next_structural);
449
+ doc_parser.parsing_buf = buf;
450
+ doc_parser.next_structural = 0 ;
451
+ stage2::structural_parser parser (len, doc_parser);
466
452
error_code result = parser.start (len);
467
453
if (result) { return result; }
468
454
0 commit comments