1 use crate::ber::*;
2 use crate::error::*;
3 use nom::bytes::complete::take;
4 use nom::{Err, IResult};
5
6 /// Read a TAGGED EXPLICIT value (function version)
7 ///
8 /// The following parses `[2] EXPLICIT INTEGER`:
9 ///
10 /// ```rust
11 /// # use der_parser::ber::*;
12 /// # use der_parser::error::BerResult;
13 /// use nom::combinator::map_res;
14 /// #
15 /// fn parse_int_explicit(i:&[u8]) -> BerResult<u32> {
16 /// parse_ber_tagged_explicit(
17 /// 2,
18 /// parse_ber_u32
19 /// )(i)
20 /// }
21 ///
22 /// # let bytes = &[0xa2, 0x05, 0x02, 0x03, 0x01, 0x00, 0x01];
23 /// let res = parse_int_explicit(bytes);
24 /// # match res {
25 /// # Ok((rem,val)) => {
26 /// # assert!(rem.is_empty());
27 /// # assert_eq!(val, 0x10001);
28 /// # },
29 /// # _ => assert!(false)
30 /// # }
31 /// ```
parse_ber_tagged_explicit<'a, T, F, E>( tag: u32, f: F, ) -> impl Fn(&'a [u8]) -> IResult<&'a [u8], T, E> where F: Fn(&'a [u8]) -> IResult<&'a [u8], T, E>, E: nom::error::ParseError<&'a [u8]> + From<BerError>,32 pub fn parse_ber_tagged_explicit<'a, T, F, E>(
33 tag: u32,
34 f: F,
35 ) -> impl Fn(&'a [u8]) -> IResult<&'a [u8], T, E>
36 where
37 F: Fn(&'a [u8]) -> IResult<&'a [u8], T, E>,
38 E: nom::error::ParseError<&'a [u8]> + From<BerError>,
39 {
40 move |i: &[u8]| {
41 let (i, hdr) = ber_read_element_header(i).map_err(nom::Err::convert)?;
42 if hdr.tag.0 != tag {
43 return Err(Err::Error(BerError::InvalidTag.into()));
44 }
45 let (i, data) = take(hdr.len as usize)(i)?;
46 let (_rest, item) = f(data)?;
47 Ok((i, item))
48 }
49 }
50
51 /// Read a TAGGED IMPLICIT value (function version)
52 ///
53 /// The following parses `[2] IMPLICIT INTEGER`:
54 ///
55 /// ```rust
56 /// # use der_parser::ber::*;
57 /// # use der_parser::error::BerResult;
58 /// use nom::combinator::map_res;
59 /// #
60 /// fn parse_int_implicit(i:&[u8]) -> BerResult<u32> {
61 /// map_res(
62 /// parse_ber_tagged_implicit(
63 /// 2,
64 /// parse_ber_content(BerTag::Integer),
65 /// ),
66 /// |x: BerObjectContent| x.as_u32()
67 /// )(i)
68 /// }
69 ///
70 /// # let bytes = &[0x82, 0x03, 0x01, 0x00, 0x01];
71 /// let res = parse_int_implicit(bytes);
72 /// # match res {
73 /// # Ok((rem,val)) => {
74 /// # assert!(rem.is_empty());
75 /// # assert_eq!(val, 0x10001);
76 /// # },
77 /// # _ => assert!(false)
78 /// # }
79 /// ```
parse_ber_tagged_implicit<'a, T, F, E>( tag: u32, f: F, ) -> impl Fn(&'a [u8]) -> IResult<&[u8], T, E> where F: Fn(&'a [u8], &'_ BerObjectHeader, usize) -> IResult<&'a [u8], T, E>, E: nom::error::ParseError<&'a [u8]> + From<BerError>,80 pub fn parse_ber_tagged_implicit<'a, T, F, E>(
81 tag: u32,
82 f: F,
83 ) -> impl Fn(&'a [u8]) -> IResult<&[u8], T, E>
84 where
85 F: Fn(&'a [u8], &'_ BerObjectHeader, usize) -> IResult<&'a [u8], T, E>,
86 E: nom::error::ParseError<&'a [u8]> + From<BerError>,
87 {
88 move |i: &[u8]| {
89 let (i, hdr) = ber_read_element_header(i).map_err(nom::Err::convert)?;
90 if hdr.tag.0 != tag {
91 return Err(Err::Error(BerError::InvalidTag.into()));
92 }
93 let (i, data) = take(hdr.len as usize)(i)?;
94 let (_rest, item) = f(data, &hdr, MAX_RECURSION)?;
95 // XXX DER: check that _rest.is_empty()?
96 Ok((i, item))
97 }
98 }
99