1#![no_std]
3
4pub mod frame_meta;
6pub mod iap2_frame_meta;
8use core::marker::PhantomData;
9
10use frame_meta::FrameMeta;
11
12#[derive(Debug, PartialEq, Eq, Clone, Copy)]
14pub struct Empty;
15
16#[derive(Debug, PartialEq, Eq, Clone, Copy)]
18pub struct Full;
19
20#[derive(Debug)]
22pub struct FramePicker<const N: usize, M: FrameMeta> {
23 storage: [u8; N],
24 read_at: usize,
25 pub dropped : usize,
27 _marker : PhantomData<M>,
28}
29
30impl<const N: usize, M: FrameMeta> FramePicker<N, M> {
31 pub fn new() -> Self {
33 Self {
34 storage: [0; N],
35 read_at: 0,
36 dropped: 0,
37 _marker: PhantomData,
38 }
39 }
40
41 pub fn feed_data(&mut self, data: &[u8]) -> Result<usize, Full> {
44 if self.read_at + data.len() > N {
45 return Err(Full);
46 }
47
48 let len = data.len();
49 self.storage[self.read_at..self.read_at + len].copy_from_slice(&data[..len]);
50 self.read_at += len;
51 self.align_buffer_with_header();
52 Ok(len)
53 }
54
55 fn align_buffer_with_header(&mut self) {
57 let mut search_at: usize = 0;
58 loop {
59 if self.read_at - search_at < M::frame_header_len() {
60 break;
61 }
62 if M::frame_match(&self.storage[search_at..self.read_at]) {
63 break;
64 } else {
65 search_at += 1;
66 }
67 }
68 if search_at > 0 {
69 self.dropped += search_at;
70 self.storage.copy_within(search_at..self.read_at, 0);
71 self.read_at -= search_at;
72 }
73 }
74
75 pub fn contain_frame(&self) -> bool {
77 if self.read_at < M::frame_header_len() {
78 return false;
79 }
80 M::frame_match(self.storage[..self.read_at].as_ref())
81 }
82
83 pub fn frame_complete(&self) -> bool {
85 if self.read_at < M::frame_header_len() {
86 return false;
87 }
88 let total_len = M::frame_totol_len(self.storage[..self.read_at].as_ref());
89 total_len > 0 && total_len <= self.read_at
90 }
91
92 pub fn acquire_frame(&mut self) -> Result<&[u8], Empty> {
94 if self.frame_complete() {
95 let total_len = M::frame_totol_len(self.storage[..self.read_at].as_ref());
96 let data = &self.storage[..total_len];
97 Ok(data)
98 } else {
99 Err(Empty)
100 }
101 }
102
103 pub fn release_frame(&mut self) -> Result<(), Empty> {
105 if self.frame_complete() {
106 let total_len = M::frame_totol_len(self.storage[..self.read_at].as_ref());
107 self.storage.copy_within(total_len..self.read_at, 0);
108 self.read_at -= total_len;
109 self.align_buffer_with_header();
110 Ok(())
111 } else {
112 Err(Empty)
113 }
114 }
115
116 pub fn dequeue_frame_with<F,R>(&mut self, f: F) -> Result<R, Empty>
118 where
119 F: FnOnce(&[u8]) -> R,
120 {
121 if let Ok(frame) = self.acquire_frame() {
122 let result = f(frame);
123 self.release_frame().unwrap();
124 Ok(result)
125 } else {
126 Err(Empty)
127 }
128 }
129}
130#[cfg(test)]
131mod tests {
132 use super::*;
133
134 fn picker() -> FramePicker::<500,iap2_frame_meta::Iap2FrameMeta> {
135 FramePicker::<500,iap2_frame_meta::Iap2FrameMeta>::new()
136 }
137
138 #[test]
139 fn test_feed_handshake() {
140 let mut picker = picker();
141 let shake = [0xff, 0x55, 0x02, 0x00, 0xee, 0x10];
142 assert_eq!(picker.feed_data(&shake[..]), Ok(6));
143 assert_eq!(picker.dropped, 0);
144 assert_eq!(picker.read_at, 6);
145 assert!(picker.contain_frame());
146 assert_eq!(picker.frame_complete(), true);
147
148 assert_eq!(picker.acquire_frame(), Ok(&shake[..]));
149 assert_eq!(picker.release_frame(), Ok(()));
150 }
151
152 #[test]
153 fn test_feed_normal_data() {
154 let mut picker = picker();
155 let normal_data = [0xff, 0x5a, 0x00, 0x0a, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a];
156 assert_eq!(picker.feed_data(&normal_data[..]), Ok(10));
157 assert_eq!(picker.dropped, 0);
158 assert_eq!(picker.read_at, 10);
159 assert!(picker.contain_frame());
160 assert_eq!(picker.frame_complete(), true);
161
162 assert_eq!(picker.acquire_frame(), Ok(&normal_data[..]));
163 assert_eq!(picker.release_frame(), Ok(()));
164 }
165
166 #[test]
167 fn test_feed_data_exceed_storage() {
168 let mut picker = FramePicker::<10,iap2_frame_meta::Iap2FrameMeta>::new();
169 let normal_data = [0xff, 0x5a, 0x00, 0x0b, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b];
170 assert_eq!(picker.feed_data(&normal_data[..]), Err(Full));
171 assert_eq!(picker.read_at, 0);
172 assert_eq!(picker.contain_frame(), false);
173 assert_eq!(picker.frame_complete(), false);
174 }
175
176 #[test]
177 fn test_feed_data_with_dropped() {
178 let mut picker = picker();
179 let normal_data = [0x00, 0x00, 0xff, 0x5a, 0x00, 0x0a, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a];
180 assert_eq!(picker.feed_data(&normal_data[..]), Ok(12));
181 assert_eq!(picker.dropped, 2);
182 assert_eq!(picker.read_at, 10);
183 assert_eq!(picker.contain_frame(), true);
184 assert_eq!(picker.frame_complete(), true);
185
186 assert_eq!(picker.feed_data(&normal_data[..]), Ok(12));
187 assert_eq!(picker.dropped, 2);
188 assert_eq!(picker.read_at, 10+12);
189 assert_eq!(picker.release_frame(), Ok(()));
190 assert_eq!(picker.release_frame(), Ok(()));
191 }
192
193 #[test]
194 fn test_short_frame() {
195 let mut picker = picker();
196 let normal_data = [0xff, 0x5a, 0x00, 0x0a, 0x05, 0x06, 0x07, 0x08, 0x09];
197 assert_eq!(picker.feed_data(&normal_data[..]), Ok(9));
198 assert_eq!(picker.dropped, 0);
199 assert_eq!(picker.read_at, 9);
200 assert!(picker.contain_frame());
201 assert_eq!(picker.frame_complete(), false);
202
203 assert_eq!(picker.feed_data(&[0x0a, 0xff, 0x5a]), Ok(3));
204 assert_eq!(picker.frame_complete(), true);
205 assert_eq!(picker.release_frame(), Ok(()));
206
207 assert_eq!(picker.feed_data(&[0x00, 0x0a, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a]), Ok(8));
208 assert_eq!(picker.frame_complete(), true);
209 }
210
211 #[test]
212 fn test_header_not_complete() {
213 let mut picker = picker();
214 let data1 = [0x32,0x34,0x42,0x33,0x52,0x42, 0x32, 0x31, 0x93,0x32,0xff];
215 let data2 = [0x5a,0x00,0x0a,0x05,0x06,0x07,0x08,0x09,0x0a];
216 assert_eq!(picker.feed_data(&data1[..]), Ok(11));
217 assert_eq!(picker.dropped, 6);
218 assert_eq!(picker.contain_frame(), false);
219
220 assert_eq!(picker.feed_data(&data2[..]), Ok(9));
221 assert_eq!(picker.dropped, 10);
222 assert_eq!(picker.contain_frame(), true);
223
224 }
225
226}