#[derive(Debug, Clone, Copy)]
pub struct ObjPhys {
pub cksum: u64,
pub oid: u64,
pub xid: u64,
pub type_and_flags: u32,
pub subtype: u32,
}
impl ObjPhys {
pub const SIZE: usize = 32;
pub fn decode(buf: &[u8]) -> crate::Result<Self> {
if buf.len() < Self::SIZE {
return Err(crate::Error::InvalidImage(
"apfs: obj_phys_t buffer too short".into(),
));
}
Ok(Self {
cksum: u64::from_le_bytes(buf[0..8].try_into().unwrap()),
oid: u64::from_le_bytes(buf[8..16].try_into().unwrap()),
xid: u64::from_le_bytes(buf[16..24].try_into().unwrap()),
type_and_flags: u32::from_le_bytes(buf[24..28].try_into().unwrap()),
subtype: u32::from_le_bytes(buf[28..32].try_into().unwrap()),
})
}
pub fn obj_type(&self) -> u32 {
self.type_and_flags & OBJECT_TYPE_MASK
}
pub fn obj_flags(&self) -> u32 {
self.type_and_flags & OBJECT_TYPE_FLAGS_MASK
}
}
pub const OBJECT_TYPE_MASK: u32 = 0x0000_ffff;
pub const OBJECT_TYPE_FLAGS_MASK: u32 = 0xffff_0000;
pub const OBJECT_TYPE_NX_SUPERBLOCK: u32 = 0x0000_0001;
pub const OBJECT_TYPE_BTREE: u32 = 0x0000_0002;
pub const OBJECT_TYPE_BTREE_NODE: u32 = 0x0000_0003;
pub const OBJECT_TYPE_OMAP: u32 = 0x0000_000b;
pub const OBJECT_TYPE_CHECKPOINT_MAP: u32 = 0x0000_000c;
pub const OBJECT_TYPE_FS: u32 = 0x0000_000d;
pub const OBJECT_TYPE_FSTREE: u32 = 0x0000_000e;
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn decode_simple_obj_phys() {
let mut buf = [0u8; 32];
buf[0..8].copy_from_slice(&0x1122_3344_5566_7788u64.to_le_bytes());
buf[8..16].copy_from_slice(&0x42u64.to_le_bytes());
buf[16..24].copy_from_slice(&0xa5u64.to_le_bytes());
buf[24..28].copy_from_slice(&(OBJECT_TYPE_NX_SUPERBLOCK | 0x8000_0000).to_le_bytes());
buf[28..32].copy_from_slice(&7u32.to_le_bytes());
let o = ObjPhys::decode(&buf).unwrap();
assert_eq!(o.cksum, 0x1122_3344_5566_7788);
assert_eq!(o.oid, 0x42);
assert_eq!(o.xid, 0xa5);
assert_eq!(o.obj_type(), OBJECT_TYPE_NX_SUPERBLOCK);
assert_eq!(o.obj_flags(), 0x8000_0000);
assert_eq!(o.subtype, 7);
}
#[test]
fn decode_rejects_short_buffer() {
let buf = [0u8; 16];
assert!(ObjPhys::decode(&buf).is_err());
}
}