//! Macintosh archived format header utilities. use crate::durandal::bin::*; /// Checks for an AppleSingle header. Returns offset to the resource fork. pub fn check_apple_single(b: &[u8]) -> Option { if b.o_u32b(0)? != 0x51600 || b.o_u32b(4)? != 0x20000 {return None} let num = b.o_u16b(24)? as usize; for i in 0..num { let p = 26 + (12 * i); let fid = b.o_u32b(p )?; let ofs = b.o_u32b(p+4)? as usize; let len = b.o_u32b(p+8)? as usize; if fid == 1 {return if ofs + len > b.len() {None} else {Some(ofs)}} } None } /// Checks for a MacBin header. Returns offset to the resource fork. pub fn check_mac_bin(b: &[u8]) -> Option { if b[0] != 0 || b[1] > 63 || b[74] != 0 || b[123] > 0x81 {return None} let mut crc = 0; for i in 0..124 { for j in 8..16 { let d = b[i] as (u16) << j; if (d ^ crc) & 0x8000 != 0 {crc = crc << 1 ^ 0x1021} else {crc <<= 1} } } if crc == b.o_u16b(124)? {Some(128)} else {None} } /// Reads a MacBin or AppleSingle header if there is one and returns the /// offset from the start of the header to the resource fork (if one is found.) pub fn try_mac_header(b: &[u8]) -> usize { let ofs = check_mac_bin(b).unwrap_or(0); if ofs != 0 {ofs} else {check_apple_single(b).unwrap_or(0)} } // EOF