1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106
use crate::{ASN1Parser, BerParser, DerParser, Error, FromBer, FromDer};
use core::marker::PhantomData;
/// An Iterator over binary data, parsing elements of type `T`
///
/// This helps parsing `SEQUENCE OF` items of type `T`. The type of parser
/// (BER/DER) is specified using the generic parameter `F` of this struct.
///
/// Note: the iterator must start on the sequence *contents*, not the sequence itself.
///
/// # Examples
///
/// ```rust
/// use asn1_rs::{DerParser, Integer, SequenceIterator};
///
/// let data = &[0x30, 0x6, 0x2, 0x1, 0x1, 0x2, 0x1, 0x2];
/// for (idx, item) in SequenceIterator::<Integer, DerParser>::new(&data[2..]).enumerate() {
/// let item = item.unwrap(); // parsing could have failed
/// let i = item.as_u32().unwrap(); // integer can be negative, or too large to fit into u32
/// assert_eq!(i as usize, idx + 1);
/// }
/// ```
#[derive(Debug)]
pub struct SequenceIterator<'a, T, F, E = Error>
where
F: ASN1Parser,
{
data: &'a [u8],
has_error: bool,
_t: PhantomData<T>,
_f: PhantomData<F>,
_e: PhantomData<E>,
}
impl<'a, T, F, E> SequenceIterator<'a, T, F, E>
where
F: ASN1Parser,
{
pub fn new(data: &'a [u8]) -> Self {
SequenceIterator {
data,
has_error: false,
_t: PhantomData,
_f: PhantomData,
_e: PhantomData,
}
}
}
impl<'a, T, E> Iterator for SequenceIterator<'a, T, BerParser, E>
where
T: FromBer<'a, E>,
E: From<Error>,
{
type Item = Result<T, E>;
fn next(&mut self) -> Option<Self::Item> {
if self.has_error || self.data.is_empty() {
return None;
}
match T::from_ber(self.data) {
Ok((rem, obj)) => {
self.data = rem;
Some(Ok(obj))
}
Err(nom::Err::Error(e)) | Err(nom::Err::Failure(e)) => {
self.has_error = true;
Some(Err(e))
}
Err(nom::Err::Incomplete(n)) => {
self.has_error = true;
Some(Err(Error::Incomplete(n).into()))
}
}
}
}
impl<'a, T, E> Iterator for SequenceIterator<'a, T, DerParser, E>
where
T: FromDer<'a, E>,
E: From<Error>,
{
type Item = Result<T, E>;
fn next(&mut self) -> Option<Self::Item> {
if self.has_error || self.data.is_empty() {
return None;
}
match T::from_der(self.data) {
Ok((rem, obj)) => {
self.data = rem;
Some(Ok(obj))
}
Err(nom::Err::Error(e)) | Err(nom::Err::Failure(e)) => {
self.has_error = true;
Some(Err(e))
}
Err(nom::Err::Incomplete(n)) => {
self.has_error = true;
Some(Err(Error::Incomplete(n).into()))
}
}
}
}