//! Macintosh archived format header utilities. use durandal::bin::*; /// Checks for an AppleSingle header. Returns offset to the resource fork. pub fn check_apple_single(b: &[u8]) -> usize { if b_u32b(&b[0..4]) != 0x51600 || b_u32b(&b[4..8]) != 0x20000 {return 0} let num = b_u16b(&b[24..26]) as usize; for i in 0..num { let p = 26 + (12 * i); let fid = b_u32b(&b[p+0..p+ 4]); let ofs = b_u32b(&b[p+4..p+ 8]) as usize; let len = b_u32b(&b[p+8..p+12]) as usize; if fid == 1 {return if ofs + len > b.len() {0} else {ofs}} } 0 } /// Checks for a MacBin header. Returns offset to the resource fork. pub fn check_mac_bin(b: &[u8]) -> usize { if b[0] != 0 || b[1] > 63 || b[74] != 0 || b[123] > 0x81 {return 0} 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_u16b(&b[124..126]) {128} else {0} } /// 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); if ofs != 0 {ofs} else {check_apple_single(b)} } // EOF