1use rns_core::constants::HEADER_MINSIZE;
6
7const FLAG: u8 = 0x7E;
8const ESC: u8 = 0x7D;
9const ESC_MASK: u8 = 0x20;
10
11pub fn escape(data: &[u8]) -> Vec<u8> {
13 let mut out = Vec::with_capacity(data.len());
14 for &b in data {
15 match b {
16 ESC => {
17 out.push(ESC);
18 out.push(ESC ^ ESC_MASK);
19 }
20 FLAG => {
21 out.push(ESC);
22 out.push(FLAG ^ ESC_MASK);
23 }
24 _ => out.push(b),
25 }
26 }
27 out
28}
29
30pub fn frame(data: &[u8]) -> Vec<u8> {
32 let escaped = escape(data);
33 let mut out = Vec::with_capacity(escaped.len() + 2);
34 out.push(FLAG);
35 out.extend_from_slice(&escaped);
36 out.push(FLAG);
37 out
38}
39
40fn unescape(data: &[u8]) -> Vec<u8> {
42 let mut out = Vec::with_capacity(data.len());
43 let mut i = 0;
44 while i < data.len() {
45 if data[i] == ESC && i + 1 < data.len() {
46 out.push(data[i + 1] ^ ESC_MASK);
47 i += 2;
48 } else {
49 out.push(data[i]);
50 i += 1;
51 }
52 }
53 out
54}
55
56pub struct Decoder {
61 buffer: Vec<u8>,
62}
63
64impl Decoder {
65 pub fn new() -> Self {
66 Decoder { buffer: Vec::new() }
67 }
68
69 pub fn feed(&mut self, chunk: &[u8]) -> Vec<Vec<u8>> {
71 self.buffer.extend_from_slice(chunk);
72 let mut frames = Vec::new();
73
74 loop {
75 let start = match self.buffer.iter().position(|&b| b == FLAG) {
77 Some(pos) => pos,
78 None => {
79 self.buffer.clear();
81 break;
82 }
83 };
84
85 if start > 0 {
87 self.buffer.drain(..start);
88 }
89
90 let end = match self.buffer[1..].iter().position(|&b| b == FLAG) {
92 Some(pos) => pos + 1, None => break, };
95
96 let between = &self.buffer[1..end];
98 let unescaped = unescape(between);
99
100 if unescaped.len() >= HEADER_MINSIZE {
102 frames.push(unescaped);
103 }
104
105 self.buffer.drain(..end);
108 }
109
110 frames
111 }
112}
113
114impl Default for Decoder {
115 fn default() -> Self {
116 Self::new()
117 }
118}
119
120#[cfg(test)]
121mod tests {
122 use super::*;
123
124 #[test]
125 fn escape_passthrough() {
126 let data = b"hello world";
127 assert_eq!(escape(data), data.to_vec());
128 }
129
130 #[test]
131 fn escape_flag() {
132 assert_eq!(escape(&[FLAG]), vec![ESC, FLAG ^ ESC_MASK]);
133 assert_eq!(escape(&[0x7E]), vec![0x7D, 0x5E]);
134 }
135
136 #[test]
137 fn escape_esc() {
138 assert_eq!(escape(&[ESC]), vec![ESC, ESC ^ ESC_MASK]);
139 assert_eq!(escape(&[0x7D]), vec![0x7D, 0x5D]);
140 }
141
142 #[test]
143 fn escape_mixed() {
144 let data = [0x01, FLAG, 0x02, ESC, 0x03];
145 let expected = vec![0x01, ESC, FLAG ^ ESC_MASK, 0x02, ESC, ESC ^ ESC_MASK, 0x03];
146 assert_eq!(escape(&data), expected);
147 }
148
149 #[test]
150 fn frame_structure() {
151 let data = b"test";
152 let framed = frame(data);
153 assert_eq!(framed[0], FLAG);
154 assert_eq!(*framed.last().unwrap(), FLAG);
155 assert_eq!(&framed[1..framed.len() - 1], &escape(data));
156 }
157
158 #[test]
159 fn roundtrip_all_bytes() {
160 let data: Vec<u8> = (0..=255).collect();
162 let framed = frame(&data);
163
164 let mut decoder = Decoder::new();
165 let frames = decoder.feed(&framed);
166 assert_eq!(frames.len(), 1);
167 assert_eq!(frames[0], data);
168 }
169
170 #[test]
171 fn decoder_single_frame() {
172 let data: Vec<u8> = (0..32).collect();
174 let framed = frame(&data);
175
176 let mut decoder = Decoder::new();
177 let frames = decoder.feed(&framed);
178 assert_eq!(frames.len(), 1);
179 assert_eq!(frames[0], data);
180 }
181
182 #[test]
183 fn decoder_two_frames_one_chunk() {
184 let data1: Vec<u8> = (0..24).collect();
185 let data2: Vec<u8> = (100..130).collect();
186 let mut combined = frame(&data1);
187 let framed2 = frame(&data2);
192 combined.extend_from_slice(&framed2[1..]);
194
195 let mut decoder = Decoder::new();
196 let frames = decoder.feed(&combined);
197 assert_eq!(frames.len(), 2);
198 assert_eq!(frames[0], data1);
199 assert_eq!(frames[1], data2);
200 }
201
202 #[test]
203 fn decoder_split_frame() {
204 let data: Vec<u8> = (0..32).collect();
205 let framed = frame(&data);
206
207 let mid = framed.len() / 2;
209 let mut decoder = Decoder::new();
210
211 let frames1 = decoder.feed(&framed[..mid]);
212 assert_eq!(frames1.len(), 0); let frames2 = decoder.feed(&framed[mid..]);
215 assert_eq!(frames2.len(), 1);
216 assert_eq!(frames2[0], data);
217 }
218
219 #[test]
220 fn decoder_drops_short() {
221 let data = vec![0x01, 0x02, 0x03]; let framed = frame(&data);
224
225 let mut decoder = Decoder::new();
226 let frames = decoder.feed(&framed);
227 assert_eq!(frames.len(), 0); }
229}