@@ -164,19 +164,75 @@ impl Tag {
164164 /// rules implemented by this crate.
165165 pub ( crate ) const MAX_SIZE : usize = 6 ;
166166
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+
167229 /// Peek at the next byte in the reader and attempt to decode it as a [`Tag`] value.
168230 ///
169231 /// Does not modify the reader's state.
170232 pub fn peek < ' a > ( reader : & impl Reader < ' a > ) -> Result < Self > {
171233 Self :: decode ( & mut reader. clone ( ) )
172234 }
173235
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-
180236 /// Returns true if given context-specific (or any given class) tag number matches the peeked tag.
181237 pub ( crate ) fn peek_matches < ' a , R : Reader < ' a > > (
182238 reader : & mut R ,
@@ -304,61 +360,7 @@ impl<'a> Decode<'a> for Tag {
304360 type Error = Error ;
305361
306362 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)
362364 }
363365}
364366
0 commit comments