web engine - experimental web browser
1//! Binary parsing utilities for reading big-endian font data.
2
3use super::FontError;
4
5/// A zero-copy reader over a byte slice, for big-endian binary parsing.
6pub struct Reader<'a> {
7 data: &'a [u8],
8}
9
10impl<'a> Reader<'a> {
11 pub fn new(data: &'a [u8]) -> Self {
12 Reader { data }
13 }
14
15 pub fn len(&self) -> usize {
16 self.data.len()
17 }
18
19 fn check(&self, offset: usize, size: usize) -> Result<(), FontError> {
20 if offset + size > self.data.len() {
21 Err(FontError::UnexpectedEof)
22 } else {
23 Ok(())
24 }
25 }
26
27 pub fn u16(&self, offset: usize) -> Result<u16, FontError> {
28 self.check(offset, 2)?;
29 Ok(u16::from_be_bytes([
30 self.data[offset],
31 self.data[offset + 1],
32 ]))
33 }
34
35 pub fn i16(&self, offset: usize) -> Result<i16, FontError> {
36 self.check(offset, 2)?;
37 Ok(i16::from_be_bytes([
38 self.data[offset],
39 self.data[offset + 1],
40 ]))
41 }
42
43 pub fn u32(&self, offset: usize) -> Result<u32, FontError> {
44 self.check(offset, 4)?;
45 Ok(u32::from_be_bytes([
46 self.data[offset],
47 self.data[offset + 1],
48 self.data[offset + 2],
49 self.data[offset + 3],
50 ]))
51 }
52
53 pub fn i32(&self, offset: usize) -> Result<i32, FontError> {
54 self.check(offset, 4)?;
55 Ok(i32::from_be_bytes([
56 self.data[offset],
57 self.data[offset + 1],
58 self.data[offset + 2],
59 self.data[offset + 3],
60 ]))
61 }
62
63 /// Read a 4-byte tag (e.g., table tags like b"head").
64 pub fn tag(&self, offset: usize) -> Result<[u8; 4], FontError> {
65 self.check(offset, 4)?;
66 Ok([
67 self.data[offset],
68 self.data[offset + 1],
69 self.data[offset + 2],
70 self.data[offset + 3],
71 ])
72 }
73
74 /// Get a sub-slice of the data.
75 pub fn slice(&self, offset: usize, len: usize) -> Result<&'a [u8], FontError> {
76 self.check(offset, len)?;
77 Ok(&self.data[offset..offset + len])
78 }
79}