use crate::bit_writer::BitWriter;
use crate::error::Result;
pub fn write_size(writer: &mut BitWriter, value: u32) -> Result<()> {
if value < (1 << 9) {
writer.write(2, 0)?;
writer.write(9, value as u64)?;
} else if value < (1 << 13) + (1 << 9) {
writer.write(2, 1)?;
writer.write(13, (value - (1 << 9)) as u64)?;
} else if value < (1 << 18) + (1 << 13) + (1 << 9) {
writer.write(2, 2)?;
writer.write(18, (value - (1 << 13) - (1 << 9)) as u64)?;
} else {
writer.write(2, 3)?;
writer.write(30, (value - (1 << 18) - (1 << 13) - (1 << 9)) as u64)?;
}
Ok(())
}
pub fn size_bits(value: u32) -> usize {
if value < (1 << 9) {
2 + 9
} else if value < (1 << 13) + (1 << 9) {
2 + 13
} else if value < (1 << 18) + (1 << 13) + (1 << 9) {
2 + 18
} else {
2 + 30
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_small_sizes() {
for value in [0, 1, 100, 511] {
let mut writer = BitWriter::new();
write_size(&mut writer, value).unwrap();
assert_eq!(writer.bits_written(), 11); assert_eq!(size_bits(value), 11);
}
}
#[test]
fn test_medium_sizes() {
let value = 1000;
let mut writer = BitWriter::new();
write_size(&mut writer, value).unwrap();
assert_eq!(writer.bits_written(), 15); assert_eq!(size_bits(value), 15);
}
#[test]
fn test_large_sizes() {
let value = 10000;
let mut writer = BitWriter::new();
write_size(&mut writer, value).unwrap();
assert_eq!(writer.bits_written(), 20); assert_eq!(size_bits(value), 20);
}
#[test]
fn test_very_large_sizes() {
let value = 300000;
let mut writer = BitWriter::new();
write_size(&mut writer, value).unwrap();
assert_eq!(writer.bits_written(), 32); assert_eq!(size_bits(value), 32);
}
#[test]
fn test_size_boundaries() {
let boundaries = [
(0, 11), (511, 11), (512, 15), ((1 << 13) + (1 << 9) - 1, 15), ((1 << 13) + (1 << 9), 20), ];
for (value, expected_bits) in boundaries {
let mut writer = BitWriter::new();
write_size(&mut writer, value).unwrap();
assert_eq!(
writer.bits_written(),
expected_bits,
"value {} should use {} bits",
value,
expected_bits
);
assert_eq!(size_bits(value), expected_bits);
}
}
}