use crate::parser::read_u8;
use crate::Error;
#[derive(Debug, Clone, Copy)]
pub(crate) struct CffHeader {
pub(crate) size: u8,
#[allow(dead_code)]
pub(crate) off_size: u8,
}
impl CffHeader {
pub(crate) fn parse(bytes: &[u8]) -> Result<Self, Error> {
let major = read_u8(bytes, 0)?;
let _minor = read_u8(bytes, 1)?;
let size = read_u8(bytes, 2)?;
let off_size = read_u8(bytes, 3)?;
if major != 1 {
return Err(Error::Cff("unsupported CFF major version"));
}
if size < 4 {
return Err(Error::Cff("hdrSize < 4"));
}
if !(1..=4).contains(&off_size) {
return Err(Error::Cff("offSize out of range"));
}
if (size as usize) > bytes.len() {
return Err(Error::UnexpectedEof);
}
Ok(Self { size, off_size })
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn parses_minimal_header() {
let bytes = [1u8, 0, 4, 2];
let h = CffHeader::parse(&bytes).expect("parse");
assert_eq!(h.size, 4);
assert_eq!(h.off_size, 2);
}
#[test]
fn rejects_cff2_major() {
let bytes = [2u8, 0, 5, 2];
assert!(matches!(
CffHeader::parse(&bytes),
Err(Error::Cff("unsupported CFF major version"))
));
}
#[test]
fn rejects_short_header() {
let bytes = [1u8, 0, 8, 1];
assert!(matches!(
CffHeader::parse(&bytes),
Err(Error::UnexpectedEof)
));
}
}