Maraiah/src/marathon/machdr.rs

72 lines
1.6 KiB
Rust

//! 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<usize>
{
// check magic numbers
if b[0..8] != [0, 5, 22, 0, 0, 2, 0, 0] {
return None;
}
// get the resource fork (entity 1)
let num = b.o_u16b(24)? as usize;
for i in 0..num {
let p = 26 + 12 * i;
let ent = b.o_u32b(p)?;
let ofs = b.o_u32b(p + 4)? as usize;
let len = b.o_u32b(p + 8)? as usize;
if ent == 1 {
return if ofs + len > b.len() {None} else {Some(ofs)};
}
}
// no resource fork
None
}
/// Checks for a MacBinary II header. Returns offset to the resource fork.
pub fn check_macbin(b: &[u8]) -> Option<usize>
{
// check legacy version, length, zero fill, and macbin2 version
if b[0] != 0 || b[1] > 63 || b[74] != 0 || b[123] > 129 {
return None;
}
let mut crc = 0;
// check header crc
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 ok, resource fork follows
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
{
if let Some(ofs) = check_macbin(b) {
ofs
} else {
check_apple_single(b).unwrap_or(0)
}
}
// EOF