use crate::error::EseError;
pub const DB_STATE_JUST_CREATED: u32 = 1;
pub const DB_STATE_DIRTY_SHUTDOWN: u32 = 2;
pub const DB_STATE_CLEAN_SHUTDOWN: u32 = 3;
#[derive(Debug, Clone)]
pub struct EseHeader {
pub signature: u32,
pub format_version: u32,
pub page_size: u32,
pub db_time: u64,
pub db_state: u32,
}
impl EseHeader {
pub const SIZE: usize = 4096;
pub fn from_bytes(data: &[u8]) -> Result<Self, EseError> {
if data.len() < Self::SIZE {
return Err(EseError::Corrupt {
page: 0,
detail: format!(
"file too short: need {} bytes, got {}",
Self::SIZE,
data.len()
),
});
}
let sig = u32::from_le_bytes([data[4], data[5], data[6], data[7]]);
if sig != 0x89AB_CDEF {
return Err(EseError::InvalidMagic {
page: 0,
found: sig,
});
}
let format_version = u32::from_le_bytes([data[8], data[9], data[10], data[11]]);
let db_time = u64::from_le_bytes([
data[0x10], data[0x11], data[0x12], data[0x13], data[0x14], data[0x15], data[0x16],
data[0x17],
]);
let db_state = u32::from_le_bytes([data[0x28], data[0x29], data[0x2A], data[0x2B]]);
let raw_page_size = u32::from_le_bytes([data[236], data[237], data[238], data[239]]);
let page_size = if raw_page_size == 0 {
4096
} else {
raw_page_size
};
const VALID_PAGE_SIZES: [u32; 4] = [4096, 8192, 16384, 32768];
if !VALID_PAGE_SIZES.contains(&page_size) {
return Err(EseError::Corrupt {
page: 0,
detail: format!(
"invalid page_size {page_size}: must be one of 4096, 8192, 16384, 32768"
),
});
}
Ok(EseHeader {
signature: sig,
format_version,
page_size,
db_time,
db_state,
})
}
}