use binrw::binread;
use bitflags::bitflags;
use macintosh_utils::{
FourCC, Point,
chrono::{DateTime, Utc},
decode_string,
};
use std::cmp::min;
bitflags! {
#[derive(Debug, Clone)]
pub struct Flags: u8 {
const LOCKED = 1<<0;
}
}
#[binread]
#[derive(Debug)]
#[br(big)]
pub struct Header {
pub version: u8,
#[br(temp,assert(name_len > 0 && name_len < 63))]
name_len: u8,
#[br(map(|r: [u8; 63]| decode_string(r[0..min(name_len as usize, 63)].to_vec())))]
pub name: String,
pub type_code: FourCC,
pub creator_code: FourCC,
pub finder_flags_upper: u8,
#[br(temp, assert(zero==0))]
zero: u8,
pub position: Point,
pub window_id: u16,
#[br(map(Flags::from_bits_retain))]
pub flags: Flags,
#[br(temp, assert(zero_again==0))]
zero_again: u8,
pub data_fork_len: u32,
pub resource_fork_len: u32,
#[br(map(macintosh_utils::date))]
pub created_at: DateTime<Utc>,
#[br(map(macintosh_utils::date))]
pub modified_at: DateTime<Utc>,
pub comment_len: u16,
pub finder_flags_lower: u8,
pub magic: FourCC,
pub file_name_script: u8,
pub extended_finder_flags: u8,
#[br(temp)]
_reserved_2: [u8; 8],
pub unpacked_total_len: u32,
pub extended_header_len: u16,
pub uploader_version: u8,
pub downloader_min_version: u8,
pub checksum: u16,
#[br(temp)]
_reserved_3: u16,
}
impl Header {
pub const FIXED_SIZE: usize = 128;
fn extended_header_location(&self) -> u64 {
Header::FIXED_SIZE as u64
}
pub fn data_fork_location(&self) -> u64 {
self.extended_header_location() + align_128(self.extended_header_len as u64)
}
pub fn resource_fork_location(&self) -> u64 {
self.data_fork_location() + align_128(self.data_fork_len as u64)
}
pub fn file_comment_location(&self) -> u64 {
self.resource_fork_location() + align_128(self.resource_fork_len as u64)
}
}
fn align_128(input: u64) -> u64 {
if (0x80 - 1) & input != 0 {
(input + 0x80) & !(0x80 - 1)
} else {
input
}
}
#[cfg(test)]
mod test {
use super::align_128;
#[test]
fn align_int() {
assert_eq!(align_128(0), 0);
assert_eq!(align_128(1), 128);
assert_eq!(align_128(127), 128);
assert_eq!(align_128(128), 128);
assert_eq!(align_128(129), 256);
}
}