1use super::error::ParseError;
6
7use std::fmt::Debug;
8use std::sync::Arc;
9use zerocopy::{FromBytes, Immutable, KnownLayout, Unaligned};
10
11pub type PolicyData = Arc<Vec<u8>>;
12pub type PolicyOffset = u32;
13
14#[derive(Clone, Debug, PartialEq)]
15pub struct PolicyCursor {
16 data: PolicyData,
17 offset: PolicyOffset,
18}
19
20impl PolicyCursor {
21 pub fn new(data: PolicyData) -> Self {
23 Self { data, offset: 0 }
24 }
25
26 pub fn new_at(data: PolicyData, offset: PolicyOffset) -> Self {
28 Self { data, offset }
29 }
30
31 pub fn parse<P: Clone + Debug + FromBytes + KnownLayout + Immutable + PartialEq + Unaligned>(
33 mut self,
34 ) -> Result<(P, Self), ParseError> {
35 let remaining_slice = &(self.data.as_ref()[self.offset as usize..]);
36 let (output, _) =
37 P::read_from_prefix(remaining_slice).map_err(|_| ParseError::MissingData {
38 type_name: std::any::type_name::<P>(),
39 type_size: std::mem::size_of::<P>(),
40 num_bytes: self.data.len() - self.offset as usize,
41 })?;
42 self.offset += std::mem::size_of::<P>() as PolicyOffset;
43 Ok((output, self))
44 }
45
46 pub fn offset(&self) -> PolicyOffset {
47 self.offset
48 }
49
50 pub fn data(&self) -> &PolicyData {
51 &self.data
52 }
53}
54
55#[cfg(test)]
56mod tests {
57 use super::*;
58 use zerocopy::little_endian as le;
59
60 #[derive(Clone, Debug, KnownLayout, FromBytes, Immutable, PartialEq, Unaligned)]
61 #[repr(C, packed)]
62 struct SomeNumbers {
63 a: u8,
64 b: le::U32,
65 c: le::U16,
66 d: u8,
67 }
68
69 #[test]
70 fn entire_vector() {
71 let bytes: Vec<u8> = (0..8).collect();
72 let data = Arc::new(bytes);
73
74 let tail = PolicyCursor::new(data);
75 let (some_numbers, tail) = tail.parse::<SomeNumbers>().expect("some numbers");
76
77 assert_eq!(0, some_numbers.a);
78 assert_eq!((1 << 0) + (2 << 8) + (3 << 16) + (4 << 24), some_numbers.b.get());
79 assert_eq!((5 << 0) + (6 << 8), some_numbers.c.get());
80 assert_eq!(7, some_numbers.d);
81 assert_eq!(8, tail.offset());
82 assert_eq!(8, tail.data().len());
83 }
84
85 #[test]
86 fn range_within_vector() {
87 let bytes: Vec<u8> = (0..40).collect();
88 let data = Arc::new(bytes);
89
90 let tail = PolicyCursor::new_at(data, 8);
91 let (first_some_numbers, tail) = tail.parse::<SomeNumbers>().expect("some numbers");
92 let (second_some_numbers, tail) = tail.parse::<SomeNumbers>().expect("some numbers");
93 let (third_some_numbers, tail) = tail.parse::<SomeNumbers>().expect("some numbers");
94
95 assert_eq!(8, first_some_numbers.a);
96 assert_eq!((9 << 0) + (10 << 8) + (11 << 16) + (12 << 24), first_some_numbers.b.get());
97 assert_eq!((13 << 0) + (14 << 8), first_some_numbers.c.get());
98 assert_eq!(15, first_some_numbers.d);
99 assert_eq!(16, second_some_numbers.a);
100 assert_eq!((17 << 0) + (18 << 8) + (19 << 16) + (20 << 24), second_some_numbers.b.get());
101 assert_eq!((21 << 0) + (22 << 8), second_some_numbers.c.get());
102 assert_eq!(23, second_some_numbers.d);
103 assert_eq!(24, third_some_numbers.a);
104 assert_eq!((25 << 0) + (26 << 8) + (27 << 16) + (28 << 24), third_some_numbers.b.get());
105 assert_eq!((29 << 0) + (30 << 8), third_some_numbers.c.get());
106 assert_eq!(31, third_some_numbers.d);
107 assert_eq!(32, tail.offset());
108 assert_eq!(40, tail.data().len());
109 }
110}