1
1
use crate :: lazy:: binary:: raw:: type_descriptor:: Header ;
2
- use crate :: types:: SymbolId ;
3
2
use crate :: IonType ;
4
3
use std:: ops:: Range ;
5
4
@@ -53,33 +52,29 @@ pub(crate) struct EncodedValue<HeaderType: EncodedHeader> {
53
52
// and IonType.
54
53
pub ( crate ) header : HeaderType ,
55
54
56
- // Each encoded value has up to five components, appearing in the following order:
55
+ // Each encoded value has up to four components, appearing in the following order:
57
56
//
58
- // [ field_id? | annotations? | header (type descriptor) | header_length? | value ]
57
+ // [ annotations? | header (type descriptor) | header_length? | value_body ]
59
58
//
60
59
// Components shown with a `?` are optional.
61
60
//
62
61
// EncodedValue stores the offset of the type descriptor byte from the beginning of the
63
62
// data source (`header_offset`). The lengths of the other fields can be used to calculate
64
63
// their positions relative to the type descriptor byte. For example, to find the offset of the
65
- // field ID (if present), we can do:
66
- // header_offset - annotations_header_length - field_id_length
64
+ // annotations header (if present), we can do:
65
+ // header_offset - annotations_header_length
67
66
//
68
67
// This allows us to store a single `usize` for the header offset, while other lengths can be
69
- // packed into a `u8`. Values are not permitted to have a field ID or annotations that take
70
- // more than 255 bytes to represent.
68
+ // packed into a `u8`. In this implementation, values are not permitted to have annotations that
69
+ // take more than 255 bytes to represent.
71
70
//
72
71
// We store the offset for the header byte because it is guaranteed to be present for all values.
73
- // Field IDs and annotations appear earlier in the stream but are optional.
74
-
75
- // The number of bytes used to encode the field ID (if present) preceding the Ion value. If
76
- // `field_id` is undefined, `field_id_length` will be zero.
77
- pub field_id_length : u8 ,
78
- // If this value is inside a struct, `field_id` will contain the SymbolId that represents
79
- // its field name.
80
- pub field_id : Option < SymbolId > ,
72
+ // Annotations appear earlier in the stream but are optional.
73
+
81
74
// The number of bytes used to encode the annotations wrapper (if present) preceding the Ion
82
- // value. If `annotations` is empty, `annotations_header_length` will be zero.
75
+ // value. If `annotations` is empty, `annotations_header_length` will be zero. The annotations
76
+ // wrapper contains several fields: an opcode, a wrapper length, a sequence length, and the
77
+ // sequence itself.
83
78
pub annotations_header_length : u8 ,
84
79
// The number of bytes used to encode the series of symbol IDs inside the annotations wrapper.
85
80
pub annotations_sequence_length : u8 ,
@@ -89,9 +84,9 @@ pub(crate) struct EncodedValue<HeaderType: EncodedHeader> {
89
84
pub length_length : u8 ,
90
85
// The number of bytes used to encode the value itself, not including the header byte
91
86
// or length fields.
92
- pub value_length : usize ,
87
+ pub value_body_length : usize ,
93
88
// The sum total of:
94
- // field_id_length + annotations_header_length + header_length + value_length
89
+ // annotations_header_length + header_length + value_length
95
90
// While this can be derived from the above fields, storing it for reuse offers a modest
96
91
// optimization. `total_length` is needed when stepping into a value, skipping a value,
97
92
// and reading a value's data.
@@ -127,53 +122,27 @@ impl<HeaderType: EncodedHeader> EncodedValue<HeaderType> {
127
122
/// If the value can fit in the type descriptor byte (e.g. `true`, `false`, `null`, `0`),
128
123
/// this function will return 0.
129
124
#[ inline( always) ]
130
- pub fn value_length ( & self ) -> usize {
131
- self . value_length
125
+ pub fn value_body_length ( & self ) -> usize {
126
+ self . value_body_length
132
127
}
133
128
134
129
/// The offset of the first byte following the header (including length bytes, if present).
135
130
/// If `value_length()` returns zero, this offset is actually the first byte of
136
131
/// the next encoded value and should not be read.
137
- pub fn value_offset ( & self ) -> usize {
132
+ pub fn value_body_offset ( & self ) -> usize {
138
133
self . header_offset + self . header_length ( )
139
134
}
140
135
141
136
/// Returns an offset Range containing any bytes following the header.
142
- pub fn value_range ( & self ) -> Range < usize > {
143
- let start = self . value_offset ( ) ;
144
- let end = start + self . value_length ;
137
+ pub fn value_body_range ( & self ) -> Range < usize > {
138
+ let start = self . value_body_offset ( ) ;
139
+ let end = start + self . value_body_length ;
145
140
start..end
146
141
}
147
142
148
143
/// Returns the index of the first byte that is beyond the end of the current value's encoding.
149
144
pub fn value_end_exclusive ( & self ) -> usize {
150
- self . value_offset ( ) + self . value_length
151
- }
152
-
153
- /// Returns the number of bytes used to encode this value's field ID, if present.
154
- pub fn field_id_length ( & self ) -> Option < usize > {
155
- self . field_id . as_ref ( ) ?;
156
- Some ( self . field_id_length as usize )
157
- }
158
-
159
- /// Returns the offset of the first byte used to encode this value's field ID, if present.
160
- pub fn field_id_offset ( & self ) -> Option < usize > {
161
- self . field_id . as_ref ( ) ?;
162
- Some (
163
- self . header_offset
164
- - self . annotations_header_length as usize
165
- - self . field_id_length as usize ,
166
- )
167
- }
168
-
169
- /// Returns an offset Range that contains the bytes used to encode this value's field ID,
170
- /// if present.
171
- pub fn field_id_range ( & self ) -> Option < Range < usize > > {
172
- if let Some ( start) = self . field_id_offset ( ) {
173
- let end = start + self . field_id_length as usize ;
174
- return Some ( start..end) ;
175
- }
176
- None
145
+ self . value_body_offset ( ) + self . value_body_length
177
146
}
178
147
179
148
/// Returns true if this encoded value has an annotations wrapper.
@@ -233,20 +202,28 @@ impl<HeaderType: EncodedHeader> EncodedValue<HeaderType> {
233
202
None
234
203
}
235
204
236
- /// Returns the total number of bytes used to represent the current value, including the
237
- /// field ID (if any), its annotations (if any), its header (type descriptor + length bytes),
238
- /// and its value.
205
+ /// Returns the total number of bytes used to represent the current value, including
206
+ /// its annotations (if any), its header (type descriptor + length bytes), and the body of
207
+ /// the value.
239
208
pub fn total_length ( & self ) -> usize {
240
209
self . total_length
241
210
}
242
211
243
212
/// The offset Range (starting from the beginning of the stream) that contains this value's
244
- /// complete encoding, including annotations. (It does not include the leading field ID, if
245
- /// any.)
213
+ /// complete encoding, including annotations.
246
214
pub fn annotated_value_range ( & self ) -> Range < usize > {
247
- // [ field_id? | annotations? | header (type descriptor) | header_length? | value ]
215
+ // [ annotations? | header (type descriptor) | header_length? | value ]
216
+ let start = self . header_offset - self . annotations_header_length as usize ;
217
+ let end = start + self . total_length ;
218
+ start..end
219
+ }
220
+
221
+ /// The offset Range (starting from the beginning of the stream) that contains this value's
222
+ /// complete encoding, not including any annotations.
223
+ pub fn unannotated_value_range ( & self ) -> Range < usize > {
224
+ // [ annotations? | header (type descriptor) | header_length? | value ]
248
225
let start = self . header_offset - self . annotations_header_length as usize ;
249
- let end = start - self . field_id_length as usize + self . total_length ;
226
+ let end = start + self . total_length ;
250
227
start..end
251
228
}
252
229
@@ -264,20 +241,18 @@ mod tests {
264
241
265
242
#[ test]
266
243
fn accessors ( ) -> IonResult < ( ) > {
267
- // 3-byte String with 1-byte annotation and field ID $10
244
+ // 3-byte String with 1-byte annotation
268
245
let value = EncodedValue {
269
246
header : Header {
270
247
ion_type : IonType :: String ,
271
248
ion_type_code : IonTypeCode :: String ,
272
249
length_code : 3 ,
273
250
} ,
274
- field_id_length : 1 ,
275
- field_id : Some ( 10 ) ,
276
251
annotations_header_length : 3 ,
277
252
annotations_sequence_length : 1 ,
278
253
header_offset : 200 ,
279
254
length_length : 0 ,
280
- value_length : 3 ,
255
+ value_body_length : 3 ,
281
256
total_length : 7 ,
282
257
} ;
283
258
assert_eq ! ( value. ion_type( ) , IonType :: String ) ;
@@ -292,18 +267,15 @@ mod tests {
292
267
assert_eq ! ( value. header_offset( ) , 200 ) ;
293
268
assert_eq ! ( value. header_length( ) , 1 ) ;
294
269
assert_eq ! ( value. header_range( ) , 200 ..201 ) ;
295
- assert_eq ! ( value. field_id_length( ) , Some ( 1 ) ) ;
296
- assert_eq ! ( value. field_id_offset( ) , Some ( 196 ) ) ;
297
- assert_eq ! ( value. field_id_range( ) , Some ( 196 ..197 ) ) ;
298
270
assert ! ( value. has_annotations( ) ) ;
299
271
assert_eq ! ( value. annotations_range( ) , Some ( 197 ..200 ) ) ;
300
272
assert_eq ! ( value. annotations_header_length( ) , Some ( 3 ) ) ;
301
273
assert_eq ! ( value. annotations_sequence_offset( ) , Some ( 199 ) ) ;
302
274
assert_eq ! ( value. annotations_sequence_length( ) , Some ( 1 ) ) ;
303
275
assert_eq ! ( value. annotations_sequence_range( ) , Some ( 199 ..200 ) ) ;
304
- assert_eq ! ( value. value_length ( ) , 3 ) ;
305
- assert_eq ! ( value. value_offset ( ) , 201 ) ;
306
- assert_eq ! ( value. value_range ( ) , 201 ..204 ) ;
276
+ assert_eq ! ( value. value_body_length ( ) , 3 ) ;
277
+ assert_eq ! ( value. value_body_offset ( ) , 201 ) ;
278
+ assert_eq ! ( value. value_body_range ( ) , 201 ..204 ) ;
307
279
assert_eq ! ( value. value_end_exclusive( ) , 204 ) ;
308
280
assert_eq ! ( value. total_length( ) , 7 ) ;
309
281
Ok ( ( ) )
0 commit comments