pub fn xor_checksum(data: &[u8]) -> u64 {
const SEED: u64 = 0x5A5A5A5A5A5A5A5A;
let mut checksum = SEED;
for (i, &byte) in data.iter().enumerate() {
checksum ^= (byte as u64) ^ (i as u64);
}
checksum
}
#[repr(C)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct FreePageHeader {
pub next_free: u64,
pub checksum: u64,
}
impl FreePageHeader {
pub const SIZE: usize = 16;
pub fn new(next_free: u64) -> Self {
Self {
next_free,
checksum: 0,
}
}
pub fn to_bytes(&self) -> [u8; Self::SIZE] {
let mut bytes = [0u8; Self::SIZE];
bytes[0..8].copy_from_slice(&self.next_free.to_le_bytes());
bytes[8..16].copy_from_slice(&self.checksum.to_le_bytes());
bytes
}
pub fn from_bytes(bytes: &[u8]) -> Option<Self> {
if bytes.len() < Self::SIZE {
return None;
}
let next_free = u64::from_le_bytes(bytes[0..8].try_into().ok()?);
let checksum = u64::from_le_bytes(bytes[8..16].try_into().ok()?);
Some(Self {
next_free,
checksum,
})
}
pub fn calculate_checksum(&self) -> u64 {
xor_checksum(&self.next_free.to_le_bytes())
}
}