dsi-bitstream 0.9.2

A Rust implementation of read/write bit streams supporting several types of instantaneous codes
Documentation
/*
 * SPDX-FileCopyrightText: 2023 Tommaso Fontana
 * SPDX-FileCopyrightText: 2023 Inria
 * SPDX-FileCopyrightText: 2023 Sebastiano Vigna
 *
 * SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later
 */

#![cfg(feature = "alloc")]

use core::error::Error;
use dsi_bitstream::prelude::*;

macro_rules! test_code {
    ($call_be:expr, $expected_be:expr, $call_le:expr, $expected_le:expr,) => {
        let mut data = vec![0_u64];
        let mut writer = <BufBitWriter<BE, _>>::new(MemWordWriterVec::new(&mut data));
        $call_be(&mut writer)?;
        drop(writer);
        assert_eq!(
            data[0].to_be(),
            $expected_be as u64,
            "\ngot: {:064b}\nexp: {:064b}\n",
            data[0].to_be(),
            $expected_be as u64,
        );

        let mut data = vec![0_u64];
        let mut writer = <BufBitWriter<LE, _>>::new(MemWordWriterVec::new(&mut data));
        $call_le(&mut writer)?;
        drop(writer);
        assert_eq!(
            data[0], $expected_le as u64,
            "\ngot: {:064b}\nexp: {:064b}\n",
            data[0], $expected_le as u64,
        );
    };
}

type Backend<'a, E> = BufBitWriter<E, MemWordWriterVec<u64, &'a mut Vec<u64>>>;

#[test]
fn test_unary() -> Result<(), Box<dyn Error + Send + Sync + 'static>> {
    for i in 0..63 {
        test_code!(
            |b: &mut Backend<BE>| b.write_unary(i),
            (1_u64 << (63 - i)),
            |b: &mut Backend<LE>| b.write_unary(i),
            (1_u64 << i),
        );
    }

    Ok(())
}

#[test]
fn test_gamma() -> Result<(), Box<dyn Error + Send + Sync + 'static>> {
    test_code!(
        |b: &mut Backend<BE>| b.write_gamma(0),
        0b1_000000000000000000000000000000000000000000000000000000000000000,
        |b: &mut Backend<LE>| b.write_gamma(0),
        0b0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0001,
    );
    test_code!(
        |b: &mut Backend<BE>| b.write_gamma(1),
        0b01_00000000000000000000000000000000000000000000000000000000000000,
        |b: &mut Backend<LE>| b.write_gamma(1),
        0b0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0010,
    );
    test_code!(
        |b: &mut Backend<BE>| b.write_gamma(2),
        0b011_0000000000000000000000000000000000000000000000000000000000000,
        |b: &mut Backend<LE>| b.write_gamma(2),
        0b0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0110,
    );
    test_code!(
        |b: &mut Backend<BE>| b.write_gamma(3),
        0b00100_00000000000000000000000000000000000000000000000000000000000,
        |b: &mut Backend<LE>| b.write_gamma(3),
        0b0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0100,
    );
    test_code!(
        |b: &mut Backend<BE>| b.write_gamma(4),
        0b00101_00000000000000000000000000000000000000000000000000000000000,
        |b: &mut Backend<LE>| b.write_gamma(4),
        0b0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_1100,
    );
    test_code!(
        |b: &mut Backend<BE>| b.write_gamma(5),
        0b00110_00000000000000000000000000000000000000000000000000000000000,
        |b: &mut Backend<LE>| b.write_gamma(5),
        0b0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0001_0100,
    );
    test_code!(
        |b: &mut Backend<BE>| b.write_gamma(6),
        0b00111_00000000000000000000000000000000000000000000000000000000000,
        |b: &mut Backend<LE>| b.write_gamma(6),
        0b0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0001_1100,
    );
    test_code!(
        |b: &mut Backend<BE>| b.write_gamma(7),
        0b0001000_000000000000000000000000000000000000000000000000000000000,
        |b: &mut Backend<LE>| b.write_gamma(7),
        0b0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_1000,
    );
    test_code!(
        |b: &mut Backend<BE>| b.write_gamma(8),
        0b0001001_000000000000000000000000000000000000000000000000000000000,
        |b: &mut Backend<LE>| b.write_gamma(8),
        0b0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0001_1000,
    );
    test_code!(
        |b: &mut Backend<BE>| b.write_gamma(9),
        0b0001010_000000000000000000000000000000000000000000000000000000000,
        |b: &mut Backend<LE>| b.write_gamma(9),
        0b0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0010_1000,
    );
    test_code!(
        |b: &mut Backend<BE>| b.write_gamma(10),
        0b0001011_000000000000000000000000000000000000000000000000000000000,
        |b: &mut Backend<LE>| b.write_gamma(10),
        0b0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0011_1000,
    );

    Ok(())
}

#[test]
fn test_delta() -> Result<(), Box<dyn Error + Send + Sync + 'static>> {
    test_code!(
        |b: &mut Backend<BE>| b.write_delta(0),
        0b1_000000000000000000000000000000000000000000000000000000000000000,
        |b: &mut Backend<LE>| b.write_delta(0),
        0b0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0001,
    );
    test_code!(
        |b: &mut Backend<BE>| b.write_delta(1),
        0b0100_000000000000000000000000000000000000000000000000000000000000,
        |b: &mut Backend<LE>| b.write_delta(1),
        0b0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0010,
    );
    test_code!(
        |b: &mut Backend<BE>| b.write_delta(2),
        0b0101_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000,
        |b: &mut Backend<LE>| b.write_delta(2),
        0b0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_1010,
    );
    test_code!(
        |b: &mut Backend<BE>| b.write_delta(3),
        0b0110_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000,
        |b: &mut Backend<LE>| b.write_delta(3),
        0b0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0110,
    );
    test_code!(
        |b: &mut Backend<BE>| b.write_delta(4),
        0b0110_1000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000,
        |b: &mut Backend<LE>| b.write_delta(4),
        0b0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_1110,
    );
    test_code!(
        |b: &mut Backend<BE>| b.write_delta(5),
        0b0111_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000,
        |b: &mut Backend<LE>| b.write_delta(5),
        0b0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0001_0110,
    );
    test_code!(
        |b: &mut Backend<BE>| b.write_delta(6),
        0b0111_1000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000,
        |b: &mut Backend<LE>| b.write_delta(6),
        0b0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0001_1110,
    );
    test_code!(
        |b: &mut Backend<BE>| b.write_delta(7),
        0b0010_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000,
        |b: &mut Backend<LE>| b.write_delta(7),
        0b0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0100,
    );
    test_code!(
        |b: &mut Backend<BE>| b.write_delta(8),
        0b0010_0001_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000,
        |b: &mut Backend<LE>| b.write_delta(8),
        0b0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0010_0100,
    );
    test_code!(
        |b: &mut Backend<BE>| b.write_delta(9),
        0b0010_0010_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000,
        |b: &mut Backend<LE>| b.write_delta(9),
        0b0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0100_0100,
    );
    test_code!(
        |b: &mut Backend<BE>| b.write_delta(10),
        0b0010_0011_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000,
        |b: &mut Backend<LE>| b.write_delta(10),
        0b0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0110_0100,
    );

    Ok(())
}

#[test]
fn test_zeta3() -> Result<(), Box<dyn Error + Send + Sync + 'static>> {
    test_code!(
        |b: &mut Backend<BE>| b.write_zeta3(0),
        0b1000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000,
        |b: &mut Backend<LE>| b.write_zeta3(0),
        0b0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0001,
    );
    test_code!(
        |b: &mut Backend<BE>| b.write_zeta3(1),
        0b1010_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000,
        |b: &mut Backend<LE>| b.write_zeta3(1),
        0b0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0011,
    );
    test_code!(
        |b: &mut Backend<BE>| b.write_zeta3(2),
        0b1011_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000,
        |b: &mut Backend<LE>| b.write_zeta3(2),
        0b0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_1011,
    );
    test_code!(
        |b: &mut Backend<BE>| b.write_zeta3(3),
        0b1100_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000,
        |b: &mut Backend<LE>| b.write_zeta3(3),
        0b0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0101,
    );
    test_code!(
        |b: &mut Backend<BE>| b.write_zeta3(4),
        0b1101_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000,
        |b: &mut Backend<LE>| b.write_zeta3(4),
        0b0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_1101,
    );
    test_code!(
        |b: &mut Backend<BE>| b.write_zeta3(5),
        0b1110_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000,
        |b: &mut Backend<LE>| b.write_zeta3(5),
        0b0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0111,
    );
    test_code!(
        |b: &mut Backend<BE>| b.write_zeta3(6),
        0b1111_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000,
        |b: &mut Backend<LE>| b.write_zeta3(6),
        0b0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_1111,
    );
    test_code!(
        |b: &mut Backend<BE>| b.write_zeta3(7),
        0b0100_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000,
        |b: &mut Backend<LE>| b.write_zeta3(7),
        0b0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0010,
    );
    test_code!(
        |b: &mut Backend<BE>| b.write_zeta3(8),
        0b0100_0010_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000,
        |b: &mut Backend<LE>| b.write_zeta3(8),
        0b0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0110,
    );
    test_code!(
        |b: &mut Backend<BE>| b.write_zeta3(9),
        0b0100_0100_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000,
        |b: &mut Backend<LE>| b.write_zeta3(9),
        0b0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_1010,
    );
    test_code!(
        |b: &mut Backend<BE>| b.write_zeta3(10),
        0b0100_0110_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000,
        |b: &mut Backend<LE>| b.write_zeta3(10),
        0b0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_1110,
    );

    Ok(())
}

#[test]
fn test_zeta2() -> Result<(), Box<dyn Error + Send + Sync + 'static>> {
    test_code!(
        |b: &mut Backend<BE>| b.write_zeta(0, 2),
        0b1000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000,
        |b: &mut Backend<LE>| b.write_zeta(0, 2),
        0b0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0001,
    );
    test_code!(
        |b: &mut Backend<BE>| b.write_zeta(1, 2),
        0b1100_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000,
        |b: &mut Backend<LE>| b.write_zeta(1, 2),
        0b0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0011,
    );
    test_code!(
        |b: &mut Backend<BE>| b.write_zeta(2, 2),
        0b1110_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000,
        |b: &mut Backend<LE>| b.write_zeta(2, 2),
        0b0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0111,
    );
    test_code!(
        |b: &mut Backend<BE>| b.write_zeta(3, 2),
        0b0100_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000,
        |b: &mut Backend<LE>| b.write_zeta(3, 2),
        0b0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0010,
    );
    test_code!(
        |b: &mut Backend<BE>| b.write_zeta(4, 2),
        0b0100_1000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000,
        |b: &mut Backend<LE>| b.write_zeta(4, 2),
        0b0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0110,
    );
    test_code!(
        |b: &mut Backend<BE>| b.write_zeta(5, 2),
        0b0101_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000,
        |b: &mut Backend<LE>| b.write_zeta(5, 2),
        0b0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_1010,
    );
    test_code!(
        |b: &mut Backend<BE>| b.write_zeta(6, 2),
        0b0101_1000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000,
        |b: &mut Backend<LE>| b.write_zeta(6, 2),
        0b0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_1110,
    );
    test_code!(
        |b: &mut Backend<BE>| b.write_zeta(7, 2),
        0b0110_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000,
        |b: &mut Backend<LE>| b.write_zeta(7, 2),
        0b0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0001_0010,
    );
    test_code!(
        |b: &mut Backend<BE>| b.write_zeta(8, 2),
        0b0110_0100_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000,
        |b: &mut Backend<LE>| b.write_zeta(8, 2),
        0b0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0011_0010,
    );
    test_code!(
        |b: &mut Backend<BE>| b.write_zeta(9, 2),
        0b0110_1000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000,
        |b: &mut Backend<LE>| b.write_zeta(9, 2),
        0b0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0001_0110,
    );
    test_code!(
        |b: &mut Backend<BE>| b.write_zeta(10, 2),
        0b0110_1100_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000,
        |b: &mut Backend<LE>| b.write_zeta(10, 2),
        0b0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0011_0110,
    );

    Ok(())
}