@@ -51,21 +51,21 @@ struct number_writer {
51
51
parser &doc_parser;
52
52
53
53
really_inline void write_s64 (int64_t value) noexcept {
54
- write_tape (0 , internal::tape_type::INT64);
54
+ append_tape (0 , internal::tape_type::INT64);
55
55
std::memcpy (&doc_parser.doc .tape [doc_parser.current_loc ], &value, sizeof (value));
56
56
++doc_parser.current_loc ;
57
57
}
58
58
really_inline void write_u64 (uint64_t value) noexcept {
59
- write_tape (0 , internal::tape_type::UINT64);
59
+ append_tape (0 , internal::tape_type::UINT64);
60
60
doc_parser.doc .tape [doc_parser.current_loc ++] = value;
61
61
}
62
62
really_inline void write_double (double value) noexcept {
63
- write_tape (0 , internal::tape_type::DOUBLE);
63
+ append_tape (0 , internal::tape_type::DOUBLE);
64
64
static_assert (sizeof (value) == sizeof (doc_parser.doc .tape [doc_parser.current_loc ]), " mismatch size" );
65
65
memcpy (&doc_parser.doc .tape [doc_parser.current_loc ++], &value, sizeof (double ));
66
66
// doc.tape[doc.current_loc++] = *((uint64_t *)&d);
67
67
}
68
- really_inline void write_tape (uint64_t val, internal::tape_type t) noexcept {
68
+ really_inline void append_tape (uint64_t val, internal::tape_type t) noexcept {
69
69
doc_parser.doc .tape [doc_parser.current_loc ++] = val | ((uint64_t (char (t))) << 56 );
70
70
}
71
71
}; // struct number_writer
@@ -84,10 +84,10 @@ struct structural_parser {
84
84
uint32_t next_structural = 0
85
85
) : structurals(buf, len, _doc_parser.structural_indexes.get(), next_structural), doc_parser{_doc_parser}, depth{0 } {}
86
86
87
- WARN_UNUSED really_inline bool start_scope (internal::tape_type type, ret_address continue_state) {
87
+ WARN_UNUSED really_inline bool start_scope (ret_address continue_state) {
88
88
doc_parser.containing_scope [depth].tape_index = doc_parser.current_loc ;
89
89
doc_parser.containing_scope [depth].count = 0 ;
90
- write_tape ( 0 , type) ; // if the document is correct, this gets rewritten later
90
+ doc_parser. current_loc ++ ; // We don't actually *write* the start element until the end.
91
91
doc_parser.ret_address [depth] = continue_state;
92
92
depth++;
93
93
bool exceeded_max_depth = depth >= doc_parser.max_depth ();
@@ -97,51 +97,55 @@ struct structural_parser {
97
97
98
98
WARN_UNUSED really_inline bool start_document (ret_address continue_state) {
99
99
log_start_value (" document" );
100
- return start_scope (internal::tape_type::ROOT, continue_state);
100
+ return start_scope (continue_state);
101
101
}
102
102
103
103
WARN_UNUSED really_inline bool start_object (ret_address continue_state) {
104
104
log_start_value (" object" );
105
- return start_scope (internal::tape_type::START_OBJECT, continue_state);
105
+ return start_scope (continue_state);
106
106
}
107
107
108
108
WARN_UNUSED really_inline bool start_array (ret_address continue_state) {
109
109
log_start_value (" array" );
110
- return start_scope (internal::tape_type::START_ARRAY, continue_state);
110
+ return start_scope (continue_state);
111
111
}
112
112
113
113
// this function is responsible for annotating the start of the scope
114
- really_inline void end_scope (internal::tape_type type ) noexcept {
114
+ really_inline void end_scope (internal::tape_type start, internal::tape_type end ) noexcept {
115
115
depth--;
116
116
// write our doc.tape location to the header scope
117
117
// The root scope gets written *at* the previous location.
118
- write_tape (doc_parser.containing_scope [depth].tape_index , type );
118
+ append_tape (doc_parser.containing_scope [depth].tape_index , end );
119
119
// count can overflow if it exceeds 24 bits... so we saturate
120
120
// the convention being that a cnt of 0xffffff or more is undetermined in value (>= 0xffffff).
121
121
const uint32_t start_tape_index = doc_parser.containing_scope [depth].tape_index ;
122
122
const uint32_t count = doc_parser.containing_scope [depth].count ;
123
123
const uint32_t cntsat = count > 0xFFFFFF ? 0xFFFFFF : count;
124
124
// This is a load and an OR. It would be possible to just write once at doc.tape[d.tape_index]
125
- doc_parser. doc . tape [ start_tape_index] |= doc_parser.current_loc | (uint64_t (cntsat) << 32 );
125
+ write_tape ( start_tape_index, doc_parser.current_loc | (uint64_t (cntsat) << 32 ), start );
126
126
}
127
127
128
128
really_inline void end_object () {
129
129
log_end_value (" object" );
130
- end_scope (internal::tape_type::END_OBJECT);
130
+ end_scope (internal::tape_type::START_OBJECT, internal::tape_type:: END_OBJECT);
131
131
}
132
132
really_inline void end_array () {
133
133
log_end_value (" array" );
134
- end_scope (internal::tape_type::END_ARRAY);
134
+ end_scope (internal::tape_type::START_ARRAY, internal::tape_type:: END_ARRAY);
135
135
}
136
136
really_inline void end_document () {
137
137
log_end_value (" document" );
138
- end_scope (internal::tape_type::ROOT);
138
+ end_scope (internal::tape_type::ROOT, internal::tape_type::ROOT );
139
139
}
140
140
141
- really_inline void write_tape (uint64_t val, internal::tape_type t) noexcept {
141
+ really_inline void append_tape (uint64_t val, internal::tape_type t) noexcept {
142
142
doc_parser.doc .tape [doc_parser.current_loc ++] = val | ((uint64_t (char (t))) << 56 );
143
143
}
144
144
145
+ really_inline void write_tape (uint32_t loc, uint64_t val, internal::tape_type t) noexcept {
146
+ doc_parser.doc .tape [loc] = val | ((uint64_t (char (t))) << 56 );
147
+ }
148
+
145
149
// increment_count increments the count of keys in an object or values in an array.
146
150
// Note that if you are at the level of the values or elements, the count
147
151
// must be increment in the preceding depth (depth-1) where the array or
@@ -152,7 +156,7 @@ struct structural_parser {
152
156
153
157
really_inline uint8_t *on_start_string () noexcept {
154
158
// we advance the point, accounting for the fact that we have a NULL termination
155
- write_tape (current_string_buf_loc - doc_parser.doc .string_buf .get (), internal::tape_type::STRING);
159
+ append_tape (current_string_buf_loc - doc_parser.doc .string_buf .get (), internal::tape_type::STRING);
156
160
return current_string_buf_loc + sizeof (uint32_t );
157
161
}
158
162
@@ -196,17 +200,17 @@ struct structural_parser {
196
200
case ' t' :
197
201
log_value (" true" );
198
202
if (!atomparsing::is_valid_true_atom (structurals.current ())) { return true ; }
199
- write_tape (0 , internal::tape_type::TRUE_VALUE);
203
+ append_tape (0 , internal::tape_type::TRUE_VALUE);
200
204
break ;
201
205
case ' f' :
202
206
log_value (" false" );
203
207
if (!atomparsing::is_valid_false_atom (structurals.current ())) { return true ; }
204
- write_tape (0 , internal::tape_type::FALSE_VALUE);
208
+ append_tape (0 , internal::tape_type::FALSE_VALUE);
205
209
break ;
206
210
case ' n' :
207
211
log_value (" null" );
208
212
if (!atomparsing::is_valid_null_atom (structurals.current ())) { return true ; }
209
- write_tape (0 , internal::tape_type::NULL_VALUE);
213
+ append_tape (0 , internal::tape_type::NULL_VALUE);
210
214
break ;
211
215
default :
212
216
log_error (" IMPOSSIBLE: unrecognized parse_atom structural character" );
@@ -220,17 +224,17 @@ struct structural_parser {
220
224
case ' t' :
221
225
log_value (" true" );
222
226
if (!atomparsing::is_valid_true_atom (structurals.current (), structurals.remaining_len ())) { return true ; }
223
- write_tape (0 , internal::tape_type::TRUE_VALUE);
227
+ append_tape (0 , internal::tape_type::TRUE_VALUE);
224
228
break ;
225
229
case ' f' :
226
230
log_value (" false" );
227
231
if (!atomparsing::is_valid_false_atom (structurals.current (), structurals.remaining_len ())) { return true ; }
228
- write_tape (0 , internal::tape_type::FALSE_VALUE);
232
+ append_tape (0 , internal::tape_type::FALSE_VALUE);
229
233
break ;
230
234
case ' n' :
231
235
log_value (" null" );
232
236
if (!atomparsing::is_valid_null_atom (structurals.current (), structurals.remaining_len ())) { return true ; }
233
- write_tape (0 , internal::tape_type::NULL_VALUE);
237
+ append_tape (0 , internal::tape_type::NULL_VALUE);
234
238
break ;
235
239
default :
236
240
log_error (" IMPOSSIBLE: unrecognized parse_atom structural character" );
0 commit comments