#[inline]
pub(super) fn low_mask_u8(n: usize) -> u8 {
if n >= 8 { 0xFF } else { (1u8 << n) - 1 }
}
#[inline]
pub(super) fn low_mask_u64(n: usize) -> u64 {
if n >= 64 { u64::MAX } else { (1u64 << n) - 1 }
}
#[inline]
pub(super) fn pack_bits(packed: &mut [u8], bit_offset: usize, value: u64, bit_width: u8) {
let bw = bit_width as usize;
if bw == 0 {
return;
}
let byte_idx = bit_offset / 8;
let bit_idx = bit_offset % 8;
let first_bits = (8 - bit_idx).min(bw);
packed[byte_idx] |= ((value & low_mask_u64(first_bits)) as u8) << bit_idx;
let mut remaining = bw - first_bits;
let mut val = value >> first_bits;
let mut bi = byte_idx + 1;
while remaining >= 8 {
packed[bi] = (val & 0xFF) as u8;
val >>= 8;
remaining -= 8;
bi += 1;
}
if remaining > 0 {
packed[bi] |= (val & low_mask_u64(remaining)) as u8;
}
}
#[inline]
pub(super) fn unpack_bits(packed: &[u8], bit_offset: usize, bit_width: u8) -> u64 {
let bw = bit_width as usize;
if bw == 0 {
return 0;
}
let byte_idx = bit_offset / 8;
let bit_idx = bit_offset % 8;
let first_bits = (8 - bit_idx).min(bw);
let mut value = ((packed[byte_idx] >> bit_idx) & low_mask_u8(first_bits)) as u64;
let mut collected = first_bits;
let mut bi = byte_idx + 1;
while collected + 8 <= bw {
value |= (packed[bi] as u64) << collected;
collected += 8;
bi += 1;
}
let remaining = bw - collected;
if remaining > 0 {
value |= ((packed[bi] & low_mask_u8(remaining)) as u64) << collected;
}
value
}