54 lines
1.3 KiB
Rust
54 lines
1.3 KiB
Rust
//! 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
|