fontdb/ttf_parser/
parser.rs1use core::convert::TryInto;
4
5pub trait FromData: Sized {
9 const SIZE: usize;
13
14 fn parse(data: &[u8]) -> Option<Self>;
16}
17
18impl FromData for u16 {
19 const SIZE: usize = 2;
20
21 #[inline]
22 fn parse(data: &[u8]) -> Option<Self> {
23 data.try_into().ok().map(u16::from_be_bytes)
24 }
25}
26
27impl FromData for u32 {
28 const SIZE: usize = 4;
29
30 #[inline]
31 fn parse(data: &[u8]) -> Option<Self> {
32 data.try_into().ok().map(u32::from_be_bytes)
33 }
34}
35
36pub trait NumFrom<T>: Sized {
42 fn num_from(_: T) -> Self;
44}
45
46impl NumFrom<u32> for usize {
47 #[inline]
48 fn num_from(v: u32) -> Self {
49 #[cfg(any(target_pointer_width = "32", target_pointer_width = "64"))]
50 {
51 v as usize
52 }
53
54 }
56}
57
58#[derive(Clone, Copy)]
62pub struct LazyArray16<'a, T> {
63 data: &'a [u8],
64 data_type: core::marker::PhantomData<T>,
65}
66
67impl<T> Default for LazyArray16<'_, T> {
68 #[inline]
69 fn default() -> Self {
70 LazyArray16 {
71 data: &[],
72 data_type: core::marker::PhantomData,
73 }
74 }
75}
76
77impl<'a, T: FromData> LazyArray16<'a, T> {
78 #[inline]
80 pub fn new(data: &'a [u8]) -> Self {
81 LazyArray16 {
82 data,
83 data_type: core::marker::PhantomData,
84 }
85 }
86
87 #[inline]
89 pub fn get(&self, index: u16) -> Option<T> {
90 if index < self.len() {
91 let start = usize::from(index) * T::SIZE;
92 let end = start + T::SIZE;
93 self.data.get(start..end).and_then(T::parse)
94 } else {
95 None
96 }
97 }
98
99 #[inline]
101 pub fn len(&self) -> u16 {
102 (self.data.len() / T::SIZE) as u16
103 }
104
105 #[inline]
107 pub fn binary_search_by<F>(&self, mut f: F) -> Option<(u16, T)>
108 where
109 F: FnMut(&T) -> core::cmp::Ordering,
110 {
111 use core::cmp::Ordering;
114
115 let mut size = self.len();
116 if size == 0 {
117 return None;
118 }
119
120 let mut base = 0;
121 while size > 1 {
122 let half = size / 2;
123 let mid = base + half;
124 let cmp = f(&self.get(mid)?);
128 base = if cmp == Ordering::Greater { base } else { mid };
129 size -= half;
130 }
131
132 let value = self.get(base)?;
134 if f(&value) == Ordering::Equal {
135 Some((base, value))
136 } else {
137 None
138 }
139 }
140}
141
142impl<'a, T: FromData> IntoIterator for LazyArray16<'a, T> {
143 type Item = T;
144 type IntoIter = LazyArrayIter16<'a, T>;
145
146 #[inline]
147 fn into_iter(self) -> Self::IntoIter {
148 LazyArrayIter16 {
149 data: self,
150 index: 0,
151 }
152 }
153}
154
155#[derive(Clone, Copy)]
157pub struct LazyArrayIter16<'a, T> {
158 data: LazyArray16<'a, T>,
159 index: u16,
160}
161
162impl<'a, T: FromData> Iterator for LazyArrayIter16<'a, T> {
163 type Item = T;
164
165 #[inline]
166 fn next(&mut self) -> Option<Self::Item> {
167 self.index += 1; self.data.get(self.index - 1)
169 }
170
171 #[inline]
172 fn count(self) -> usize {
173 usize::from(self.data.len().saturating_sub(self.index))
174 }
175}
176
177#[derive(Clone, Copy)]
181pub struct LazyArray32<'a, T> {
182 data: &'a [u8],
183 data_type: core::marker::PhantomData<T>,
184}
185
186impl<'a, T: FromData> LazyArray32<'a, T> {
187 #[inline]
189 pub fn new(data: &'a [u8]) -> Self {
190 LazyArray32 {
191 data,
192 data_type: core::marker::PhantomData,
193 }
194 }
195
196 #[inline]
198 pub fn get(&self, index: u32) -> Option<T> {
199 if index < self.len() {
200 let start = usize::num_from(index) * T::SIZE;
201 let end = start + T::SIZE;
202 self.data.get(start..end).and_then(T::parse)
203 } else {
204 None
205 }
206 }
207
208 #[inline]
210 pub fn len(&self) -> u32 {
211 (self.data.len() / T::SIZE) as u32
212 }
213}
214
215#[derive(Clone, Default, Debug)]
217pub struct Stream<'a> {
218 data: &'a [u8],
219 offset: usize,
220}
221
222impl<'a> Stream<'a> {
223 #[inline]
225 pub fn new(data: &'a [u8]) -> Self {
226 Stream { data, offset: 0 }
227 }
228
229 #[inline]
231 pub fn offset(&self) -> usize {
232 self.offset
233 }
234
235 #[inline]
239 pub fn tail(&self) -> Option<&'a [u8]> {
240 self.data.get(self.offset..)
241 }
242
243 #[inline]
247 pub fn skip<T: FromData>(&mut self) {
248 self.advance(T::SIZE);
249 }
250
251 #[inline]
255 pub fn advance(&mut self, len: usize) {
256 self.offset += len;
257 }
258
259 #[inline]
261 pub fn advance_checked(&mut self, len: usize) -> Option<()> {
262 if self.offset + len <= self.data.len() {
263 self.advance(len);
264 Some(())
265 } else {
266 None
267 }
268 }
269
270 #[inline]
275 pub fn read<T: FromData>(&mut self) -> Option<T> {
276 self.read_bytes(T::SIZE).and_then(T::parse)
277 }
278
279 #[inline]
281 pub fn read_at<T: FromData>(data: &[u8], offset: usize) -> Option<T> {
282 data.get(offset..offset + T::SIZE).and_then(T::parse)
283 }
284
285 #[inline]
287 pub fn read_bytes(&mut self, len: usize) -> Option<&'a [u8]> {
288 debug_assert!(self.offset as u64 + len as u64 <= u32::MAX as u64);
292
293 let v = self.data.get(self.offset..self.offset + len)?;
294 self.advance(len);
295 Some(v)
296 }
297
298 #[inline]
300 pub fn read_array16<T: FromData>(&mut self, count: u16) -> Option<LazyArray16<'a, T>> {
301 let len = usize::from(count) * T::SIZE;
302 self.read_bytes(len).map(LazyArray16::new)
303 }
304
305 #[inline]
307 pub fn read_array32<T: FromData>(&mut self, count: u32) -> Option<LazyArray32<'a, T>> {
308 let len = usize::num_from(count) * T::SIZE;
309 self.read_bytes(len).map(LazyArray32::new)
310 }
311}
312
313pub trait Offset {
315 fn to_usize(&self) -> usize;
317}
318
319#[derive(Clone, Copy, Debug)]
321pub struct Offset16(pub u16);
322
323impl Offset for Offset16 {
324 #[inline]
325 fn to_usize(&self) -> usize {
326 usize::from(self.0)
327 }
328}
329
330impl FromData for Offset16 {
331 const SIZE: usize = 2;
332
333 #[inline]
334 fn parse(data: &[u8]) -> Option<Self> {
335 u16::parse(data).map(Offset16)
336 }
337}
338
339#[derive(Clone, Copy, Debug)]
341pub struct Offset32(pub u32);
342
343impl Offset for Offset32 {
344 #[inline]
345 fn to_usize(&self) -> usize {
346 usize::num_from(self.0)
347 }
348}
349
350impl FromData for Offset32 {
351 const SIZE: usize = 4;
352
353 #[inline]
354 fn parse(data: &[u8]) -> Option<Self> {
355 u32::parse(data).map(Offset32)
356 }
357}