@@ -9,6 +9,104 @@ use crate::types::{self, AsnType, Constraints, Enumerated, SetOf, Tag};
9
9
pub use nom:: Needed ;
10
10
pub use rasn_derive:: Decode ;
11
11
12
+ /// A generic ASN.1 decoding iterator. JER and XER are not supported.
13
+ pub fn iter < D : Decode > ( input : & [ u8 ] , codec : crate :: codec:: Codec ) -> Iter < ' _ , D > {
14
+ Iter :: new ( input, codec)
15
+ }
16
+
17
+ /// Represents the input buffer in one of two states:
18
+ /// - `Borrowed(&[u8])` for the original input slice.
19
+ /// - `Owned { data: Vec<u8>, pos: usize }` after extra data has been appended.
20
+ /// Here `pos` tracks how many bytes have been consumed.
21
+ enum IterBuffer < ' a > {
22
+ Borrowed ( & ' a [ u8 ] ) ,
23
+ Owned { data : Vec < u8 > , pos : usize } ,
24
+ }
25
+
26
+ impl IterBuffer < ' _ > {
27
+ /// Returns the current unread portion of the data.
28
+ fn as_slice ( & self ) -> & [ u8 ] {
29
+ match self {
30
+ IterBuffer :: Borrowed ( slice) => slice,
31
+ IterBuffer :: Owned { data, pos } => & data[ * pos..] ,
32
+ }
33
+ }
34
+ /// Updates the buffer to account for the fact that `consumed` bytes were processed.
35
+ fn update_after_consumption ( & mut self , consumed : usize ) {
36
+ match self {
37
+ IterBuffer :: Borrowed ( slice) => * slice = & slice[ consumed..] ,
38
+ IterBuffer :: Owned { data, pos } => {
39
+ * pos += consumed;
40
+ // Drop the consumed bytes from the buffer once half of the data is already consumed.
41
+ if * pos > data. len ( ) / 2 {
42
+ data. drain ( 0 ..* pos) ;
43
+ * pos = 0 ;
44
+ }
45
+ }
46
+ }
47
+ }
48
+
49
+ /// Converts a Borrowed variant to an Owned one.
50
+ #[ allow( clippy:: wrong_self_convention) ]
51
+ fn to_owned ( & mut self ) {
52
+ if let IterBuffer :: Borrowed ( slice) = self {
53
+ let vec = slice. to_vec ( ) ;
54
+ * self = IterBuffer :: Owned { data : vec, pos : 0 } ;
55
+ }
56
+ }
57
+
58
+ /// Appends new bytes.
59
+ ///
60
+ /// Internal buffer is in the Owned state from this point forward.
61
+ fn extend ( & mut self , bytes : & [ u8 ] ) {
62
+ self . to_owned ( ) ;
63
+ if let IterBuffer :: Owned { data, .. } = self {
64
+ data. extend_from_slice ( bytes) ;
65
+ }
66
+ }
67
+ }
68
+
69
+ /// A generic ASN.1 decoding iterator.
70
+ pub struct Iter < ' input , D : Decode > {
71
+ buf : IterBuffer < ' input > ,
72
+ codec : crate :: codec:: Codec ,
73
+ _kind : core:: marker:: PhantomData < D > ,
74
+ }
75
+
76
+ impl < ' input , D : Decode > Iter < ' input , D > {
77
+ /// Create a new iterator from a borrowed input slice.
78
+ pub fn new ( input : & ' input [ u8 ] , codec : crate :: codec:: Codec ) -> Self {
79
+ Self {
80
+ buf : IterBuffer :: Borrowed ( input) ,
81
+ codec,
82
+ _kind : core:: marker:: PhantomData ,
83
+ }
84
+ }
85
+
86
+ /// Append new bytes to the input stream.
87
+ /// After this call the iterator will switch to using an owned buffer.
88
+ pub fn append_bytes ( & mut self , bytes : & ' input [ u8 ] ) {
89
+ self . buf . extend ( bytes) ;
90
+ }
91
+ }
92
+
93
+ impl < D : Decode > Iterator for Iter < ' _ , D > {
94
+ type Item = Result < D , DecodeError > ;
95
+
96
+ fn next ( & mut self ) -> Option < Self :: Item > {
97
+ let input = self . buf . as_slice ( ) ;
98
+ match self . codec . decode_from_binary_with_remainder ( input) {
99
+ Ok ( ( value, remainder) ) => {
100
+ // Determine how many bytes were consumed.
101
+ let consumed = input. len ( ) - remainder. len ( ) ;
102
+ self . buf . update_after_consumption ( consumed) ;
103
+ Some ( Ok ( value) )
104
+ }
105
+ Err ( err) => Some ( Err ( err) ) ,
106
+ }
107
+ }
108
+ }
109
+
12
110
/// A **data type** that can decoded from any ASN.1 format.
13
111
pub trait Decode : Sized + AsnType {
14
112
/// Decode this value from a given ASN.1 decoder.
0 commit comments