1use super::*;
2
3pub struct Decoder {
5 header_found: bool,
6 esc_seq: [u8; 4],
7 esc_seq_len: usize,
8}
9
10impl Decoder {
11 pub fn new() -> Self {
13 Decoder {
14 header_found: false,
15 esc_seq: [0; 4],
16 esc_seq_len: 0,
17 }
18 }
19
20 pub fn decode<'a>(&mut self, input: &'a [u8], output: &'a mut [u8])
25 -> Result<(usize, &'a [u8], bool)>
26 {
27 let input_len = input.len();
28 let mut stream = input;
29 if !self.header_found {
30 stream = self.decode_header(stream)?;
31 }
32 let res = self.decode_stream(stream, output)?;
33
34 Ok((input_len - res.0.len(), res.1, res.2))
35 }
36
37 fn decode_header<'a>(&mut self, input: &'a [u8]) -> Result<&'a [u8]> {
39 if input.len() < 1 {
40 return Err(Error::BadHeaderDecode);
42 }
43
44 if input[0] != END {
45 return Err(Error::BadHeaderDecode);
46 }
47 self.header_found = true;
48
49 Ok(&input[1..])
50 }
51
52 fn decode_stream<'a>(&mut self, input: &'a [u8], output: &'a mut [u8])
54 -> Result<(&'a [u8], &'a [u8], bool)>
55 {
56 let mut in_byte = 0;
57 let mut out_byte = 0;
58 let mut end = false;
59
60 loop {
61 if in_byte == input.len() || out_byte == output.len() {
62 break;
63 }
64
65 if self.esc_seq_len > 0 {
66 match input[in_byte] {
67 ESC_END => {
68 output[out_byte] = END
69 }
70 ESC_ESC => {
71 output[out_byte] = ESC
72 }
73 _ => return Err(Error::BadEscapeSequenceDecode),
74 }
75 out_byte += 1;
76 self.esc_sequence_empty();
77 } else {
78 match input[in_byte] {
79 ESC => {
80 self.esc_sequence_push(ESC);
81 }
82 END => {
83 in_byte += 1;
84 end = true;
85 break;
86 }
87 _ => {
88 output[out_byte] = input[in_byte];
89 out_byte += 1;
90 }
91 }
92 }
93 in_byte += 1;
94 }
95
96 Ok((&input[in_byte..], &output[..out_byte], end))
97 }
98
99 fn esc_sequence_push(&mut self, byte: u8) {
101 self.esc_seq[self.esc_seq_len] = byte;
102 self.esc_seq_len += 1;
103 }
104
105 fn esc_sequence_empty(&mut self) {
107 self.esc_seq_len = 0;
108 }
109}
110
111#[cfg(test)]
112mod tests {
113 use super::*;
114
115 #[test]
116 fn empty_decode() {
117 const INPUT: [u8; 2] = [0xc0, 0xc0];
118 let mut output: [u8; 32] = [0; 32];
119
120 let mut slip = Decoder::new();
121 let res = slip.decode(&INPUT, &mut output).unwrap();
122 assert_eq!(INPUT.len(), res.0);
123 assert_eq!(&[0;0], res.1);
124 assert_eq!(true, res.2);
125 }
126
127 #[test]
128 fn simple_decode() {
129 const INPUT: [u8; 7] = [0xc0, 0x01, 0x02, 0x03, 0x04, 0x05, 0xc0];
130 const DATA: [u8; 5] = [0x01, 0x02, 0x03, 0x04, 0x05];
131 let mut output: [u8; 32] = [0; 32];
132
133 let mut slip = Decoder::new();
134 let res = slip.decode(&INPUT, &mut output).unwrap();
135 assert_eq!(INPUT.len(), res.0);
136 assert_eq!(&DATA, res.1);
137 assert_eq!(true, res.2);
138 }
139
140 #[test]
142 fn decode_esc_then_esc_end_sequence() {
143 const INPUT: [u8; 6] = [0xc0, 0x01, 0xdb, 0xdc, 0x03, 0xc0];
144 const DATA: [u8; 3] = [0x01, 0xc0, 0x03];
145 let mut output: [u8; 200] = [0; 200];
146
147 let mut slip = Decoder::new();
148 let res = slip.decode(&INPUT, &mut output).unwrap();
149 assert_eq!(INPUT.len(), res.0);
150 assert_eq!(&DATA, res.1);
151 assert_eq!(true, res.2);
152 }
153
154 #[test]
156 fn decode_esc_then_esc_esc_sequence() {
157 const INPUT: [u8; 6] = [0xc0, 0x01, 0xdb, 0xdd, 0x03, 0xc0];
158 const DATA: [u8; 3] = [0x01, 0xdb, 0x03];
159 let mut output: [u8; 200] = [0; 200];
160
161 let mut slip = Decoder::new();
162 let res = slip.decode(&INPUT, &mut output).unwrap();
163 assert_eq!(INPUT.len(), res.0);
164 assert_eq!(&DATA, res.1);
165 assert_eq!(true, res.2);
166 }
167
168 #[test]
169 fn multi_part_decode() {
170 const INPUT_1: [u8; 6] = [0xc0, 0x01, 0x02, 0x03, 0x04, 0x05];
171 const INPUT_2: [u8; 6] = [0x05, 0x06, 0x07, 0x08, 0x09, 0xc0];
172 const DATA_1: [u8; 5] = [0x01, 0x02, 0x03, 0x04, 0x05];
173 const DATA_2: [u8; 5] = [0x05, 0x06, 0x07, 0x08, 0x09];
174 let mut output: [u8; 200] = [0; 200];
175
176 let mut slip = Decoder::new();
177 let mut offset = 0;
178 {
179 let res = slip.decode(&INPUT_1, &mut output[offset..]).unwrap();
180 assert_eq!(INPUT_1.len(), res.0);
181 assert_eq!(&DATA_1, res.1);
182 assert_eq!(false, res.2);
183 offset += res.1.len();
184 }
185 {
186 let res = slip.decode(&INPUT_2, &mut output[offset..]).unwrap();
187 assert_eq!(INPUT_2.len(), res.0);
188 assert_eq!(&DATA_2, res.1);
189 assert_eq!(true, res.2);
190 offset += res.1.len();
191 }
192 assert_eq!(10, offset);
193 }
194}