1#![doc = include_str!("../README.md")]
2#![no_std]
3use core::iter::{Iterator, FusedIterator};
4use core::error::Error;
5use core::fmt::Display;
6
7pub const IDMV1_FRAME_SIZE: usize = 6;
9pub const IDMV2_FRAME_SIZE: usize = 8;
11pub const MIN_FRAME_SIZE: usize = IDMV1_FRAME_SIZE;
13
14pub type IDMVersion = u8;
16pub const IDM_VERSION_1: IDMVersion = 1;
18pub const IDM_VERSION_2: IDMVersion = 2;
20
21pub type IDMFinality = u8;
23pub const IDM_NOT_FINAL: IDMFinality = 0;
25pub const IDM_FINAL: IDMFinality = 1;
27
28pub type EncodingMask = u16;
30pub const IDM_ENCODING_DER: EncodingMask = 0b1000_0000_0000_0000;
32pub const IDM_ENCODING_PER_ALIGNED: EncodingMask = 0b0100_0000_0000_0000;
34pub const IDM_ENCODING_PER_UNALIGNED: EncodingMask = 0b0010_0000_0000_0000;
36pub const IDM_ENCODING_XER: EncodingMask = 0b0001_0000_0000_0000;
38
39#[derive(Debug, Clone, Eq, PartialEq)]
41pub enum IdmError {
42 UnsupportedVersion(u8),
44}
45
46impl Display for IdmError {
47
48 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
49 match self {
50 IdmError::UnsupportedVersion(v) => write!(f, "unrecognized idm version ({})", v),
51 }
52 }
53
54}
55
56impl Error for IdmError {}
57
58#[derive(Debug)]
60pub struct IdmFrame <'a> {
61 pub version: u8,
64 pub final_: u8,
69 pub encoding: u16,
72 pub data: &'a [u8],
74}
75
76pub struct IdmFrameIter <'a> {
79 buffer: &'a [u8],
80}
81
82impl <'a> IdmFrameIter<'a> {
83
84 pub fn new(buffer: &'a [u8]) -> IdmFrameIter<'a> {
86 IdmFrameIter { buffer }
87 }
88
89 pub fn bytes_unread(&self) -> usize {
91 self.buffer.len()
92 }
93
94}
95
96impl <'a> Iterator for IdmFrameIter<'a> {
97 type Item = Result<IdmFrame<'a>, IdmError>;
98
99 fn next(&mut self) -> Option<Self::Item> {
100 if self.buffer.len() < MIN_FRAME_SIZE {
101 return None;
102 }
103 let version: u8 = self.buffer[0];
104 let final_: u8 = self.buffer[1];
105 let mut encoding: u16 = 0;
106 match version {
107 1 => {
108 let len: usize = u32::from_be_bytes([
109 self.buffer[2],
110 self.buffer[3],
111 self.buffer[4],
112 self.buffer[5],
113 ]) as usize;
114 let data = self.buffer.get(IDMV1_FRAME_SIZE..IDMV1_FRAME_SIZE + len)?;
115 self.buffer = &self.buffer[IDMV1_FRAME_SIZE + len..];
116 Some(Ok(IdmFrame {
117 version,
118 final_,
119 encoding,
120 data,
121 }))
122 },
123 2 => {
124 if self.buffer.len() < IDMV2_FRAME_SIZE {
125 return None;
126 }
127 encoding = u16::from_be_bytes([
128 self.buffer[2],
129 self.buffer[3],
130 ]);
131 let len: usize = u32::from_be_bytes([
132 self.buffer[4],
133 self.buffer[5],
134 self.buffer[6],
135 self.buffer[7],
136 ]) as usize;
137 let data = self.buffer.get(IDMV2_FRAME_SIZE..IDMV2_FRAME_SIZE + len)?;
138 self.buffer = &self.buffer[IDMV2_FRAME_SIZE + len..];
139 Some(Ok(IdmFrame {
140 version,
141 final_,
142 encoding,
143 data,
144 }))
145 },
146 _ => {
147 self.buffer = &self.buffer[0..0];
148 Some(Err(IdmError::UnsupportedVersion(version)))
149 },
150 }
151 }
152
153}
154
155impl <'a> FusedIterator for IdmFrameIter<'a> {}
156
157pub fn write_idm_v1_frame_header(
159 header: &mut [u8; IDMV1_FRAME_SIZE],
160 final_: bool,
161 data_len: u32,
162) {
163 header[0] = IDM_VERSION_1;
164 header[1] = if final_ { IDM_FINAL } else { IDM_NOT_FINAL };
165 let [l1, l2, l3, l4] = data_len.to_be_bytes();
166 header[2] = l1;
167 header[3] = l2;
168 header[4] = l3;
169 header[5] = l4;
170}
171
172pub fn write_idm_v2_frame_header(
174 header: &mut [u8; IDMV2_FRAME_SIZE],
175 final_: bool,
176 encoding: EncodingMask,
177 data_len: u32,
178) {
179 header[0] = IDM_VERSION_2;
180 header[1] = if final_ { IDM_FINAL } else { IDM_NOT_FINAL };
181 let [e1, e2] = encoding.to_be_bytes();
182 header[2] = e1;
183 header[3] = e2;
184 let [l1, l2, l3, l4] = data_len.to_be_bytes();
185 header[4] = l1;
186 header[5] = l2;
187 header[6] = l3;
188 header[7] = l4;
189}
190
191#[cfg(test)]
192mod tests {
193
194 extern crate alloc;
195 use alloc::vec::Vec;
196
197 use super::{
198 IdmFrameIter,
199 write_idm_v1_frame_header,
200 write_idm_v2_frame_header,
201 IDM_ENCODING_XER,
202 IDMV1_FRAME_SIZE,
203 IDMV2_FRAME_SIZE,
204 };
205
206 #[test]
207 fn iter_idm_v1_frames_1() {
208 let buffer: Vec<u8> = Vec::from([
209 1, 1, 0, 0, 0, 5, 1, 2, 3, 4, 5,
210 ].as_slice());
211 let mut frames = IdmFrameIter::new(buffer.as_slice());
212 let frame = frames.next().unwrap().unwrap();
213 assert_eq!(frame.version, 1);
214 assert_eq!(frame.final_, 1);
215 assert_eq!(frame.encoding, 0);
216 assert_eq!(frame.data, [1,2,3,4,5].as_slice());
217 let frame = frames.next();
218 assert!(frame.is_none());
219 let frame = frames.next();
220 assert!(frame.is_none());
221 }
222
223 #[test]
224 fn iter_idm_v1_frames_2() {
225 let buffer: Vec<u8> = Vec::from([
226 1, 1, 0, 0, 0, 5, 1, 2, 3, 4, 5, 1
227 ].as_slice());
228 let mut frames = IdmFrameIter::new(buffer.as_slice());
229 let frame = frames.next().unwrap().unwrap();
230 assert_eq!(frame.version, 1);
231 assert_eq!(frame.final_, 1);
232 assert_eq!(frame.encoding, 0);
233 assert_eq!(frame.data, [1,2,3,4,5].as_slice());
234 let frame = frames.next();
235 assert!(frame.is_none());
236 let frame = frames.next();
237 assert!(frame.is_none());
238 }
239
240 #[test]
241 fn iter_idm_v1_frames_3() {
242 let buffer: Vec<u8> = Vec::from([ 1, 1, 0, 0, 0, 0 ].as_slice());
243 let mut frames = IdmFrameIter::new(buffer.as_slice());
244 let frame = frames.next().unwrap().unwrap();
245 assert_eq!(frame.version, 1);
246 assert_eq!(frame.final_, 1);
247 assert_eq!(frame.encoding, 0);
248 assert_eq!(frame.data, [].as_slice());
249 let frame = frames.next();
250 assert!(frame.is_none());
251 let frame = frames.next();
252 assert!(frame.is_none());
253 }
254
255 #[test]
256 fn iter_idm_v1_frames_4() {
257 let buffer: Vec<u8> = Vec::from([
258 1, 0, 0, 0, 0, 5, 1, 2, 3, 4, 5,
259 1, 1, 0, 0, 0, 4, 5, 6, 7, 8, 9,
260 ].as_slice());
261 let mut frames = IdmFrameIter::new(buffer.as_slice());
262 let frame = frames.next().unwrap().unwrap();
263 assert_eq!(frame.version, 1);
264 assert_eq!(frame.final_, 0);
265 assert_eq!(frame.encoding, 0);
266 assert_eq!(frame.data, [1,2,3,4,5].as_slice());
267 let frame = frames.next().unwrap().unwrap();
268 assert_eq!(frame.version, 1);
269 assert_eq!(frame.final_, 1);
270 assert_eq!(frame.encoding, 0);
271 assert_eq!(frame.data, [5,6,7,8].as_slice());
272
273 let frame = frames.next();
274 assert!(frame.is_none());
275 let frame = frames.next();
276 assert!(frame.is_none());
277 }
278
279 #[test]
280 fn iter_idm_v2_frames_1() {
281 let buffer: Vec<u8> = Vec::from([
282 2, 1, 8, 8, 0, 0, 0, 5, 1, 2, 3, 4, 5,
283 ].as_slice());
284 let mut frames = IdmFrameIter::new(buffer.as_slice());
285 let frame = frames.next().unwrap().unwrap();
286 assert_eq!(frame.version, 2);
287 assert_eq!(frame.final_, 1);
288 assert_eq!(frame.encoding, 0x0808);
289 assert_eq!(frame.data, [1,2,3,4,5].as_slice());
290 let frame = frames.next();
291 assert!(frame.is_none());
292 let frame = frames.next();
293 assert!(frame.is_none());
294 }
295
296 #[test]
297 fn iter_idm_v2_frames_2() {
298 let buffer: Vec<u8> = Vec::from([
299 2, 1, 8, 8, 0, 0, 0, 5, 1, 2, 3, 4, 5, 1
300 ].as_slice());
301 let mut frames = IdmFrameIter::new(buffer.as_slice());
302 let frame = frames.next().unwrap().unwrap();
303 assert_eq!(frame.version, 2);
304 assert_eq!(frame.final_, 1);
305 assert_eq!(frame.encoding, 0x0808);
306 assert_eq!(frame.data, [1,2,3,4,5].as_slice());
307 let frame = frames.next();
308 assert!(frame.is_none());
309 let frame = frames.next();
310 assert!(frame.is_none());
311 }
312
313 #[test]
314 fn iter_idm_v2_frames_3() {
315 let buffer: Vec<u8> = Vec::from([ 2, 1, 8, 8, 0, 0, 0, 0 ].as_slice());
316 let mut frames = IdmFrameIter::new(buffer.as_slice());
317 let frame = frames.next().unwrap().unwrap();
318 assert_eq!(frame.version, 2);
319 assert_eq!(frame.final_, 1);
320 assert_eq!(frame.encoding, 0x0808);
321 assert_eq!(frame.data, [].as_slice());
322 let frame = frames.next();
323 assert!(frame.is_none());
324 let frame = frames.next();
325 assert!(frame.is_none());
326 }
327
328 #[test]
329 fn iter_idm_v2_frames_4() {
330 let buffer: Vec<u8> = Vec::from([
331 2, 0, 8, 8, 0, 0, 0, 5, 1, 2, 3, 4, 5,
332 2, 1, 8, 8, 0, 0, 0, 4, 5, 6, 7, 8, 9,
333 ].as_slice());
334 let mut frames = IdmFrameIter::new(buffer.as_slice());
335 let frame = frames.next().unwrap().unwrap();
336 assert_eq!(frame.version, 2);
337 assert_eq!(frame.final_, 0);
338 assert_eq!(frame.encoding, 0x0808);
339 assert_eq!(frame.data, [1,2,3,4,5].as_slice());
340 let frame = frames.next().unwrap().unwrap();
341 assert_eq!(frame.version, 2);
342 assert_eq!(frame.final_, 1);
343 assert_eq!(frame.encoding, 0x0808);
344 assert_eq!(frame.data, [5,6,7,8].as_slice());
345
346 let frame = frames.next();
347 assert!(frame.is_none());
348 let frame = frames.next();
349 assert!(frame.is_none());
350 }
351
352 #[test]
353 fn iter_idm_unrecognized_version() {
354 let buffer: Vec<u8> = Vec::from([
355 3, 1, 8, 8, 0, 0, 0, 4, 5, 6, 7, 8, 9,
356 ].as_slice());
357 let mut frames = IdmFrameIter::new(buffer.as_slice());
358 let frame = frames.next().unwrap();
359 assert!(frame.is_err());
360
361 let frame = frames.next();
362 assert!(frame.is_none());
363 let frame = frames.next();
364 assert!(frame.is_none());
365 }
366
367 #[test]
368 fn test_write_idm_v1_frame_header_1() {
369 let mut buf: [u8; IDMV1_FRAME_SIZE] = [0, 0, 0, 0, 0, 0];
370 write_idm_v1_frame_header(&mut buf, true, 1024);
371 assert_eq!(buf, [1, 1, 0, 0, 4, 0]);
372 }
373
374 #[test]
375 fn test_write_idm_v2_frame_header_1() {
376 let mut buf: [u8; IDMV2_FRAME_SIZE] = [0, 0, 0, 0, 0, 0, 0, 0];
377 write_idm_v2_frame_header(&mut buf, true, IDM_ENCODING_XER, 1024);
378 assert_eq!(buf, [2, 1, 0x10, 0, 0, 0, 4, 0]);
379 }
380
381}