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
114#[cfg(test)]
115mod tests {
116 use super::*;
117
118 #[test]
119 fn escape_passthrough() {
120 let data = b"hello world";
121 assert_eq!(escape(data), data.to_vec());
122 }
123
124 #[test]
125 fn escape_flag() {
126 assert_eq!(escape(&[FLAG]), vec![ESC, FLAG ^ ESC_MASK]);
127 assert_eq!(escape(&[0x7E]), vec![0x7D, 0x5E]);
128 }
129
130 #[test]
131 fn escape_esc() {
132 assert_eq!(escape(&[ESC]), vec![ESC, ESC ^ ESC_MASK]);
133 assert_eq!(escape(&[0x7D]), vec![0x7D, 0x5D]);
134 }
135
136 #[test]
137 fn escape_mixed() {
138 let data = [0x01, FLAG, 0x02, ESC, 0x03];
139 let expected = vec![0x01, ESC, FLAG ^ ESC_MASK, 0x02, ESC, ESC ^ ESC_MASK, 0x03];
140 assert_eq!(escape(&data), expected);
141 }
142
143 #[test]
144 fn frame_structure() {
145 let data = b"test";
146 let framed = frame(data);
147 assert_eq!(framed[0], FLAG);
148 assert_eq!(*framed.last().unwrap(), FLAG);
149 assert_eq!(&framed[1..framed.len() - 1], &escape(data));
150 }
151
152 #[test]
153 fn roundtrip_all_bytes() {
154 let data: Vec<u8> = (0..=255).collect();
156 let framed = frame(&data);
157
158 let mut decoder = Decoder::new();
159 let frames = decoder.feed(&framed);
160 assert_eq!(frames.len(), 1);
161 assert_eq!(frames[0], data);
162 }
163
164 #[test]
165 fn decoder_single_frame() {
166 let data: Vec<u8> = (0..32).collect();
168 let framed = frame(&data);
169
170 let mut decoder = Decoder::new();
171 let frames = decoder.feed(&framed);
172 assert_eq!(frames.len(), 1);
173 assert_eq!(frames[0], data);
174 }
175
176 #[test]
177 fn decoder_two_frames_one_chunk() {
178 let data1: Vec<u8> = (0..24).collect();
179 let data2: Vec<u8> = (100..130).collect();
180 let mut combined = frame(&data1);
181 let framed2 = frame(&data2);
186 combined.extend_from_slice(&framed2[1..]);
188
189 let mut decoder = Decoder::new();
190 let frames = decoder.feed(&combined);
191 assert_eq!(frames.len(), 2);
192 assert_eq!(frames[0], data1);
193 assert_eq!(frames[1], data2);
194 }
195
196 #[test]
197 fn decoder_split_frame() {
198 let data: Vec<u8> = (0..32).collect();
199 let framed = frame(&data);
200
201 let mid = framed.len() / 2;
203 let mut decoder = Decoder::new();
204
205 let frames1 = decoder.feed(&framed[..mid]);
206 assert_eq!(frames1.len(), 0); let frames2 = decoder.feed(&framed[mid..]);
209 assert_eq!(frames2.len(), 1);
210 assert_eq!(frames2[0], data);
211 }
212
213 #[test]
214 fn decoder_drops_short() {
215 let data = vec![0x01, 0x02, 0x03]; let framed = frame(&data);
218
219 let mut decoder = Decoder::new();
220 let frames = decoder.feed(&framed);
221 assert_eq!(frames.len(), 0); }
223}