pub const OBJ_PHYS_LEN: usize = 32;
#[must_use]
pub fn fletcher64_stored(block: &[u8]) -> u64 {
crate::bytes::le_u64(block, 0)
}
#[derive(Debug, Clone, Copy)]
#[non_exhaustive]
pub struct ObjPhys {
pub cksum: u64,
pub oid: u64,
pub xid: u64,
pub obj_type_raw: u32,
pub subtype: u32,
}
impl ObjPhys {
#[must_use]
pub fn parse(block: &[u8]) -> Option<Self> {
if block.len() < OBJ_PHYS_LEN {
return None;
}
Some(Self {
cksum: crate::bytes::le_u64(block, 0),
oid: crate::bytes::le_u64(block, 8),
xid: crate::bytes::le_u64(block, 16),
obj_type_raw: crate::bytes::le_u32(block, 24),
subtype: crate::bytes::le_u32(block, 28),
})
}
#[must_use]
pub fn obj_type(&self) -> u16 {
(self.obj_type_raw & 0x0000_ffff) as u16
}
}
#[must_use]
pub fn fletcher64_checksum(block: &[u8]) -> u64 {
const MOD: u64 = 0xffff_ffff;
let mut sum_lo: u64 = 0;
let mut sum_hi: u64 = 0;
for (i, word) in block.chunks_exact(4).enumerate() {
let v = if i < 2 {
0 } else {
u64::from(u32::from_le_bytes([word[0], word[1], word[2], word[3]]))
};
sum_lo = (sum_lo + v) % MOD;
sum_hi = (sum_hi + sum_lo) % MOD;
}
let check_lo = MOD - ((sum_lo + sum_hi) % MOD);
let check_hi = MOD - ((sum_lo + check_lo) % MOD);
(check_hi << 32) | check_lo
}