use super::layout::read_u32_at;
pub const NODE_STRIDE_U32: usize = 10;
pub const SENTINEL: u32 = u32::MAX;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct VastNode {
pub kind: u32,
pub parent_idx: u32,
pub first_child: u32,
pub next_sibling: u32,
pub src_file: u32,
pub src_byte_off: u32,
pub src_byte_len: u32,
pub attr_off: u32,
pub attr_len: u32,
pub reserved: u32,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct VastFile {
pub path_off: u32,
pub path_len: u32,
pub size: u32,
}
impl VastFile {
#[must_use]
pub fn read_row_bytes(file_bytes: &[u8], file_index: u32) -> Option<Self> {
let base = (file_index as usize).checked_mul(3)?;
Some(Self {
path_off: read_u32_at(file_bytes, base)?,
path_len: read_u32_at(file_bytes, base + 1)?,
size: read_u32_at(file_bytes, base + 2)?,
})
}
}
impl VastNode {
#[must_use]
pub fn read_row_bytes(node_bytes: &[u8], node_index: u32) -> Option<Self> {
let base = (node_index as usize).checked_mul(NODE_STRIDE_U32)?;
Some(Self {
kind: read_u32_at(node_bytes, base)?,
parent_idx: read_u32_at(node_bytes, base + 1)?,
first_child: read_u32_at(node_bytes, base + 2)?,
next_sibling: read_u32_at(node_bytes, base + 3)?,
src_file: read_u32_at(node_bytes, base + 4)?,
src_byte_off: read_u32_at(node_bytes, base + 5)?,
src_byte_len: read_u32_at(node_bytes, base + 6)?,
attr_off: read_u32_at(node_bytes, base + 7)?,
attr_len: read_u32_at(node_bytes, base + 8)?,
reserved: read_u32_at(node_bytes, base + 9)?,
})
}
#[must_use]
pub fn to_bytes(self) -> [u8; NODE_STRIDE_U32 * 4] {
let mut out = [0u8; NODE_STRIDE_U32 * 4];
let w = [
self.kind,
self.parent_idx,
self.first_child,
self.next_sibling,
self.src_file,
self.src_byte_off,
self.src_byte_len,
self.attr_off,
self.attr_len,
self.reserved,
];
for (i, word) in w.iter().enumerate() {
out[i * 4..(i + 1) * 4].copy_from_slice(&word.to_le_bytes());
}
out
}
}