//! Binary parsing utilities for reading big-endian font data. use super::FontError; /// A zero-copy reader over a byte slice, for big-endian binary parsing. pub struct Reader<'a> { data: &'a [u8], } impl<'a> Reader<'a> { pub fn new(data: &'a [u8]) -> Self { Reader { data } } pub fn len(&self) -> usize { self.data.len() } fn check(&self, offset: usize, size: usize) -> Result<(), FontError> { if offset + size > self.data.len() { Err(FontError::UnexpectedEof) } else { Ok(()) } } pub fn u16(&self, offset: usize) -> Result { self.check(offset, 2)?; Ok(u16::from_be_bytes([ self.data[offset], self.data[offset + 1], ])) } pub fn i16(&self, offset: usize) -> Result { self.check(offset, 2)?; Ok(i16::from_be_bytes([ self.data[offset], self.data[offset + 1], ])) } pub fn u32(&self, offset: usize) -> Result { self.check(offset, 4)?; Ok(u32::from_be_bytes([ self.data[offset], self.data[offset + 1], self.data[offset + 2], self.data[offset + 3], ])) } pub fn i32(&self, offset: usize) -> Result { self.check(offset, 4)?; Ok(i32::from_be_bytes([ self.data[offset], self.data[offset + 1], self.data[offset + 2], self.data[offset + 3], ])) } /// Read a 4-byte tag (e.g., table tags like b"head"). pub fn tag(&self, offset: usize) -> Result<[u8; 4], FontError> { self.check(offset, 4)?; Ok([ self.data[offset], self.data[offset + 1], self.data[offset + 2], self.data[offset + 3], ]) } /// Get a sub-slice of the data. pub fn slice(&self, offset: usize, len: usize) -> Result<&'a [u8], FontError> { self.check(offset, len)?; Ok(&self.data[offset..offset + len]) } }