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()))
}
}
}
}
|