pem_iterator/
body.rs

1use core::iter::Map;
2
3use core::borrow::{Borrow, BorrowMut};
4use core::slice;
5 
6use core::iter::FromIterator;
7
8use {Void, map_chars, is_whitespace};
9
10#[derive(Debug, PartialEq)]
11pub enum BodyError<Loc, E> {
12    InvalidCharacter{
13        location: Loc,
14        found: char
15    },
16    MissingExpected(char),
17    SourceError(E),
18}
19
20impl<Location, E> From<E> for BodyError<Location, E> {
21    fn from(e: E) -> Self {
22        BodyError::SourceError(e)
23    }
24}
25
26
27
28
29#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
30pub enum Bytes {
31    One([u8; 1]),
32    Two([u8; 2]),
33    Three([u8; 3]),
34}
35
36pub struct ResultBytes<Loc, E>(pub Result<Bytes, BodyError<Loc, E>>);
37
38#[derive(Clone, Copy, Debug, PartialEq, Eq)]
39pub enum BytesIter {
40    Zero,
41    One([u8; 1]),
42    Two([u8; 2]),
43    Three([u8; 3]),
44}
45
46pub enum ResultBytesIter<Loc, E> {
47    Empty,
48    Err(BodyError<Loc, E>),
49    One([u8; 1]),
50    Two([u8; 2]),
51    Three([u8; 3]),
52}
53
54// A helper for collecting Bytes into Container<u8>
55pub struct BytesContainer<T>(pub T);
56
57#[cfg(feature = "std")]
58impl Extend<Bytes> for Vec<u8> {
59    #[inline]
60    fn extend<T: IntoIterator<Item = Bytes>>(&mut self, iter: T) {
61        for bytes in iter {
62            match bytes {
63                Bytes::One(a) => self.push(a[0]),
64                Bytes::Two(a) => self.extend_from_slice(&a[..]),
65                Bytes::Three(a) => self.extend_from_slice(&a[..]),
66            }
67        }
68    }
69}
70
71#[cfg(feature = "std")]
72impl FromIterator<Bytes> for Vec<u8> {
73    fn from_iter<T: IntoIterator<Item = Bytes>>(iter: T) -> Self {
74        let mut vec = Vec::new();
75        vec.extend(iter);
76        vec
77    }
78}
79
80impl<C> BytesContainer<C> {
81    pub fn into(self) -> C {
82        self.0
83    }
84}
85
86impl<C> Extend<Bytes> for BytesContainer<C>
87where C: Extend<u8> {
88    #[inline]
89    fn extend<T: IntoIterator<Item = Bytes>>(&mut self, iter: T) {
90        use core::iter::once;
91        for bytes in iter {
92            match bytes {
93                Bytes::One(a) => self.0.extend(once(a[0])),
94                Bytes::Two(a) => self.0.extend(once(a[0]).chain(once(a[1]))),
95                Bytes::Three(a) => self.0.extend(once(a[0]).chain(once(a[1])).chain(once(a[2]))),
96            }
97        }
98    }
99}
100
101impl<C> FromIterator<Bytes> for BytesContainer<C>
102where C: Default+Extend<u8> {
103    fn from_iter<T: IntoIterator<Item = Bytes>>(iter: T) -> Self {
104        let mut c = BytesContainer(C::default());
105        c.extend(iter);
106        c
107    }
108}
109
110impl AsRef<[u8]> for Bytes {
111    fn as_ref(&self) -> &[u8] {
112        match self {
113            &Bytes::One(ref a) => a,
114            &Bytes::Two(ref a) => a,
115            &Bytes::Three(ref a) => a,
116        }
117    }
118}
119impl AsMut<[u8]> for Bytes {
120    fn as_mut(&mut self) -> &mut [u8] {
121        match self {
122            &mut Bytes::One(ref mut a) => a,
123            &mut Bytes::Two(ref mut a) => a,
124            &mut Bytes::Three(ref mut a) => a,
125        }
126    }
127}
128
129impl Borrow<[u8]> for Bytes {
130    fn borrow(&self) -> &[u8] {
131        match self {
132            &Bytes::One(ref a) => a,
133            &Bytes::Two(ref a) => a,
134            &Bytes::Three(ref a) => a,
135        }
136    }
137}
138
139impl BorrowMut<[u8]> for Bytes {
140    fn borrow_mut(&mut self) -> &mut [u8] {
141        match self {
142            &mut Bytes::One(ref mut a) => a,
143            &mut Bytes::Two(ref mut a) => a,
144            &mut Bytes::Three(ref mut a) => a,
145        }
146    }
147}
148
149impl IntoIterator for Bytes {
150    type Item = u8;
151    type IntoIter = BytesIter;
152    fn into_iter(self) -> Self::IntoIter {
153        match self {
154            Bytes::One(a) => BytesIter::One(a),
155            Bytes::Two(a) => BytesIter::Two(a),
156            Bytes::Three(a) => BytesIter::Three(a),
157        }
158    }
159}
160
161impl<'a> IntoIterator for &'a Bytes {
162    type Item = &'a u8;
163    type IntoIter = slice::Iter<'a, u8>;
164    fn into_iter(self) -> Self::IntoIter {
165        self.as_ref().into_iter()
166    }
167}
168
169impl<'a> IntoIterator for &'a mut Bytes {
170    type Item = &'a mut u8;
171    type IntoIter = slice::IterMut<'a, u8>;
172    fn into_iter(self) -> Self::IntoIter {
173        self.as_mut().into_iter()
174    }
175}
176
177impl<Loc, E> IntoIterator for ResultBytes<Loc, E> {
178    type Item = Result<u8, BodyError<Loc, E>>;
179    type IntoIter = ResultBytesIter<Loc, E>;
180    fn into_iter(self) -> Self::IntoIter {
181        match self.0 {
182            Err(e) => ResultBytesIter::Err(e),
183            Ok(Bytes::One(a)) => ResultBytesIter::One(a),
184            Ok(Bytes::Two(a)) => ResultBytesIter::Two(a),
185            Ok(Bytes::Three(a)) => ResultBytesIter::Three(a),
186        }
187    }
188}
189
190
191impl Iterator for BytesIter {
192    type Item = u8;
193    fn next(&mut self) -> Option<Self::Item> {
194        match *self {
195            BytesIter::Zero => None,
196            BytesIter::One(a) => {
197                *self = BytesIter::Zero;
198                Some(a[0])
199            }
200            BytesIter::Two(a) => {
201                *self = BytesIter::One([a[1]]);
202                Some(a[0])
203            }
204            BytesIter::Three(a) => {
205                *self = BytesIter::Two([a[1], a[2]]);
206                Some(a[0])
207            }
208        }
209    }
210
211    fn size_hint(&self) -> (usize, Option<usize>) {
212        match self {
213            &BytesIter::Zero => (0, Some(0)),
214            &BytesIter::One(..) => (1, Some(1)),
215            &BytesIter::Two(..) => (2, Some(2)),
216            &BytesIter::Three(..) => (3, Some(3)),
217        }
218    }
219}
220
221impl ExactSizeIterator for BytesIter {}
222
223
224impl<Loc, E> Iterator for ResultBytesIter<Loc, E> {
225    type Item = Result<u8, BodyError<Loc, E>>;
226    fn next(&mut self) -> Option<Self::Item> {
227        use core::mem::replace;
228        match replace(self, ResultBytesIter::Empty) {
229            ResultBytesIter::Empty => None,
230            ResultBytesIter::Err(e) => Some(Err(e)),
231            ResultBytesIter::One(a) => Some(Ok(a[0])),
232            ResultBytesIter::Two(a) => {
233                *self = ResultBytesIter::One([a[1]]);
234                Some(Ok(a[0]))
235            }
236            ResultBytesIter::Three(a) => {
237                *self = ResultBytesIter::Two([a[1], a[2]]);
238                Some(Ok(a[0]))
239            }
240        }
241    }
242
243    fn size_hint(&self) -> (usize, Option<usize>) {
244        match self {
245            &ResultBytesIter::Empty => (0, Some(0)),
246            &ResultBytesIter::Err(..) => (1, Some(1)),
247            &ResultBytesIter::One(..) => (1, Some(1)),
248            &ResultBytesIter::Two(..) => (2, Some(2)),
249            &ResultBytesIter::Three(..) => (3, Some(3)),
250        }
251    }
252}
253
254impl<Loc, E> ExactSizeIterator for ResultBytesIter<Loc, E> {}
255
256
257
258pub(crate) fn get_6_bits<Location, E>(
259    stream: &mut Iterator<Item = Result<(Location, char), E>>,
260) -> Result<Option<u8>, BodyError<Location, E>> {
261    use self::BodyError::*;
262
263    // Ignore '=' and whitespace
264    fn ignore<Location>(c: &(Location, char)) -> bool {
265        c.1 != '=' && !is_whitespace(c)
266    }
267    let mut stream = stream.filter(|c| c.as_ref().map(ignore).unwrap_or(true));
268
269    // If the stream ends without a footer, complain
270    let (location, c) = stream.next().ok_or(MissingExpected('-'))??;
271
272    let (offset, base) = match c {
273        '-' => return Ok(None),
274        'A'...'Z' => (0, 'A'),
275        'a'...'z' => (26, 'a'),
276        '0'...'9' => (52, '0'),
277        '+' => (62, '+'),
278        '/' => (63, '/'),
279        found => return Err(InvalidCharacter{found, location}),
280    };
281
282    Ok(Some((offset + c as u32 - base as u32) as u8))
283}
284
285
286pub struct Chunked<S> {
287    stream: S,
288    state: Option<ChunkedState>,
289}
290
291enum ChunkedState {
292    Zero,
293    NonZero(ChunkedState2),
294}
295enum ChunkedState2 {
296    One(u8),
297    NonOne(ChunkedState3),
298}
299enum ChunkedState3 {
300    Two(u8, u8),
301    Three(u8, u8, u8),
302}
303
304impl<Loc, E, S> Chunked<S>
305where S: Iterator<Item = Result<(Loc, char), E>>
306{
307    pub fn new(stream: S) -> Self {
308        Chunked{
309            stream, state: Some(ChunkedState::Zero)
310        }
311    }
312}
313
314impl<Loc, S> Chunked<Map<S, fn((Loc, char)) -> Result<(Loc, char), Void>>>
315where S: Iterator<Item = (Loc, char)>
316    {
317    pub fn from_chars(stream: S) -> Self {
318        Self::new(stream.map(map_chars))
319    }
320}
321
322impl<'a, Loc, E, S> Iterator for Chunked<S>
323where Loc: 'a,
324    E: 'a,
325    S: 'a + Iterator<Item = Result<(Loc, char), E>>
326{
327    type Item = Result<Bytes, BodyError<Loc, E>>;
328
329    /// May panic if called after it returns `None`
330    fn next(&mut self) -> Option<Result<Bytes, BodyError<Loc, E>>> {
331        self.state.take().and_then(|state| {
332            let (state, result) = state.process(&mut self.stream);
333            self.state = state;
334            result
335        })
336    }
337}
338
339fn one(a: u8) -> ChunkedState {
340    use self::ChunkedState::*;
341    use self::ChunkedState2::*;
342    NonZero(One(a))
343}
344fn two(a: u8, b: u8) -> ChunkedState {
345    use self::ChunkedState::*;
346    use self::ChunkedState2::*;
347    use self::ChunkedState3::*;
348    NonZero(NonOne(Two(a, b)))
349}
350fn three(a: u8, b: u8, c: u8) -> ChunkedState {
351    use self::ChunkedState::*;
352    use self::ChunkedState2::*;
353    use self::ChunkedState3::*;
354    NonZero(NonOne(Three(a, b, c)))
355}
356
357impl ChunkedState {
358    fn process<'a, Loc: 'a, E: 'a>(self, stream: &'a mut Iterator<Item = Result<(Loc, char), E>>) -> (Option<Self>, Option<Result<Bytes, BodyError<Loc, E>>>) {
359        use self::ChunkedState::*;
360        use self::ChunkedState2::*;
361        
362        let v = match self {
363            Zero => match get_6_bits(stream) {
364                Err(e) => return (Some(Zero), Some(Err(e))),
365                Ok(None) => return (None, None),
366                Ok(Some(v)) => One(v << 2),
367            },
368            NonZero(v) => v,
369        };
370
371        v.process(stream)
372    }
373}
374
375impl ChunkedState2 {
376    fn process<'a, Loc: 'a, E: 'a>(self, stream: &'a mut Iterator<Item = Result<(Loc, char), E>>) -> (Option<ChunkedState>, Option<Result<Bytes, BodyError<Loc, E>>>) {
377        use self::ChunkedState2::*;
378        use self::ChunkedState3::*;
379        
380        let v = match self {
381            One(a) => match get_6_bits(stream) {
382                Err(e) => return (Some(one(a)), Some(Err(e))),
383                Ok(None) => return (None, Some(Ok(Bytes::One([a])))),
384                Ok(Some(v)) => Two(a | (v >> 4), (v & 0b1111) << 4),
385            },
386            NonOne(v) => v,
387        };
388
389        v.process(stream)
390    }
391}
392
393impl ChunkedState3 {
394    fn process<'a, Loc: 'a, E: 'a>(self, stream: &'a mut Iterator<Item = Result<(Loc, char), E>>) -> (Option<ChunkedState>, Option<Result<Bytes, BodyError<Loc, E>>>) {
395        use self::ChunkedState::*;
396        use self::ChunkedState3::*;
397        
398        let (a, b, c) = match self {
399            Two(a, b) => match get_6_bits(stream) {
400                Err(e) => return (Some(two(a, b)), Some(Err(e))),
401                Ok(None) => return (None, Some(Ok(Bytes::Two([a, b])))),
402                Ok(Some(v)) => (a, b | (v >> 2), (v & 0b11) << 6),
403            },
404            Three(a, b, c) => (a, b, c),
405        };
406
407        match get_6_bits(stream) {
408            Err(e) => (Some(three(a, b, c)), Some(Err(e))),
409            Ok(None) => (None, Some(Ok(Bytes::Three([a, b, c])))),
410            Ok(Some(v)) => (Some(Zero), Some(Ok(Bytes::Three([a, b, c | v])))),
411        }
412    }
413}
414
415pub struct Single<S> {
416    stream: S,
417    state: Option<SingleState>,
418}
419
420enum SingleState {
421    ZeroBits,
422    NonZeroBits(SingleState2),
423}
424
425enum SingleState2 {
426    SixBits(u8),
427    FourBits(u8),
428    TwoBits(u8),
429}
430
431impl<Loc, E, S> Single<S>
432where S: Iterator<Item = Result<(Loc, char), E>>
433{
434    pub fn new(stream: S) -> Self {
435        Single{
436            stream, state: Some(SingleState::ZeroBits)
437        }
438    }
439}
440
441impl<Loc, S> Single<Map<S, fn((Loc, char)) -> Result<(Loc, char), Void>>>
442where S: Iterator<Item = (Loc, char)>
443    {
444    pub fn from_chars(stream: S) -> Self {
445        Self::new(stream.map(map_chars))
446    }
447}
448
449impl<'a, Loc, E, S> Iterator for Single<S>
450where Loc: 'a,
451    E: 'a,
452    S: 'a + Iterator<Item = Result<(Loc, char), E>>
453{
454    type Item = Result<u8, BodyError<Loc, E>>;
455
456    /// May panic if called after it returns `None`
457    fn next(&mut self) -> Option<Result<u8, BodyError<Loc, E>>> {
458        self.state.take().and_then(|state| {
459            let (state, result) = state.process(&mut self.stream);
460            self.state = state;
461            result
462        })
463    }
464}
465
466impl SingleState {
467    fn process<'a, Loc: 'a, E: 'a>(self, stream: &'a mut Iterator<Item = Result<(Loc, char), E>>) -> (Option<SingleState>, Option<Result<u8, BodyError<Loc, E>>>) {
468        use self::SingleState::*;
469        use self::SingleState2::*;
470        
471        let v = if let NonZeroBits(v) = self {
472            v
473        } else {
474            match get_6_bits(stream) {
475                Err(e) => return (Some(ZeroBits), Some(Err(e))),
476                Ok(None) => return (None, None),
477                Ok(Some(v)) => SixBits(v << 2),
478            }
479        };
480
481        let new = match get_6_bits(stream) {
482            Err(e) => return (Some(NonZeroBits(v)), Some(Err(e))),
483            Ok(None) => return (None, None),
484            Ok(Some(v)) => v,
485        };
486
487        match v {
488            SixBits(old) => (Some(NonZeroBits(FourBits((new & 0b1111) << 4))), Some(Ok(old | (new >> 4)))),
489            FourBits(old) => (Some(NonZeroBits(TwoBits((new & 0b11) << 6))), Some(Ok(old | (new >> 2)))),
490            TwoBits(old) => (Some(ZeroBits), Some(Ok(old | new))),
491        }
492    }
493}