#[derive(Clone, Copy, Debug)]
pub(crate) enum ByteOrder {
Little,
Big,
}
impl ByteOrder {
pub(crate) const fn u16(self, value: u16) -> [u8; 2] {
match self {
Self::Little => value.to_le_bytes(),
Self::Big => value.to_be_bytes(),
}
}
pub(crate) const fn u32(self, value: u32) -> [u8; 4] {
match self {
Self::Little => value.to_le_bytes(),
Self::Big => value.to_be_bytes(),
}
}
pub(crate) const fn u64(self, value: u64) -> [u8; 8] {
match self {
Self::Little => value.to_le_bytes(),
Self::Big => value.to_be_bytes(),
}
}
}
pub(crate) fn align(output: &mut Vec<u8>, alignment: usize) {
output.resize(output.len().next_multiple_of(alignment), 0);
}
pub(crate) fn write_uint(output: &mut Vec<u8>, value: u64, width: usize, order: ByteOrder) {
let bytes = order.u64(value);
match order {
ByteOrder::Little => output.extend_from_slice(&bytes[..width]),
ByteOrder::Big => output.extend_from_slice(&bytes[8 - width..]),
}
}
pub(crate) fn write_offset(output: &mut Vec<u8>, offset: usize, order: ByteOrder) {
output.extend_from_slice(&order.u64(as_u64(offset)));
}
pub(crate) fn patch_uint(
output: &mut [u8],
offset: usize,
value: u64,
width: usize,
order: ByteOrder,
) {
let bytes = order.u64(value);
let source = match order {
ByteOrder::Little => &bytes[..width],
ByteOrder::Big => &bytes[8 - width..],
};
output[offset..offset + width].copy_from_slice(source);
}
pub(crate) fn as_u64(value: usize) -> u64 {
u64::try_from(value).expect("fixture offsets stay well below u64::MAX")
}