@@ -39,7 +39,13 @@ struct structural_parser : structural_iterator {
39
39
40
40
WARN_UNUSED really_inline error_code start_document () {
41
41
log_start_value (" document" );
42
- return start_scope (false );
42
+ parser.containing_scope [depth].tape_index = next_tape_index ();
43
+ parser.containing_scope [depth].count = 0 ;
44
+ tape.skip (); // We don't actually *write* the start element until the end.
45
+ parser.is_array [depth] = false ;
46
+ depth++;
47
+ if (depth >= parser.max_depth ()) { log_error (" Exceeded max depth!" ); return DEPTH_ERROR; }
48
+ return SUCCESS;
43
49
}
44
50
45
51
WARN_UNUSED really_inline error_code start_object (bool parent_is_array) {
@@ -55,15 +61,14 @@ struct structural_parser : structural_iterator {
55
61
// this function is responsible for annotating the start of the scope
56
62
really_inline void end_scope (internal::tape_type start, internal::tape_type end) noexcept {
57
63
depth--;
58
- // write our doc->tape location to the header scope
59
- // The root scope gets written *at* the previous location.
60
- tape.append (parser.containing_scope [depth].tape_index , end);
64
+ // Write the ending tape element, pointing at the start location
65
+ const uint32_t start_tape_index = parser.containing_scope [depth].tape_index ;
66
+ tape.append (start_tape_index, end);
67
+ // Write the start tape element, pointing at the end location (and including count)
61
68
// count can overflow if it exceeds 24 bits... so we saturate
62
69
// the convention being that a cnt of 0xffffff or more is undetermined in value (>= 0xffffff).
63
- const uint32_t start_tape_index = parser.containing_scope [depth].tape_index ;
64
70
const uint32_t count = parser.containing_scope [depth].count ;
65
71
const uint32_t cntsat = count > 0xFFFFFF ? 0xFFFFFF : count;
66
- // This is a load and an OR. It would be possible to just write once at doc->tape[d.tape_index]
67
72
tape_writer::write (parser.doc ->tape [start_tape_index], next_tape_index () | (uint64_t (cntsat) << 32 ), start);
68
73
}
69
74
@@ -81,7 +86,10 @@ struct structural_parser : structural_iterator {
81
86
}
82
87
really_inline void end_document () {
83
88
log_end_value (" document" );
84
- end_scope (internal::tape_type::ROOT, internal::tape_type::ROOT);
89
+ depth--;
90
+ constexpr uint32_t start_tape_index = 0 ;
91
+ tape.append (start_tape_index, internal::tape_type::ROOT);
92
+ tape_writer::write (parser.doc ->tape [start_tape_index], next_tape_index (), internal::tape_type::ROOT);
85
93
}
86
94
87
95
really_inline void empty_container (internal::tape_type start, internal::tape_type end) {
0 commit comments