@@ -164,19 +164,75 @@ impl Tag {
164
164
/// rules implemented by this crate.
165
165
pub ( crate ) const MAX_SIZE : usize = 6 ;
166
166
167
+ /// Decode a [`Tag`] in addition to returning the value of the constructed bit.
168
+ pub ( crate ) fn decode_with_constructed_bit < ' a > (
169
+ reader : & mut impl Reader < ' a > ,
170
+ ) -> Result < ( Self , bool ) > {
171
+ let first_byte = reader. read_byte ( ) ?;
172
+ let is_constructed = first_byte & CONSTRUCTED_FLAG != 0 ;
173
+
174
+ let tag = match first_byte {
175
+ 0x01 => Tag :: Boolean ,
176
+ 0x02 => Tag :: Integer ,
177
+ 0x03 => Tag :: BitString ,
178
+ 0x04 => Tag :: OctetString ,
179
+ 0x05 => Tag :: Null ,
180
+ 0x06 => Tag :: ObjectIdentifier ,
181
+ 0x09 => Tag :: Real ,
182
+ 0x0A => Tag :: Enumerated ,
183
+ 0x0C => Tag :: Utf8String ,
184
+ 0x12 => Tag :: NumericString ,
185
+ 0x13 => Tag :: PrintableString ,
186
+ 0x14 => Tag :: TeletexString ,
187
+ 0x15 => Tag :: VideotexString ,
188
+ 0x16 => Tag :: Ia5String ,
189
+ 0x17 => Tag :: UtcTime ,
190
+ 0x18 => Tag :: GeneralizedTime ,
191
+ 0x1A => Tag :: VisibleString ,
192
+ 0x1B => Tag :: GeneralString ,
193
+ 0x1E => Tag :: BmpString ,
194
+ 0x24 if reader. encoding_rules ( ) == EncodingRules :: Ber => Tag :: OctetString ,
195
+ 0x30 => Tag :: Sequence , // constructed
196
+ 0x31 => Tag :: Set , // constructed
197
+ 0x40 ..=0x7F => {
198
+ let ( constructed, number) = parse_parts ( first_byte, reader) ?;
199
+
200
+ Tag :: Application {
201
+ constructed,
202
+ number,
203
+ }
204
+ }
205
+ 0x80 ..=0xBF => {
206
+ let ( constructed, number) = parse_parts ( first_byte, reader) ?;
207
+
208
+ Tag :: ContextSpecific {
209
+ constructed,
210
+ number,
211
+ }
212
+ }
213
+ 0xC0 ..=0xFF => {
214
+ let ( constructed, number) = parse_parts ( first_byte, reader) ?;
215
+
216
+ Tag :: Private {
217
+ constructed,
218
+ number,
219
+ }
220
+ }
221
+ // universal tag in long form
222
+ 0x1F => return Err ( reader. error ( ErrorKind :: TagNumberInvalid ) ) ,
223
+ byte => return Err ( reader. error ( ErrorKind :: TagUnknown { byte } ) ) ,
224
+ } ;
225
+
226
+ Ok ( ( tag, is_constructed) )
227
+ }
228
+
167
229
/// Peek at the next byte in the reader and attempt to decode it as a [`Tag`] value.
168
230
///
169
231
/// Does not modify the reader's state.
170
232
pub fn peek < ' a > ( reader : & impl Reader < ' a > ) -> Result < Self > {
171
233
Self :: decode ( & mut reader. clone ( ) )
172
234
}
173
235
174
- /// Peek at whether the next byte in the reader has the constructed bit set.
175
- pub ( crate ) fn peek_is_constructed < ' a > ( reader : & impl Reader < ' a > ) -> Result < bool > {
176
- let octet = reader. clone ( ) . read_byte ( ) ?;
177
- Ok ( octet & CONSTRUCTED_FLAG != 0 )
178
- }
179
-
180
236
/// Returns true if given context-specific (or any given class) tag number matches the peeked tag.
181
237
pub ( crate ) fn peek_matches < ' a , R : Reader < ' a > > (
182
238
reader : & mut R ,
@@ -304,61 +360,7 @@ impl<'a> Decode<'a> for Tag {
304
360
type Error = Error ;
305
361
306
362
fn decode < R : Reader < ' a > > ( reader : & mut R ) -> Result < Self > {
307
- let first_byte = reader. read_byte ( ) ?;
308
-
309
- let tag = match first_byte {
310
- 0x01 => Tag :: Boolean ,
311
- 0x02 => Tag :: Integer ,
312
- 0x03 => Tag :: BitString ,
313
- 0x04 => Tag :: OctetString ,
314
- 0x05 => Tag :: Null ,
315
- 0x06 => Tag :: ObjectIdentifier ,
316
- 0x09 => Tag :: Real ,
317
- 0x0A => Tag :: Enumerated ,
318
- 0x0C => Tag :: Utf8String ,
319
- 0x12 => Tag :: NumericString ,
320
- 0x13 => Tag :: PrintableString ,
321
- 0x14 => Tag :: TeletexString ,
322
- 0x15 => Tag :: VideotexString ,
323
- 0x16 => Tag :: Ia5String ,
324
- 0x17 => Tag :: UtcTime ,
325
- 0x18 => Tag :: GeneralizedTime ,
326
- 0x1A => Tag :: VisibleString ,
327
- 0x1B => Tag :: GeneralString ,
328
- 0x1E => Tag :: BmpString ,
329
- 0x24 if reader. encoding_rules ( ) == EncodingRules :: Ber => Tag :: OctetString ,
330
- 0x30 => Tag :: Sequence , // constructed
331
- 0x31 => Tag :: Set , // constructed
332
- 0x40 ..=0x7F => {
333
- let ( constructed, number) = parse_parts ( first_byte, reader) ?;
334
-
335
- Tag :: Application {
336
- constructed,
337
- number,
338
- }
339
- }
340
- 0x80 ..=0xBF => {
341
- let ( constructed, number) = parse_parts ( first_byte, reader) ?;
342
-
343
- Tag :: ContextSpecific {
344
- constructed,
345
- number,
346
- }
347
- }
348
- 0xC0 ..=0xFF => {
349
- let ( constructed, number) = parse_parts ( first_byte, reader) ?;
350
-
351
- Tag :: Private {
352
- constructed,
353
- number,
354
- }
355
- }
356
- // universal tag in long form
357
- 0x1F => return Err ( reader. error ( ErrorKind :: TagNumberInvalid ) ) ,
358
- byte => return Err ( reader. error ( ErrorKind :: TagUnknown { byte } ) ) ,
359
- } ;
360
-
361
- Ok ( tag)
363
+ Self :: decode_with_constructed_bit ( reader) . map ( |( tag, _) | tag)
362
364
}
363
365
}
364
366
0 commit comments