use super::*;
use crate::io::per::Error;
#[derive(Debug, Default)]
pub struct BitBuffer {
pub(crate) buffer: Vec<u8>,
pub(crate) write_position: usize,
pub(crate) read_position: usize,
}
impl BitBuffer {
pub fn with_capacity(capacity: usize) -> Self {
Self {
buffer: Vec::with_capacity(capacity),
..Default::default()
}
}
pub fn from_bytes(buffer: Vec<u8>) -> Self {
let bits = buffer.len() * BYTE_LEN;
Self::from_bits(buffer, bits)
}
pub fn from_bits(buffer: Vec<u8>, bit_length: usize) -> Self {
assert!(bit_length <= buffer.len() * BYTE_LEN);
Self {
buffer,
write_position: bit_length,
read_position: 0,
}
}
pub fn from_bits_with_position(
buffer: Vec<u8>,
write_position: usize,
read_position: usize,
) -> Self {
assert!(write_position <= buffer.len() * BYTE_LEN);
assert!(read_position <= buffer.len() * BYTE_LEN);
Self {
buffer,
write_position,
read_position,
}
}
pub fn clear(&mut self) {
self.buffer.clear();
self.write_position = 0;
self.read_position = 0;
}
pub fn reset_read_position(&mut self) {
self.read_position = 0;
}
pub fn content(&self) -> &[u8] {
&self.buffer
}
pub const fn bit_len(&self) -> usize {
self.write_position
}
pub fn byte_len(&self) -> usize {
self.buffer.len()
}
#[inline]
pub fn with_write_position_at<T, F: Fn(&mut Self) -> T>(&mut self, position: usize, f: F) -> T {
debug_assert!(position <= self.buffer.len() * 8);
let before = core::mem::replace(&mut self.write_position, position);
let result = f(self);
self.write_position = before;
result
}
#[inline]
pub fn with_read_position_at<T, F: Fn(&mut Self) -> T>(&mut self, position: usize, f: F) -> T {
debug_assert!(position < self.write_position);
let before = core::mem::replace(&mut self.read_position, position);
let result = f(self);
self.read_position = before;
result
}
pub fn with_max_read<T, F: Fn(&mut Self) -> T>(&mut self, max_read_len: usize, f: F) -> T {
let before =
core::mem::replace(&mut self.write_position, self.read_position + max_read_len);
let result = f(self);
self.write_position = before;
result
}
pub fn ensure_can_write_additional_bits(&mut self, bit_len: usize) {
if self.write_position + bit_len >= self.buffer.len() * BYTE_LEN {
let required_len = ((self.write_position + bit_len) + 7) / BYTE_LEN;
let extend_by_len = required_len - self.buffer.len();
self.buffer
.extend(core::iter::repeat(0u8).take(extend_by_len))
}
}
}
impl From<BitBuffer> for Vec<u8> {
fn from(bb: BitBuffer) -> Vec<u8> {
bb.buffer
}
}
impl From<Vec<u8>> for BitBuffer {
fn from(buffer: Vec<u8>) -> Self {
Self::from_bytes(buffer)
}
}
impl BitRead for BitBuffer {
#[inline]
fn read_bit(&mut self) -> Result<bool, Error> {
if self.read_position < self.write_position {
BitRead::read_bit(&mut (&self.buffer[..], &mut self.read_position))
} else {
Err(Error::EndOfStream)
}
}
#[inline]
fn read_bits(&mut self, dst: &mut [u8]) -> Result<(), Error> {
BitRead::read_bits(&mut (&self.buffer[..], &mut self.read_position), dst)
}
#[inline]
fn read_bits_with_offset(
&mut self,
dst: &mut [u8],
dst_bit_offset: usize,
) -> Result<(), Error> {
BitRead::read_bits_with_offset(
&mut (&self.buffer[..], &mut self.read_position),
dst,
dst_bit_offset,
)
}
#[inline]
fn read_bits_with_len(&mut self, dst: &mut [u8], dst_bit_len: usize) -> Result<(), Error> {
BitRead::read_bits_with_len(
&mut (&self.buffer[..], &mut self.read_position),
dst,
dst_bit_len,
)
}
#[inline]
fn read_bits_with_offset_len(
&mut self,
dst: &mut [u8],
dst_bit_offset: usize,
dst_bit_len: usize,
) -> Result<(), Error> {
BitRead::read_bits_with_offset_len(
&mut (&self.buffer[..], &mut self.read_position),
dst,
dst_bit_offset,
dst_bit_len,
)
}
}
impl BitWrite for BitBuffer {
#[inline]
fn write_bit(&mut self, bit: bool) -> Result<(), Error> {
self.ensure_can_write_additional_bits(1);
BitWrite::write_bit(&mut (&mut self.buffer[..], &mut self.write_position), bit)
}
#[inline]
fn write_bits(&mut self, src: &[u8]) -> Result<(), Error> {
self.ensure_can_write_additional_bits(src.len() * BYTE_LEN);
BitWrite::write_bits(&mut (&mut self.buffer[..], &mut self.write_position), src)
}
#[inline]
fn write_bits_with_offset(&mut self, src: &[u8], src_bit_offset: usize) -> Result<(), Error> {
self.ensure_can_write_additional_bits(src.len() * BYTE_LEN - src_bit_offset);
BitWrite::write_bits_with_offset(
&mut (&mut self.buffer[..], &mut self.write_position),
src,
src_bit_offset,
)
}
#[inline]
fn write_bits_with_len(&mut self, src: &[u8], bit_len: usize) -> Result<(), Error> {
self.ensure_can_write_additional_bits(bit_len);
BitWrite::write_bits_with_len(
&mut (&mut self.buffer[..], &mut self.write_position),
src,
bit_len,
)
}
#[inline]
fn write_bits_with_offset_len(
&mut self,
src: &[u8],
src_bit_offset: usize,
src_bit_len: usize,
) -> Result<(), Error> {
self.ensure_can_write_additional_bits(src_bit_len);
BitWrite::write_bits_with_offset_len(
&mut (&mut self.buffer[..], &mut self.write_position),
src,
src_bit_offset,
src_bit_len,
)
}
}
pub struct Bits<'a> {
slice: &'a [u8],
pos: usize,
len: usize,
}
impl<'a> From<&'a [u8]> for Bits<'a> {
fn from(slice: &'a [u8]) -> Self {
Self {
slice,
pos: 0,
len: slice.len() * BYTE_LEN,
}
}
}
impl<'a> From<(&'a [u8], usize)> for Bits<'a> {
fn from((slice, len): (&'a [u8], usize)) -> Self {
debug_assert!(len <= slice.len() * BYTE_LEN);
Self { slice, pos: 0, len }
}
}
impl<'a> From<&'a BitBuffer> for Bits<'a> {
fn from(buffer: &'a BitBuffer) -> Self {
Self {
slice: buffer.content(),
pos: 0,
len: buffer.bit_len(),
}
}
}
impl BitRead for Bits<'_> {
#[inline]
fn read_bit(&mut self) -> Result<bool, Error> {
if self.pos < self.len {
BitRead::read_bit(&mut (self.slice, &mut self.pos))
} else {
Err(Error::EndOfStream)
}
}
#[inline]
fn read_bits(&mut self, dst: &mut [u8]) -> Result<(), Error> {
BitRead::read_bits(&mut (self.slice, &mut self.pos), dst)
}
#[inline]
fn read_bits_with_offset(
&mut self,
dst: &mut [u8],
dst_bit_offset: usize,
) -> Result<(), Error> {
BitRead::read_bits_with_offset(&mut (self.slice, &mut self.pos), dst, dst_bit_offset)
}
#[inline]
fn read_bits_with_len(&mut self, dst: &mut [u8], dst_bit_len: usize) -> Result<(), Error> {
BitRead::read_bits_with_len(&mut (self.slice, &mut self.pos), dst, dst_bit_len)
}
#[inline]
fn read_bits_with_offset_len(
&mut self,
dst: &mut [u8],
dst_bit_offset: usize,
dst_bit_len: usize,
) -> Result<(), Error> {
BitRead::read_bits_with_offset_len(
&mut (self.slice, &mut self.pos),
dst,
dst_bit_offset,
dst_bit_len,
)
}
}
impl ScopedBitRead for Bits<'_> {
#[inline]
fn pos(&self) -> usize {
self.pos
}
#[inline]
fn set_pos(&mut self, position: usize) -> usize {
let pos = position.min(self.len);
self.pos = pos;
pos
}
#[inline]
fn len(&self) -> usize {
self.len
}
#[inline]
fn set_len(&mut self, len: usize) -> usize {
let len = len.min(self.slice.len() * BYTE_LEN);
self.len = len;
len
}
#[inline]
fn remaining(&self) -> usize {
self.len - self.pos
}
}
#[cfg(test)]
#[allow(clippy::identity_op, clippy::inconsistent_digit_grouping)] pub mod tests {
use super::*;
use crate::io::per::unaligned::BitRead;
use crate::io::per::unaligned::BitWrite;
use crate::io::per::unaligned::PackedRead;
use crate::io::per::unaligned::PackedWrite;
#[test]
pub fn bit_buffer_write_bit_keeps_correct_order() -> Result<(), Error> {
let mut buffer = BitBuffer::default();
buffer.write_bit(true)?;
buffer.write_bit(false)?;
buffer.write_bit(false)?;
buffer.write_bit(true)?;
buffer.write_bit(true)?;
buffer.write_bit(true)?;
buffer.write_bit(true)?;
buffer.write_bit(false)?;
assert_eq!(buffer.content(), &[0b1001_1110]);
buffer.write_bit(true)?;
buffer.write_bit(false)?;
buffer.write_bit(true)?;
buffer.write_bit(true)?;
buffer.write_bit(true)?;
buffer.write_bit(true)?;
buffer.write_bit(true)?;
buffer.write_bit(false)?;
assert_eq!(buffer.content(), &[0b1001_1110, 0b1011_1110]);
buffer.write_bit(true)?;
buffer.write_bit(false)?;
buffer.write_bit(true)?;
buffer.write_bit(false)?;
assert_eq!(buffer.content(), &[0b1001_1110, 0b1011_1110, 0b1010_0000]);
let mut buffer = BitBuffer::from_bits(buffer.content().into(), buffer.bit_len());
assert!(buffer.read_bit()?);
assert!(!buffer.read_bit()?);
assert!(!buffer.read_bit()?);
assert!(buffer.read_bit()?);
assert!(buffer.read_bit()?);
assert!(buffer.read_bit()?);
assert!(buffer.read_bit()?);
assert!(!buffer.read_bit()?);
assert!(buffer.read_bit()?);
assert!(!buffer.read_bit()?);
assert!(buffer.read_bit()?);
assert!(buffer.read_bit()?);
assert!(buffer.read_bit()?);
assert!(buffer.read_bit()?);
assert!(buffer.read_bit()?);
assert!(!buffer.read_bit()?);
assert!(buffer.read_bit()?);
assert!(!buffer.read_bit()?);
assert!(buffer.read_bit()?);
assert!(!buffer.read_bit()?);
assert_eq!(buffer.read_bit(), Err(Error::EndOfStream));
Ok(())
}
#[test]
fn bit_buffer_bits() -> Result<(), Error> {
let content = &[0xFF, 0x74, 0xA6, 0x0F];
let mut buffer = BitBuffer::default();
buffer.write_bits(content)?;
assert_eq!(buffer.content(), content);
{
let mut buffer2 = BitBuffer::from_bits(buffer.content().into(), buffer.bit_len());
let mut content2 = vec![0_u8; content.len()];
buffer2.read_bits(&mut content2[..])?;
assert_eq!(&content[..], &content2[..]);
}
let mut content2 = vec![0xFF_u8; content.len()];
buffer.read_bits(&mut content2[..])?;
assert_eq!(&content[..], &content2[..]);
Ok(())
}
#[test]
fn bit_buffers_with_offset() -> Result<(), Error> {
let content = &[0b1111_1111, 0b0111_0100, 0b1010_0110, 0b0000_1111];
let mut buffer = BitBuffer::default();
buffer.write_bits_with_offset(content, 7)?;
assert_eq!(
buffer.content(),
&[0b1011_1010, 0b0101_0011, 0b0000_0111, 0b1000_0000]
);
{
let mut buffer2 = BitBuffer::from_bits(buffer.content().into(), buffer.bit_len());
let mut content2 = vec![0xFF_u8; content.len()];
content2[0] = content[0] & 0b1111_1110; buffer2.read_bits_with_offset(&mut content2[..], 7)?;
assert_eq!(&content[..], &content2[..]);
}
let mut content2 = vec![0_u8; content.len()];
content2[0] = content[0] & 0b1111_1110; buffer.read_bits_with_offset(&mut content2[..], 7)?;
assert_eq!(&content[..], &content2[..]);
Ok(())
}
#[test]
fn bit_buffer_bits_with_offset_len() -> Result<(), Error> {
let content = &[0b1111_1111, 0b0111_0100, 0b1010_0110, 0b0000_1111];
let mut buffer = BitBuffer::default();
buffer.write_bits_with_offset_len(content, 7, 12)?;
assert_eq!(buffer.content(), &[0b1011_1010, 0b0101_0000]);
{
let mut buffer2 = BitBuffer::from_bits(buffer.content().into(), buffer.bit_len());
let mut content2 = vec![0_u8; content.len()];
let content = &[
content[0] & 0x01,
content[1],
content[2] & 0b1110_0000,
0x00,
];
buffer2.read_bits_with_offset_len(&mut content2[..], 7, 12)?;
assert_eq!(&content[..], &content2[..]);
}
let mut content2 = vec![0x00_u8; content.len()];
let content = &[
content[0] & 0x01,
content[1],
content[2] & 0b1110_0000,
0x00,
];
buffer.read_bits_with_offset_len(&mut content2[..], 7, 12)?;
assert_eq!(&content[..], &content2[..]);
Ok(())
}
#[test]
fn bit_buffer_length_determinant_0() -> Result<(), Error> {
const DET: u64 = 0;
let mut buffer = BitBuffer::default();
buffer.write_length_determinant(None, None, DET)?;
assert_eq!(buffer.content(), &[0x00 | DET as u8]);
{
let mut buffer2 = BitBuffer::from_bits(buffer.content().into(), buffer.bit_len());
assert_eq!(DET, buffer2.read_length_determinant(None, None)?);
}
assert_eq!(DET, buffer.read_length_determinant(None, None)?);
Ok(())
}
#[test]
fn bit_buffer_length_determinant_1() -> Result<(), Error> {
const DET: u64 = 1;
let mut buffer = BitBuffer::default();
buffer.write_length_determinant(None, None, DET)?;
assert_eq!(buffer.content(), &[0x00 | DET as u8]);
{
let mut buffer2 = BitBuffer::from_bits(buffer.content().into(), buffer.bit_len());
assert_eq!(DET, buffer2.read_length_determinant(None, None)?);
}
assert_eq!(DET, buffer.read_length_determinant(None, None)?);
Ok(())
}
#[test]
fn bit_buffer_length_determinant_127() -> Result<(), Error> {
const DET: u64 = 126;
let mut buffer = BitBuffer::default();
buffer.write_length_determinant(None, None, DET)?;
assert_eq!(buffer.content(), &[0x00 | DET as u8]);
{
let mut buffer2 = BitBuffer::from_bits(buffer.content().into(), buffer.bit_len());
assert_eq!(DET, buffer2.read_length_determinant(None, None)?);
}
assert_eq!(DET, buffer.read_length_determinant(None, None)?);
Ok(())
}
#[test]
fn bit_buffer_length_determinant_128() -> Result<(), Error> {
const DET: u64 = 128;
let mut buffer = BitBuffer::default();
buffer.write_length_determinant(None, None, DET)?;
assert_eq!(buffer.content(), &[0x80 | 0x00, 0x00 | DET as u8]);
{
let mut buffer2 = BitBuffer::from_bits(buffer.content().into(), buffer.bit_len());
assert_eq!(DET, buffer2.read_length_determinant(None, None)?);
}
assert_eq!(DET, buffer.read_length_determinant(None, None)?);
Ok(())
}
#[test]
fn bit_buffer_length_determinant_16383() -> Result<(), Error> {
const DET: u64 = 16383;
let mut buffer = BitBuffer::default();
buffer.write_length_determinant(None, None, DET)?;
assert_eq!(
buffer.content(),
&[0x80 | (DET >> 8) as u8, 0x00 | (DET & 0xFF) as u8]
);
{
let mut buffer2 = BitBuffer::from_bits(buffer.content().into(), buffer.bit_len());
assert_eq!(DET, buffer2.read_length_determinant(None, None)?);
}
assert_eq!(DET, buffer.read_length_determinant(None, None)?);
Ok(())
}
fn check_unconstrained_whole_number(buffer: &mut BitBuffer, int: i64) -> Result<(), Error> {
{
let mut buffer2 = BitBuffer::from_bits(buffer.content().into(), buffer.bit_len());
assert_eq!(int, buffer2.read_unconstrained_whole_number()?)
}
assert_eq!(int, buffer.read_unconstrained_whole_number()?);
Ok(())
}
#[test]
fn bit_buffer_unconstrained_whole_number_neg_12() -> Result<(), Error> {
const INT: i64 = -12;
let mut buffer = BitBuffer::default();
buffer.write_unconstrained_whole_number(INT)?;
assert_eq!(buffer.content(), &[0x00 | 1, INT as u8]);
check_unconstrained_whole_number(&mut buffer, INT)?;
Ok(())
}
#[test]
fn bit_buffer_unconstrained_whole_number_0() -> Result<(), Error> {
const INT: i64 = 0;
let mut buffer = BitBuffer::default();
buffer.write_unconstrained_whole_number(INT)?;
assert_eq!(buffer.content(), &[0x00 | 1, INT as u8]);
check_unconstrained_whole_number(&mut buffer, INT)?;
Ok(())
}
#[test]
fn bit_buffer_unconstrained_whole_number_127() -> Result<(), Error> {
const INT: i64 = 127; let mut buffer = BitBuffer::default();
buffer.write_unconstrained_whole_number(INT)?;
assert_eq!(buffer.content(), &[0x00 | 1, INT as u8]);
check_unconstrained_whole_number(&mut buffer, INT)?;
Ok(())
}
#[test]
fn bit_buffer_unconstrained_whole_number_128() -> Result<(), Error> {
const INT: i64 = 128; let mut buffer = BitBuffer::default();
buffer.write_unconstrained_whole_number(INT)?;
assert_eq!(buffer.content(), &[0x02, 0x00, 0x80]);
check_unconstrained_whole_number(&mut buffer, INT)?;
Ok(())
}
#[test]
fn bit_buffer_unconstrained_whole_number_255() -> Result<(), Error> {
const INT: i64 = 255; let mut buffer = BitBuffer::default();
buffer.write_unconstrained_whole_number(INT)?;
assert_eq!(buffer.content(), &[0x02, 0x00, 0xFF]);
check_unconstrained_whole_number(&mut buffer, INT)?;
Ok(())
}
#[test]
fn bit_buffer_unconstrained_whole_number_256() -> Result<(), Error> {
const INT: i64 = 256; let mut buffer = BitBuffer::default();
buffer.write_unconstrained_whole_number(INT)?;
assert_eq!(
buffer.content(),
&[
0x00 | 2,
((INT & 0xFF_00) >> 8) as u8,
((INT & 0x00_ff) >> 0) as u8,
]
);
check_unconstrained_whole_number(&mut buffer, INT)?;
Ok(())
}
#[test]
fn bit_buffer_unconstrained_whole_number_65535() -> Result<(), Error> {
const INT: i64 = 65_535; let mut buffer = BitBuffer::default();
buffer.write_unconstrained_whole_number(INT)?;
assert_eq!(buffer.content(), &[0x03, 0x00, 0xFF, 0xFF]);
check_unconstrained_whole_number(&mut buffer, INT)?;
Ok(())
}
#[test]
fn bit_buffer_unconstrained_whole_number_65536() -> Result<(), Error> {
const INT: i64 = 65_536; let mut buffer = BitBuffer::default();
buffer.write_unconstrained_whole_number(INT)?;
assert_eq!(buffer.content(), &[0x03, 0x01, 0x00, 0x00]);
check_unconstrained_whole_number(&mut buffer, INT)?;
Ok(())
}
#[test]
fn bit_buffer_unconstrained_whole_number_16777215() -> Result<(), Error> {
const INT: i64 = 16_777_215; let mut buffer = BitBuffer::default();
buffer.write_unconstrained_whole_number(INT)?;
assert_eq!(buffer.content(), &[0x04, 0x00, 0xFF, 0xFF, 0xFF]);
check_unconstrained_whole_number(&mut buffer, INT)?;
Ok(())
}
#[test]
fn bit_buffer_unconstrained_whole_number_16777216() -> Result<(), Error> {
const INT: i64 = 16_777_216; let mut buffer = BitBuffer::default();
buffer.write_unconstrained_whole_number(INT)?;
assert_eq!(
buffer.content(),
&[
0x00 | 4,
((INT & 0xFF_00_00_00) >> 24) as u8,
((INT & 0x00_FF_00_00) >> 16) as u8,
((INT & 0x00_00_FF_00) >> 8) as u8,
((INT & 0x00_00_00_FF) >> 0) as u8,
]
);
check_unconstrained_whole_number(&mut buffer, INT)?;
Ok(())
}
#[test]
fn bit_buffer_unconstrained_whole_number_4294967295() -> Result<(), Error> {
const INT: i64 = 4_294_967_295; let mut buffer = BitBuffer::default();
buffer.write_unconstrained_whole_number(INT)?;
assert_eq!(buffer.content(), &[0x05, 0x00, 0xFF, 0xFF, 0xFF, 0xFF]);
check_unconstrained_whole_number(&mut buffer, INT)?;
Ok(())
}
#[test]
fn bit_buffer_unconstrained_whole_number_4294967296() -> Result<(), Error> {
const INT: i64 = 4_294_967_296; let mut buffer = BitBuffer::default();
buffer.write_unconstrained_whole_number(INT)?;
assert_eq!(buffer.content(), &[0x05, 0x01, 0x00, 0x00, 0x00, 0x00]);
check_unconstrained_whole_number(&mut buffer, INT)?;
Ok(())
}
#[test]
fn bit_buffer_unconstrained_whole_number_i64_max() -> Result<(), Error> {
const INT: i64 = i64::max_value();
let mut buffer = BitBuffer::default();
buffer.write_unconstrained_whole_number(INT)?;
assert_eq!(
buffer.content(),
&[
0x00 | 8,
((INT as u64 & 0xFF_00_00_00_00_00_00_00_u64) >> 56) as u8,
((INT as u64 & 0x00_FF_00_00_00_00_00_00_u64) >> 48) as u8,
((INT as u64 & 0x00_00_FF_00_00_00_00_00_u64) >> 40) as u8,
((INT as u64 & 0x00_00_00_FF_00_00_00_00_u64) >> 32) as u8,
((INT as u64 & 0x00_00_00_00_FF_00_00_00_u64) >> 24) as u8,
((INT as u64 & 0x00_00_00_00_00_FF_00_00_u64) >> 16) as u8,
((INT as u64 & 0x00_00_00_00_00_00_FF_00_u64) >> 8) as u8,
((INT as u64 & 0x00_00_00_00_00_00_00_FF_u64) >> 0) as u8,
]
);
check_unconstrained_whole_number(&mut buffer, INT)?;
Ok(())
}
#[test]
fn bit_buffer_write_constrained_whole_number_detects_not_in_range_positive_only() {
let mut buffer = BitBuffer::default();
assert_eq!(
buffer.write_constrained_whole_number(10, 127, 0),
Err(Error::ValueNotInRange(0, 10, 127))
);
assert_eq!(
buffer.write_constrained_whole_number(10, 127, 128),
Err(Error::ValueNotInRange(128, 10, 127))
);
}
#[test]
fn bit_buffer_write_constrained_whole_number_detects_not_in_range_negative() {
let mut buffer = BitBuffer::default();
assert_eq!(
buffer.write_constrained_whole_number(-10, -1, -11),
Err(Error::ValueNotInRange(-11, -10, -1))
);
assert_eq!(
buffer.write_constrained_whole_number(-10, -1, 0),
Err(Error::ValueNotInRange(0, -10, -1))
);
}
#[test]
fn bit_buffer_write_constrained_whole_number_detects_not_in_range_with_negative() {
let mut buffer = BitBuffer::default();
assert_eq!(
buffer.write_constrained_whole_number(-10, 1, -11),
Err(Error::ValueNotInRange(-11, -10, 1))
);
assert_eq!(
buffer.write_constrained_whole_number(-10, 1, 2),
Err(Error::ValueNotInRange(2, -10, 1))
);
}
fn check_constrained_whole_number(
buffer: &mut BitBuffer,
int: i64,
range: (i64, i64),
) -> Result<(), Error> {
{
let mut buffer2 = BitBuffer::from_bits(buffer.content().into(), buffer.bit_len());
assert_eq!(
int,
buffer2.read_constrained_whole_number(range.0, range.1)?
);
}
assert_eq!(int, buffer.read_constrained_whole_number(range.0, range.1)?);
Ok(())
}
#[test]
fn bit_buffer_constrained_whole_number_7bits() -> Result<(), Error> {
const INT: i64 = 10;
const RANGE: (i64, i64) = (0, 127);
let mut buffer = BitBuffer::default();
buffer.write_constrained_whole_number(RANGE.0, RANGE.1, INT)?;
assert_eq!(buffer.content(), &[(INT as u8) << 1]);
check_constrained_whole_number(&mut buffer, INT, RANGE)?;
buffer.write_bit(true)?;
assert_eq!(buffer.content(), &[(INT as u8) << 1 | 0b0000_0001]);
Ok(())
}
#[test]
fn bit_buffer_constrained_whole_number_neg() -> Result<(), Error> {
const INT: i64 = -10;
const RANGE: (i64, i64) = (-128, 127);
let mut buffer = BitBuffer::default();
buffer.write_constrained_whole_number(RANGE.0, RANGE.1, INT)?;
assert_eq!(buffer.content(), &[(INT - RANGE.0) as u8]);
check_constrained_whole_number(&mut buffer, INT, RANGE)?;
Ok(())
}
#[test]
fn bit_buffer_constrained_whole_number_neg_extended_range() -> Result<(), Error> {
const INT: i64 = -10;
const RANGE: (i64, i64) = (-128, 128);
let mut buffer = BitBuffer::default();
buffer.write_constrained_whole_number(RANGE.0, RANGE.1, INT)?;
assert_eq!(
buffer.content(),
&[
((INT - RANGE.0) as u8) >> 1,
(((INT - RANGE.0) as u8) << 7) | 0b0000_0000
]
);
buffer.write_bit(true)?;
assert_eq!(
buffer.content(),
&[
((INT - RANGE.0) as u8) >> 1,
((INT - RANGE.0) as u8) << 7 | 0b0100_0000
]
);
check_constrained_whole_number(&mut buffer, INT, RANGE)?;
Ok(())
}
#[test]
fn bit_buffer_octet_string_with_range() -> Result<(), Error> {
const BYTES: &[u8] = &[0x2A, 0x2B, 0x96, 0xFF];
const RANGE: (u64, u64) = (1, 20);
let mut buffer = BitBuffer::default();
buffer.write_octetstring(Some(RANGE.0), Some(RANGE.1), false, BYTES)?;
assert_eq!(&[0x19, 0x51, 0x5c, 0xb7, 0xf8], &buffer.content());
Ok(())
}
#[test]
fn bit_buffer_octet_string_without_range() -> Result<(), Error> {
const BYTES: &[u8] = &[0x2A, 0x2B, 0x96, 0xFF];
let mut buffer = BitBuffer::default();
buffer.write_octetstring(None, None, false, BYTES)?;
assert_eq!(&[0x04, 0x2a, 0x2b, 0x96, 0xff], &buffer.content());
Ok(())
}
#[test]
fn bit_buffer_octet_string_empty() -> Result<(), Error> {
const BYTES: &[u8] = &[];
let mut buffer = BitBuffer::default();
buffer.write_octetstring(None, None, false, BYTES)?;
assert_eq!(&[0x00], &buffer.content());
Ok(())
}
#[test]
fn bit_buffer_normally_small_non_negative_whole_number_5() -> Result<(), Error> {
let mut buffer = BitBuffer::default();
buffer.write_normally_small_non_negative_whole_number(5)?;
assert_eq!(&[0b0000_101_0], &buffer.content());
assert_eq!(5, buffer.read_normally_small_non_negative_whole_number()?);
Ok(())
}
#[test]
fn bit_buffer_normally_small_non_negative_whole_number_60() -> Result<(), Error> {
let mut buffer = BitBuffer::default();
buffer.write_normally_small_non_negative_whole_number(60)?;
assert_eq!(&[0b0111_100_0], &buffer.content());
assert_eq!(60, buffer.read_normally_small_non_negative_whole_number()?);
Ok(())
}
#[test]
fn bit_buffer_normally_small_non_negative_whole_number_254() -> Result<(), Error> {
let mut buffer = BitBuffer::default();
buffer.write_normally_small_non_negative_whole_number(254)?;
assert_eq!(
&[0b1_000_0000, 0b1__111_1111, 0b0_000_0000],
&buffer.content()
);
Ok(())
}
#[test]
fn bit_buffer_write_choice_index_extensible() -> Result<(), Error> {
fn write_once(index: u64, no_of_default_variants: u64) -> Result<(usize, Vec<u8>), Error> {
let mut buffer = BitBuffer::default();
buffer.write_choice_index(no_of_default_variants, true, index)?;
let bits = buffer.bit_len();
Ok((bits, buffer.into()))
}
assert_eq!((2, vec![0x00]), write_once(0, 2)?);
assert_eq!((2, vec![0x40]), write_once(1, 2)?);
assert_eq!((8, vec![0x80]), write_once(2, 2)?);
assert_eq!((8, vec![0x81]), write_once(3, 2)?);
Ok(())
}
#[test]
fn bit_buffer_read_choice_index_extensible() -> Result<(), Error> {
fn read_once(data: &[u8], bits: usize, no_of_variants: u64) -> Result<u64, Error> {
let mut buffer = BitBuffer::default();
buffer.write_bits_with_len(data, bits)?;
buffer.read_choice_index(no_of_variants, true)
}
assert_eq!(0, read_once(&[0x00], 2, 2)?);
assert_eq!(1, read_once(&[0x40], 2, 2)?);
assert_eq!(2, read_once(&[0x80], 8, 2)?);
assert_eq!(3, read_once(&[0x81], 8, 2)?);
Ok(())
}
}