use std::mem;
pub const HEADER_SIGNATURE: [u8; 8] = *b"LPKSHHRH";
pub const DEFAULT_DATA_HASH_TABLE_SIZE: usize = 2047;
pub const DEFAULT_FIELD_HASH_TABLE_SIZE: usize = 1023;
pub const HEADER_SIZE: u64 = 272;
pub const HEADER_SIZE_MIN: u64 = 232;
pub const ALIGN: u64 = 8;
#[repr(u8)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum FileState {
Offline = 0,
Online = 1,
Archived = 2,
}
pub mod compat {
pub const SEALED: u32 = 1 << 0;
pub const TAIL_ENTRY_BOOT_ID: u32 = 1 << 1;
pub const SEALED_CONTINUOUS: u32 = 1 << 2;
}
pub mod incompat {
pub const COMPRESSED_XZ: u32 = 1 << 0;
pub const COMPRESSED_LZ4: u32 = 1 << 1;
pub const KEYED_HASH: u32 = 1 << 2;
pub const COMPRESSED_ZSTD: u32 = 1 << 3;
pub const COMPACT: u32 = 1 << 4;
pub const SUPPORTED_WRITE: u32 = KEYED_HASH | COMPACT;
pub const SUPPORTED_READ: u32 = COMPRESSED_XZ | COMPRESSED_LZ4 | COMPRESSED_ZSTD | KEYED_HASH | COMPACT;
}
#[repr(u8)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ObjectType {
Unused = 0,
Data = 1,
Field = 2,
Entry = 3,
DataHashTable = 4,
FieldHashTable = 5,
EntryArray = 6,
Tag = 7,
}
impl TryFrom<u8> for ObjectType {
type Error = u8;
fn try_from(v: u8) -> std::result::Result<Self, Self::Error> {
match v {
0 => Ok(Self::Unused),
1 => Ok(Self::Data),
2 => Ok(Self::Field),
3 => Ok(Self::Entry),
4 => Ok(Self::DataHashTable),
5 => Ok(Self::FieldHashTable),
6 => Ok(Self::EntryArray),
7 => Ok(Self::Tag),
x => Err(x),
}
}
}
pub mod obj_flags {
pub const COMPRESSED_XZ: u8 = 1 << 0;
pub const COMPRESSED_LZ4: u8 = 1 << 1;
pub const COMPRESSED_ZSTD: u8 = 1 << 2;
pub const COMPRESSED_MASK: u8 = COMPRESSED_XZ | COMPRESSED_LZ4 | COMPRESSED_ZSTD;
}
#[repr(C, packed)]
#[derive(Debug, Clone, Copy)]
pub struct ObjectHeader {
pub object_type: u8,
pub flags: u8,
pub reserved: [u8; 6],
pub size: [u8; 8], }
pub const OBJECT_HEADER_SIZE: usize = mem::size_of::<ObjectHeader>();
impl ObjectHeader {
pub fn size_le(&self) -> u64 {
u64::from_le_bytes(self.size)
}
}
#[repr(C, packed)]
#[derive(Debug, Clone, Copy, Default)]
pub struct HashItem {
pub head_hash_offset: [u8; 8], pub tail_hash_offset: [u8; 8], }
pub const HASH_ITEM_SIZE: usize = mem::size_of::<HashItem>();
#[repr(C, packed)]
#[derive(Debug, Clone, Copy)]
pub struct DataObjectHeader {
pub object: ObjectHeader,
pub hash: [u8; 8],
pub next_hash_offset: [u8; 8],
pub next_field_offset: [u8; 8],
pub entry_offset: [u8; 8],
pub entry_array_offset: [u8; 8],
pub n_entries: [u8; 8],
}
pub const DATA_OBJECT_HEADER_SIZE: usize = mem::size_of::<DataObjectHeader>();
#[repr(C, packed)]
#[derive(Debug, Clone, Copy)]
pub struct FieldObjectHeader {
pub object: ObjectHeader,
pub hash: [u8; 8],
pub next_hash_offset: [u8; 8],
pub head_data_offset: [u8; 8],
}
pub const FIELD_OBJECT_HEADER_SIZE: usize = mem::size_of::<FieldObjectHeader>();
#[repr(C, packed)]
#[derive(Debug, Clone, Copy, Default)]
pub struct EntryItem {
pub object_offset: [u8; 8], pub hash: [u8; 8], }
pub const ENTRY_ITEM_SIZE: usize = mem::size_of::<EntryItem>();
#[repr(C, packed)]
#[derive(Debug, Clone, Copy)]
pub struct EntryObjectHeader {
pub object: ObjectHeader,
pub seqnum: [u8; 8],
pub realtime: [u8; 8],
pub monotonic: [u8; 8],
pub boot_id: [u8; 16],
pub xor_hash: [u8; 8],
}
pub const ENTRY_OBJECT_HEADER_SIZE: usize = mem::size_of::<EntryObjectHeader>();
#[repr(C, packed)]
#[derive(Debug, Clone, Copy)]
pub struct EntryArrayObjectHeader {
pub object: ObjectHeader,
pub next_entry_array_offset: [u8; 8],
}
pub const ENTRY_ARRAY_OBJECT_HEADER_SIZE: usize = mem::size_of::<EntryArrayObjectHeader>();
#[repr(C, packed)]
#[derive(Debug, Clone, Copy)]
pub struct Header {
pub signature: [u8; 8], pub compatible_flags: [u8; 4], pub incompatible_flags: [u8; 4], pub state: u8,
pub reserved: [u8; 7],
pub file_id: [u8; 16], pub machine_id: [u8; 16], pub tail_entry_boot_id: [u8; 16], pub seqnum_id: [u8; 16], pub header_size: [u8; 8], pub arena_size: [u8; 8], pub data_hash_table_offset: [u8; 8], pub data_hash_table_size: [u8; 8], pub field_hash_table_offset: [u8; 8], pub field_hash_table_size: [u8; 8], pub tail_object_offset: [u8; 8], pub n_objects: [u8; 8], pub n_entries: [u8; 8], pub tail_entry_seqnum: [u8; 8], pub head_entry_seqnum: [u8; 8], pub entry_array_offset: [u8; 8], pub head_entry_realtime: [u8; 8], pub tail_entry_realtime: [u8; 8], pub tail_entry_monotonic: [u8; 8], pub n_data: [u8; 8], pub n_fields: [u8; 8], pub n_tags: [u8; 8], pub n_entry_arrays: [u8; 8], pub data_hash_chain_depth: [u8; 8], pub field_hash_chain_depth: [u8; 8], pub tail_entry_array_offset: [u8; 4], pub tail_entry_array_n_entries: [u8; 4], pub tail_entry_offset: [u8; 8], }
const _: () = assert!(mem::size_of::<Header>() == 272);
#[inline]
pub fn align64(x: u64) -> u64 {
(x + 7) & !7
}
#[inline]
pub fn valid64(x: u64) -> bool {
x & 7 == 0
}
#[inline]
pub fn le64(v: u64) -> [u8; 8] {
v.to_le_bytes()
}
#[inline]
pub fn from_le64(b: &[u8; 8]) -> u64 {
u64::from_le_bytes(*b)
}
#[inline]
pub fn le32(v: u32) -> [u8; 4] {
v.to_le_bytes()
}
#[inline]
pub fn from_le32(b: &[u8; 4]) -> u32 {
u32::from_le_bytes(*b)
}