1 | use core::convert::TryInto; |
2 | |
3 | pub struct StreamSliceU8<'a>(&'a [u8]); |
4 | pub struct StreamSliceU16<'a>(&'a [u8]); |
5 | pub struct StreamSliceU32<'a>(&'a [u8]); |
6 | impl<'a> StreamSliceU8<'a> { |
7 | #[inline ] |
8 | pub fn get(&self, index: usize) -> Option<u8> { |
9 | const SIZE: usize = 1; |
10 | let offset: usize = index * SIZE; |
11 | let slice: &[u8] = self.0.get(index:offset..offset + SIZE)?; |
12 | Some(slice[0]) |
13 | } |
14 | } |
15 | impl<'a> StreamSliceU16<'a> { |
16 | #[inline ] |
17 | pub fn get(&self, index: usize) -> Option<u16> { |
18 | const SIZE: usize = 2; |
19 | let offset: usize = index * SIZE; |
20 | let slice: &[u8] = self.0.get(index:offset..offset + SIZE)?; |
21 | Some(u16::from_be_bytes(slice.try_into().unwrap())) |
22 | } |
23 | } |
24 | impl<'a> StreamSliceU32<'a> { |
25 | #[inline ] |
26 | pub fn get(&self, index: usize) -> Option<u32> { |
27 | const SIZE: usize = 4; |
28 | let offset: usize = index * SIZE; |
29 | let slice: &[u8] = self.0.get(index:offset..offset + SIZE)?; |
30 | Some(u32::from_be_bytes(slice.try_into().unwrap())) |
31 | } |
32 | } |
33 | |
34 | pub struct StreamSliceI8<'a>(StreamSliceU8<'a>); |
35 | pub struct StreamSliceI16<'a>(StreamSliceU16<'a>); |
36 | pub struct StreamSliceI32<'a>(StreamSliceU32<'a>); |
37 | impl<'a> StreamSliceI8<'a> { |
38 | #[inline ] |
39 | pub fn get(&self, index: usize) -> Option<i8> { |
40 | Some(unsafe { core::mem::transmute(self.0.get(index)?) }) |
41 | } |
42 | } |
43 | impl<'a> StreamSliceI16<'a> { |
44 | #[inline ] |
45 | pub fn get(&self, index: usize) -> Option<i16> { |
46 | Some(unsafe { core::mem::transmute(self.0.get(index)?) }) |
47 | } |
48 | } |
49 | impl<'a> StreamSliceI32<'a> { |
50 | #[inline ] |
51 | pub fn get(&self, index: usize) -> Option<i32> { |
52 | Some(unsafe { core::mem::transmute(self.0.get(index)?) }) |
53 | } |
54 | } |
55 | |
56 | pub struct Stream<'a> { |
57 | bytes: &'a [u8], |
58 | offset: usize, |
59 | } |
60 | |
61 | impl<'a> Stream<'a> { |
62 | pub const fn new(bytes: &'a [u8]) -> Stream<'a> { |
63 | Stream { |
64 | bytes, |
65 | offset: 0, |
66 | } |
67 | } |
68 | |
69 | // UTILITY |
70 | |
71 | #[inline ] |
72 | pub fn reset(&mut self) { |
73 | self.offset = 0; |
74 | } |
75 | |
76 | #[inline ] |
77 | pub const fn offset(&self) -> usize { |
78 | self.offset |
79 | } |
80 | |
81 | #[inline ] |
82 | pub fn seek(&mut self, offset: usize) { |
83 | self.offset = offset; |
84 | } |
85 | |
86 | #[inline ] |
87 | pub fn skip(&mut self, offset: usize) { |
88 | self.offset += offset; |
89 | } |
90 | |
91 | // UNSIGNED SLICE |
92 | |
93 | #[inline ] |
94 | pub fn read_u8_slice(&mut self, len: usize) -> Option<StreamSliceU8<'a>> { |
95 | let end = self.offset + len; |
96 | self.bytes.get(self.offset..end).map(|slice| { |
97 | self.offset = end; |
98 | StreamSliceU8(slice) |
99 | }) |
100 | } |
101 | |
102 | #[inline ] |
103 | pub fn read_u16_slice(&mut self, len: usize) -> Option<StreamSliceU16<'a>> { |
104 | let end = self.offset + len * 2; |
105 | self.bytes.get(self.offset..end).map(|slice| { |
106 | self.offset = end; |
107 | StreamSliceU16(slice) |
108 | }) |
109 | } |
110 | |
111 | #[inline ] |
112 | pub fn read_u32_slice(&mut self, len: usize) -> Option<StreamSliceU32<'a>> { |
113 | let end = self.offset + len * 4; |
114 | self.bytes.get(self.offset..end).map(|slice| { |
115 | self.offset = end; |
116 | StreamSliceU32(slice) |
117 | }) |
118 | } |
119 | |
120 | // SIGNED SLICE |
121 | |
122 | #[inline ] |
123 | pub fn read_i8_slice(&mut self, len: usize) -> Option<StreamSliceI8<'a>> { |
124 | Some(StreamSliceI8(self.read_u8_slice(len)?)) |
125 | } |
126 | |
127 | #[inline ] |
128 | pub fn read_i16_slice(&mut self, len: usize) -> Option<StreamSliceI16<'a>> { |
129 | Some(StreamSliceI16(self.read_u16_slice(len)?)) |
130 | } |
131 | |
132 | #[inline ] |
133 | pub fn read_i32_slice(&mut self, len: usize) -> Option<StreamSliceI32<'a>> { |
134 | Some(StreamSliceI32(self.read_u32_slice(len)?)) |
135 | } |
136 | |
137 | // UNSIGNED |
138 | |
139 | #[inline ] |
140 | pub fn read_u8(&mut self) -> Option<u8> { |
141 | const SIZE: usize = 1; |
142 | let slice = self.bytes.get(self.offset..self.offset + SIZE)?; |
143 | self.offset += SIZE; |
144 | Some(slice[0]) |
145 | } |
146 | |
147 | #[inline ] |
148 | pub fn read_u16(&mut self) -> Option<u16> { |
149 | const SIZE: usize = 2; |
150 | let slice = self.bytes.get(self.offset..self.offset + SIZE)?; |
151 | self.offset += SIZE; |
152 | Some(u16::from_be_bytes(slice.try_into().unwrap())) |
153 | } |
154 | |
155 | #[inline ] |
156 | pub fn read_u32(&mut self) -> Option<u32> { |
157 | const SIZE: usize = 4; |
158 | let slice = self.bytes.get(self.offset..self.offset + SIZE)?; |
159 | self.offset += SIZE; |
160 | Some(u32::from_be_bytes(slice.try_into().unwrap())) |
161 | } |
162 | |
163 | // SIGNED |
164 | |
165 | #[inline ] |
166 | pub fn read_i8(&mut self) -> Option<i8> { |
167 | Some(unsafe { core::mem::transmute(self.read_u8()?) }) |
168 | } |
169 | |
170 | #[inline ] |
171 | pub fn read_i16(&mut self) -> Option<i16> { |
172 | Some(unsafe { core::mem::transmute(self.read_u16()?) }) |
173 | } |
174 | |
175 | #[inline ] |
176 | pub fn read_i32(&mut self) -> Option<i32> { |
177 | Some(unsafe { core::mem::transmute(self.read_u32()?) }) |
178 | } |
179 | |
180 | // FONT |
181 | |
182 | #[inline ] |
183 | pub fn read_f2dot14(&mut self) -> Option<f32> { |
184 | let val = self.read_i16()?; |
185 | let result = val as f32 * (1.0 / (1 << 14) as f32); |
186 | Some(result) |
187 | } |
188 | |
189 | #[inline ] |
190 | pub fn read_tag(&mut self) -> Option<[u8; 4]> { |
191 | const SIZE: usize = 4; |
192 | let slice = self.bytes.get(self.offset..self.offset + SIZE)?; |
193 | self.offset += SIZE; |
194 | Some(slice.try_into().unwrap()) |
195 | } |
196 | } |
197 | |