use core::mem::size_of;
use super::Component;
pub(crate) struct Representation;
impl Representation {
pub fn component_count(buf: &[u8]) -> usize {
Self::usize_at_offset(buf, 0)
}
pub fn total_length(buf: &[u8], component_count: usize) -> usize {
match component_count.checked_sub(1) {
None => 0,
Some(i) => Self::sum_of_lengths_for_component(buf, i),
}
}
#[allow(dead_code)] pub fn component_len(buf: &[u8], i: usize) -> usize {
if i == 0 {
Self::sum_of_lengths_for_component(buf, i)
} else {
Self::sum_of_lengths_for_component(buf, i)
- Self::sum_of_lengths_for_component(buf, i - 1)
}
}
pub fn component<const MCL: usize>(buf: &[u8], i: usize) -> &Component<MCL> {
let start = Self::start_offset_of_component(buf, i);
let end = Self::end_offset_of_component(buf, i);
Component::new(&buf[start..end]).unwrap()
}
pub fn sum_of_lengths_for_component(buf: &[u8], i: usize) -> usize {
let start_offset_in_bytes = Self::start_offset_of_sum_of_lengths_for_component(i);
Self::usize_at_offset(buf, start_offset_in_bytes)
}
pub fn allocation_size(total_length: usize, component_count: usize) -> usize {
total_length + ((component_count + 1) * size_of::<usize>())
}
pub fn start_offset_of_sum_of_lengths_for_component(i: usize) -> usize {
size_of::<usize>() * (i + 1)
}
pub fn start_offset_of_component(buf: &[u8], i: usize) -> usize {
let metadata_length = (Self::component_count(buf) + 1) * size_of::<usize>();
if i == 0 {
metadata_length
} else {
Self::sum_of_lengths_for_component(buf, i - 1) + metadata_length
}
}
pub fn end_offset_of_component(buf: &[u8], i: usize) -> usize {
let metadata_length = (Self::component_count(buf) + 1) * size_of::<usize>();
Self::sum_of_lengths_for_component(buf, i) + metadata_length
}
fn usize_at_offset(buf: &[u8], offset_in_bytes: usize) -> usize {
let end = offset_in_bytes + size_of::<usize>();
let mut usize_bytes = [0u8; size_of::<usize>()];
if buf.len() < end {
panic!();
} else {
usize_bytes.copy_from_slice(&buf[offset_in_bytes..end]);
usize::from_ne_bytes(usize_bytes)
}
}
}