serial_line_ip/
encoder.rs1use super::*;
2
3#[derive(Clone)]
5pub struct Encoder {
6 header_written: bool,
8}
9
10pub struct EncodeTotals {
13 pub read: usize,
15 pub written: usize,
17}
18
19impl Encoder {
20 pub fn new() -> Self {
22 Encoder {
23 header_written: false,
24 }
25 }
26
27 pub fn encode(&mut self, input: &[u8], output: &mut [u8]) -> Result<EncodeTotals> {
30 let mut out_byte = 0;
31 if !self.header_written {
32 if output.len() < 1 {
33 return Err(Error::NoOutputSpaceForHeader);
34 }
35
36 output[out_byte] = END;
37 out_byte = 1;
38 self.header_written = true;
39 }
40
41 let mut in_byte = 0;
42 while in_byte < input.len() {
43 match input[in_byte] {
44 ESC => {
45 if (output.len() - out_byte) < 2 {
46 break;
47 }
48 output[out_byte] = ESC;
49 output[out_byte + 1] = ESC_ESC;
50 out_byte += 2;
51 }
52 END => {
53 if (output.len() - out_byte) < 2 {
54 break;
55 }
56 output[out_byte] = ESC;
57 output[out_byte + 1] = ESC_END;
58 out_byte += 2;
59 }
60 _ => {
61 if (output.len() - out_byte) < 1 {
62 break;
63 }
64 output[out_byte] = input[in_byte];
65 out_byte += 1;
66 }
67 }
68 in_byte += 1;
69 }
70
71 Ok(EncodeTotals {
72 read: in_byte,
73 written: out_byte,
74 })
75 }
76
77 pub fn finish(self, output: &mut [u8]) -> Result<EncodeTotals> {
79 if output.len() < 1 {
80 return Err(Error::NoOutputSpaceForEndByte);
81 }
82 output[0] = END;
83
84 Ok(EncodeTotals {
85 read: 0,
86 written: 1,
87 })
88 }
89}
90
91impl core::ops::AddAssign for EncodeTotals {
92 fn add_assign(&mut self, other: EncodeTotals) {
93 *self = EncodeTotals {
94 read: self.read + other.read,
95 written: self.written + other.written,
96 };
97 }
98}
99
100#[cfg(test)]
101mod tests {
102 use super::*;
103
104 #[test]
105 fn empty_encode() {
106 const EXPECTED: [u8; 2] = [0xc0, 0xc0];
107 let mut output: [u8; 32] = [0; 32];
108
109 let mut slip = Encoder::new();
110 let mut totals = slip.encode(&[0; 0], &mut output).unwrap();
111 assert_eq!(0, totals.read);
112 assert_eq!(1, totals.written);
113 totals += slip.finish(&mut output[totals.written..]).unwrap();
114 assert_eq!(0, totals.read);
115 assert_eq!(2, totals.written);
116 assert_eq!(&EXPECTED, &output[..totals.written]);
117 }
118
119 #[test]
120 fn encode_esc_esc_sequence() {
121 const INPUT: [u8; 3] = [0x01, ESC, 0x03];
122 const EXPECTED: [u8; 6] = [0xc0, 0x01, ESC, ESC_ESC, 0x03, 0xc0];
123 let mut output: [u8; 32] = [0; 32];
124
125 let mut slip = Encoder::new();
126 let mut totals = slip.encode(&INPUT, &mut output).unwrap();
127 assert_eq!(2 + INPUT.len(), totals.written);
128 totals += slip.finish(&mut output[totals.written..]).unwrap();
129 assert_eq!(INPUT.len(), totals.read);
130 assert_eq!(3 + INPUT.len(), totals.written);
131 assert_eq!(&EXPECTED, &output[..totals.written]);
132 }
133 #[test]
134 fn encode_end_esc_sequence() {
135 const INPUT: [u8; 3] = [0x01, END, 0x03];
136 const EXPECTED: [u8; 6] = [0xc0, 0x01, ESC, ESC_END, 0x03, 0xc0];
137 let mut output: [u8; 32] = [0; 32];
138
139 let mut slip = Encoder::new();
140 let mut totals = slip.encode(&INPUT, &mut output).unwrap();
141 assert_eq!(2 + INPUT.len(), totals.written);
142 totals += slip.finish(&mut output[totals.written..]).unwrap();
143 assert_eq!(INPUT.len(), totals.read);
144 assert_eq!(3 + INPUT.len(), totals.written);
145 assert_eq!(&EXPECTED, &output[..totals.written]);
146 }
147
148 #[test]
149 fn multi_part_encode() {
150 const INPUT_1: [u8; 4] = [0x01, 0x02, 0x03, ESC];
151 const INPUT_2: [u8; 4] = [0x05, END, 0x07, 0x08];
152 const INPUT_3: [u8; 4] = [0x09, 0x0a, ESC, 0x0c];
153 const EXPECTED: &[u8] = &[
154 0xc0, 0x01, 0x02, 0x03, ESC, ESC_ESC, 0x05, ESC, ESC_END, 0x07, 0x08, 0x09, 0x0a, ESC,
155 ESC_ESC, 0x0c, 0xc0,
156 ];
157 let mut output: [u8; 32] = [0; 32];
158
159 let mut slip = Encoder::new();
160 let mut final_totals = EncodeTotals {
161 read: 0,
162 written: 0,
163 };
164
165 let totals = slip.encode(&INPUT_1, &mut output).unwrap();
166 assert_eq!(INPUT_1.len(), totals.read);
167 assert_eq!(1 + INPUT_1.len() + 1, totals.written);
168 final_totals += totals;
169
170 let totals = slip
171 .encode(&INPUT_2, &mut output[final_totals.written..])
172 .unwrap();
173 assert_eq!(INPUT_2.len(), totals.read);
174 assert_eq!(INPUT_2.len() + 1, totals.written);
175 final_totals += totals;
176
177 let totals = slip
178 .encode(&INPUT_3, &mut output[final_totals.written..])
179 .unwrap();
180 assert_eq!(INPUT_3.len(), totals.read);
181 assert_eq!(INPUT_3.len() + 1, totals.written);
182 final_totals += totals;
183
184 let totals = slip.finish(&mut output[final_totals.written..]).unwrap();
185 assert_eq!(0, totals.read);
186 assert_eq!(1, totals.written);
187 final_totals += totals;
188
189 assert_eq!(EXPECTED, &output[..final_totals.written]);
190 }
191}