mirror of
https://codeberg.org/icewind/bitbuffer.git
synced 2026-06-03 16:44:06 +02:00
writing wip and bool be read fixes
This commit is contained in:
parent
0e239cc011
commit
8979354c60
9 changed files with 477 additions and 55 deletions
|
|
@ -2,7 +2,7 @@
|
|||
#![allow(unreachable_patterns)]
|
||||
|
||||
use bitbuffer::{
|
||||
bit_size_of, bit_size_of_sized, BigEndian, BitReadBuffer, BitReadStream, Endianness,
|
||||
bit_size_of, bit_size_of_sized, BigEndian, BitReadStream, BitWriteBuffer, Endianness,
|
||||
LittleEndian,
|
||||
};
|
||||
use bitbuffer_derive::{BitRead, BitReadSized};
|
||||
|
|
@ -45,7 +45,7 @@ fn test_read_struct() {
|
|||
0b0101_0101,
|
||||
0b1010_1010,
|
||||
];
|
||||
let buffer = BitReadBuffer::new(bytes, LittleEndian);
|
||||
let buffer = BitWriteBuffer::new(bytes, LittleEndian);
|
||||
let mut stream = BitReadStream::from(buffer);
|
||||
assert_eq!(
|
||||
TestStruct {
|
||||
|
|
@ -83,7 +83,7 @@ fn test_read_bare_enum() {
|
|||
0b1000_0100,
|
||||
0b1000_0100,
|
||||
];
|
||||
let buffer = BitReadBuffer::new(bytes, BigEndian);
|
||||
let buffer = BitWriteBuffer::new(bytes, BigEndian);
|
||||
let mut stream = BitReadStream::from(buffer);
|
||||
assert_eq!(TestBareEnum::Asd, stream.read().unwrap());
|
||||
assert_eq!(TestBareEnum::Foo, stream.read().unwrap());
|
||||
|
|
@ -114,7 +114,7 @@ fn test_read_unnamed_field_enum() {
|
|||
0b1000_0100,
|
||||
0b1000_0100,
|
||||
];
|
||||
let buffer = BitReadBuffer::new(bytes, BigEndian);
|
||||
let buffer = BitWriteBuffer::new(bytes, BigEndian);
|
||||
let mut stream = BitReadStream::from(buffer);
|
||||
assert_eq!(
|
||||
TestUnnamedFieldEnum::Asd(0b_00_0110_10),
|
||||
|
|
@ -144,7 +144,7 @@ fn test_read_struct_sized() {
|
|||
let bytes = vec![
|
||||
12, 'h' as u8, 'e' as u8, 'l' as u8, 'l' as u8, 'o' as u8, 0, 0, 0, 0, 0, 0,
|
||||
];
|
||||
let buffer = BitReadBuffer::new(bytes, LittleEndian);
|
||||
let buffer = BitWriteBuffer::new(bytes, LittleEndian);
|
||||
let mut stream = BitReadStream::from(buffer);
|
||||
assert_eq!(
|
||||
TestStructSized {
|
||||
|
|
@ -180,7 +180,7 @@ fn test_read_unnamed_field_enum_sized() {
|
|||
0b1000_0100,
|
||||
0b1000_0100,
|
||||
];
|
||||
let buffer = BitReadBuffer::new(bytes, BigEndian);
|
||||
let buffer = BitWriteBuffer::new(bytes, BigEndian);
|
||||
let mut stream = BitReadStream::from(buffer);
|
||||
assert_eq!(
|
||||
TestUnnamedFieldEnumSized::Asd(0b_00_0110),
|
||||
|
|
@ -213,7 +213,7 @@ fn test_read_struct2() {
|
|||
'l' as u8,
|
||||
'e' as u8,
|
||||
];
|
||||
let buffer = BitReadBuffer::new(bytes, BigEndian);
|
||||
let buffer = BitWriteBuffer::new(bytes, BigEndian);
|
||||
let mut stream = BitReadStream::from(buffer);
|
||||
assert_eq!(
|
||||
TestStruct2 {
|
||||
|
|
@ -236,7 +236,7 @@ struct TestStruct3<E: Endianness> {
|
|||
#[test]
|
||||
fn test_read_struct3() {
|
||||
let bytes = vec![0b0000_0101, 0, 0, 0, 0, 0, 0, 0];
|
||||
let buffer = BitReadBuffer::new(bytes, BigEndian);
|
||||
let buffer = BitWriteBuffer::new(bytes, BigEndian);
|
||||
let mut stream = BitReadStream::from(buffer);
|
||||
let result: TestStruct3<BigEndian> = stream.read().unwrap();
|
||||
assert_eq!(5, result.size);
|
||||
|
|
@ -265,7 +265,7 @@ fn test_read_rest_enum() {
|
|||
0b1000_0100,
|
||||
0b1000_0100,
|
||||
];
|
||||
let buffer = BitReadBuffer::new(bytes, BigEndian);
|
||||
let buffer = BitWriteBuffer::new(bytes, BigEndian);
|
||||
let mut stream = BitReadStream::from(buffer);
|
||||
assert_eq!(TestEnumRest::Asd, stream.read().unwrap());
|
||||
assert_eq!(TestEnumRest::Foo, stream.read().unwrap());
|
||||
|
|
@ -281,7 +281,7 @@ fn test_unnamed_struct() {
|
|||
let bytes = vec![
|
||||
12, 'h' as u8, 'e' as u8, 'l' as u8, 'l' as u8, 'o' as u8, 0, 0, 0, 0, 0, 0,
|
||||
];
|
||||
let buffer = BitReadBuffer::new(bytes, LittleEndian);
|
||||
let buffer = BitWriteBuffer::new(bytes, LittleEndian);
|
||||
let mut stream = BitReadStream::from(buffer);
|
||||
|
||||
assert_eq!(
|
||||
|
|
@ -295,7 +295,7 @@ struct EmptyStruct;
|
|||
|
||||
fn test_empty_struct() {
|
||||
let bytes = vec![0, 0, 0, 0];
|
||||
let buffer = BitReadBuffer::new(bytes, BigEndian);
|
||||
let buffer = BitWriteBuffer::new(bytes, BigEndian);
|
||||
let mut stream = BitReadStream::from(buffer);
|
||||
assert_eq!(EmptyStruct, stream.read().unwrap());
|
||||
assert_eq!(0, stream.pos());
|
||||
|
|
|
|||
|
|
@ -1,27 +0,0 @@
|
|||
pub trait IsSigned {
|
||||
fn is_signed() -> bool;
|
||||
}
|
||||
|
||||
macro_rules! impl_is_signed {
|
||||
($type:ty, $signed:expr) => {
|
||||
impl IsSigned for $type {
|
||||
#[inline(always)]
|
||||
fn is_signed() -> bool {
|
||||
$signed
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
impl_is_signed!(u8, false);
|
||||
impl_is_signed!(u16, false);
|
||||
impl_is_signed!(u32, false);
|
||||
impl_is_signed!(u64, false);
|
||||
impl_is_signed!(u128, false);
|
||||
impl_is_signed!(usize, false);
|
||||
impl_is_signed!(i8, true);
|
||||
impl_is_signed!(i16, true);
|
||||
impl_is_signed!(i32, true);
|
||||
impl_is_signed!(i64, true);
|
||||
impl_is_signed!(i128, true);
|
||||
impl_is_signed!(isize, true);
|
||||
|
|
@ -64,13 +64,14 @@ pub use endianness::*;
|
|||
pub use read::{BitRead, BitReadSized, LazyBitRead, LazyBitReadSized};
|
||||
pub use readbuffer::BitReadBuffer;
|
||||
pub use readstream::BitReadStream;
|
||||
pub use writestream::BitWriteStream;
|
||||
|
||||
mod endianness;
|
||||
mod is_signed;
|
||||
mod num_traits;
|
||||
mod read;
|
||||
mod readbuffer;
|
||||
mod readstream;
|
||||
mod unchecked_primitive;
|
||||
mod writestream;
|
||||
|
||||
/// Errors that can be returned when trying to read from a buffer
|
||||
#[derive(Debug)]
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
/// some extra number traits
|
||||
|
||||
/// Allow casting floats unchecked
|
||||
pub trait UncheckedPrimitiveFloat: Sized {
|
||||
fn from_f32_unchecked(n: f32) -> Self;
|
||||
|
|
@ -177,3 +179,59 @@ impl_unchecked_int!(u128, into_u128_unchecked);
|
|||
impl_unchecked_int!(i128, into_i128_unchecked);
|
||||
impl_unchecked_int!(usize, into_usize_unchecked);
|
||||
impl_unchecked_int!(isize, into_isize_unchecked);
|
||||
|
||||
pub trait IsSigned {
|
||||
fn is_signed() -> bool;
|
||||
}
|
||||
|
||||
macro_rules! impl_is_signed {
|
||||
($type:ty, $signed:expr) => {
|
||||
impl IsSigned for $type {
|
||||
#[inline(always)]
|
||||
fn is_signed() -> bool {
|
||||
$signed
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
pub trait IntoBytes: Sized {
|
||||
fn into_bytes(self) -> Vec<u8>;
|
||||
}
|
||||
|
||||
macro_rules! impl_into_bytes {
|
||||
($type:ty) => {
|
||||
impl IntoBytes for $type {
|
||||
#[inline(always)]
|
||||
fn into_bytes(self) -> Vec<u8> {
|
||||
self.to_le_bytes().to_vec()
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
impl_is_signed!(u8, false);
|
||||
impl_is_signed!(u16, false);
|
||||
impl_is_signed!(u32, false);
|
||||
impl_is_signed!(u64, false);
|
||||
impl_is_signed!(u128, false);
|
||||
impl_is_signed!(usize, false);
|
||||
impl_is_signed!(i8, true);
|
||||
impl_is_signed!(i16, true);
|
||||
impl_is_signed!(i32, true);
|
||||
impl_is_signed!(i64, true);
|
||||
impl_is_signed!(i128, true);
|
||||
impl_is_signed!(isize, true);
|
||||
|
||||
impl_into_bytes!(u8);
|
||||
impl_into_bytes!(u16);
|
||||
impl_into_bytes!(u32);
|
||||
impl_into_bytes!(u64);
|
||||
impl_into_bytes!(u128);
|
||||
impl_into_bytes!(usize);
|
||||
impl_into_bytes!(i8);
|
||||
impl_into_bytes!(i16);
|
||||
impl_into_bytes!(i32);
|
||||
impl_into_bytes!(i64);
|
||||
impl_into_bytes!(i128);
|
||||
impl_into_bytes!(isize);
|
||||
|
|
@ -9,8 +9,7 @@ use std::rc::Rc;
|
|||
use num_traits::{Float, PrimInt};
|
||||
|
||||
use crate::endianness::Endianness;
|
||||
use crate::is_signed::IsSigned;
|
||||
use crate::unchecked_primitive::{UncheckedPrimitiveFloat, UncheckedPrimitiveInt};
|
||||
use crate::num_traits::{IsSigned, UncheckedPrimitiveFloat, UncheckedPrimitiveInt};
|
||||
use crate::{ReadError, Result};
|
||||
use std::convert::TryInto;
|
||||
|
||||
|
|
@ -74,6 +73,22 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
pub(crate) fn get_bits_from_usize<E: Endianness>(
|
||||
val: usize,
|
||||
bit_offset: usize,
|
||||
count: usize,
|
||||
) -> usize {
|
||||
let usize_bit_size = size_of::<usize>() * 8;
|
||||
|
||||
let shifted = if E::is_le() {
|
||||
val >> bit_offset
|
||||
} else {
|
||||
val >> (usize_bit_size - bit_offset - count)
|
||||
};
|
||||
let mask = !(std::usize::MAX << count);
|
||||
shifted & mask
|
||||
}
|
||||
|
||||
impl<E> BitReadBuffer<E>
|
||||
where
|
||||
E: Endianness,
|
||||
|
|
@ -109,7 +124,6 @@ where
|
|||
unsafe fn read_usize(&self, position: usize, count: usize) -> usize {
|
||||
let byte_index = position / 8;
|
||||
let bit_offset = position & 7;
|
||||
let usize_bit_size = size_of::<usize>() * 8;
|
||||
|
||||
let bytes: [u8; USIZE_SIZE] = self.read_usize_bytes(byte_index);
|
||||
|
||||
|
|
@ -119,13 +133,7 @@ where
|
|||
usize::from_be_bytes(bytes)
|
||||
};
|
||||
|
||||
let shifted = if E::is_le() {
|
||||
container >> bit_offset
|
||||
} else {
|
||||
container >> (usize_bit_size - bit_offset - count)
|
||||
};
|
||||
let mask = !(std::usize::MAX << count);
|
||||
shifted & mask
|
||||
get_bits_from_usize::<E>(container, bit_offset, count)
|
||||
}
|
||||
|
||||
/// Read a single bit from the buffer as boolean
|
||||
|
|
@ -160,8 +168,13 @@ where
|
|||
|
||||
if position < self.bit_len() {
|
||||
let byte = self.bytes[byte_index];
|
||||
let shifted = byte >> bit_offset;
|
||||
Ok(shifted & 1u8 == 1)
|
||||
if E::is_le() {
|
||||
let shifted = byte >> bit_offset as u8;
|
||||
Ok(shifted & 1u8 == 1)
|
||||
} else {
|
||||
let shifted = byte << bit_offset as u8;
|
||||
Ok(shifted & 0b1000_0000u8 == 0b1000_0000u8)
|
||||
}
|
||||
} else {
|
||||
Err(ReadError::NotEnoughData {
|
||||
requested: 1,
|
||||
|
|
|
|||
|
|
@ -4,8 +4,7 @@ use std::ops::BitOrAssign;
|
|||
use num_traits::{Float, PrimInt};
|
||||
|
||||
use crate::endianness::Endianness;
|
||||
use crate::is_signed::IsSigned;
|
||||
use crate::unchecked_primitive::{UncheckedPrimitiveFloat, UncheckedPrimitiveInt};
|
||||
use crate::num_traits::{IsSigned, UncheckedPrimitiveFloat, UncheckedPrimitiveInt};
|
||||
use crate::BitReadBuffer;
|
||||
use crate::{BitRead, BitReadSized, ReadError, Result};
|
||||
use std::cmp::min;
|
||||
|
|
@ -40,7 +39,7 @@ impl<E> BitReadStream<E>
|
|||
where
|
||||
E: Endianness,
|
||||
{
|
||||
/// Create a new stream for a [`BitBuffer`]
|
||||
/// Create a new stream from a [`BitBuffer`]
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
|
|
|
|||
258
src/writestream.rs
Normal file
258
src/writestream.rs
Normal file
|
|
@ -0,0 +1,258 @@
|
|||
use std::cmp::min;
|
||||
use std::marker::PhantomData;
|
||||
use std::mem::size_of;
|
||||
use std::ops::{BitOrAssign, BitXor};
|
||||
|
||||
use num_traits::{Float, PrimInt};
|
||||
|
||||
use crate::endianness::Endianness;
|
||||
use crate::num_traits::{IntoBytes, IsSigned, UncheckedPrimitiveFloat, UncheckedPrimitiveInt};
|
||||
use crate::readbuffer::get_bits_from_usize;
|
||||
use crate::{LittleEndian, ReadError, Result};
|
||||
use std::iter::{once, repeat};
|
||||
|
||||
const USIZE_SIZE: usize = size_of::<usize>();
|
||||
const USIZE_BITS: usize = USIZE_SIZE * 8;
|
||||
|
||||
/// Stream that provides an a way to write non bit aligned adata
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bitbuffer::{BitWriteStream, LittleEndian};
|
||||
/// # use bitbuffer::Result;
|
||||
///
|
||||
/// # fn main() -> Result<()> {
|
||||
/// let mut stream = BitWriteStream::new(LittleEndian);
|
||||
///
|
||||
/// stream.write_bool(false)?;
|
||||
/// stream.write_int(123u16, 15)?;
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
/// ```
|
||||
///
|
||||
/// [`BitBuffer`]: struct.BitBuffer.html
|
||||
pub struct BitWriteStream<E>
|
||||
where
|
||||
E: Endianness,
|
||||
{
|
||||
bytes: Vec<u8>,
|
||||
bit_len: usize,
|
||||
endianness: PhantomData<E>,
|
||||
}
|
||||
|
||||
impl<E> BitWriteStream<E>
|
||||
where
|
||||
E: Endianness,
|
||||
{
|
||||
/// Create a new write stream
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bitbuffer::{BitWriteStream, LittleEndian};
|
||||
///
|
||||
/// let mut stream = BitWriteStream::new(LittleEndian);
|
||||
/// ```
|
||||
pub fn new(_endianness: E) -> Self {
|
||||
BitWriteStream {
|
||||
bytes: Vec::new(),
|
||||
bit_len: 0,
|
||||
endianness: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<E> BitWriteStream<E>
|
||||
where
|
||||
E: Endianness,
|
||||
{
|
||||
/// The number of written bits in the buffer
|
||||
pub fn bit_len(&self) -> usize {
|
||||
self.bit_len
|
||||
}
|
||||
|
||||
/// The number of written bytes in the buffer
|
||||
pub fn byte_len(&self) -> usize {
|
||||
self.bytes.len()
|
||||
}
|
||||
|
||||
fn push_non_fit_bits(&mut self, bits: &[u8], count: usize) {
|
||||
debug_assert!(bits.len() == count / 8);
|
||||
let counts = repeat(8)
|
||||
.take(bits.len() - 1)
|
||||
.chain(once(count - (bits.len() - 1) * 8));
|
||||
if E::is_le() {
|
||||
bits.iter()
|
||||
.copied()
|
||||
.zip(counts)
|
||||
.for_each(|(chunk, count)| self.push_bits(chunk as usize, count))
|
||||
} else {
|
||||
bits.iter()
|
||||
.rev()
|
||||
.copied()
|
||||
.zip(counts)
|
||||
.for_each(|(chunk, count)| self.push_bits(chunk as usize, count))
|
||||
}
|
||||
}
|
||||
|
||||
/// Push up to an usize worth of bits
|
||||
fn push_bits(&mut self, bits: usize, count: usize) {
|
||||
let bit_offset = self.bit_len & 7;
|
||||
let byte_count = (count + 7) / 8;
|
||||
|
||||
if bit_offset == 0 {
|
||||
if E::is_le() {
|
||||
self.bytes
|
||||
.extend_from_slice(&bits.to_le_bytes()[0..byte_count])
|
||||
} else {
|
||||
let bytes = (bits << (USIZE_BITS - bit_offset - count)).to_be_bytes();
|
||||
self.bytes.extend_from_slice(&bytes[0..byte_count])
|
||||
}
|
||||
self.bit_len += count;
|
||||
} else {
|
||||
if E::is_le() {
|
||||
let first_part_length = min(USIZE_SIZE - bit_offset, count);
|
||||
let first_part = get_bits_from_usize::<E>(bits, 0, first_part_length) as u8;
|
||||
|
||||
let last_written_byte = self.bytes.pop().unwrap_or(0);
|
||||
let merged_byte = last_written_byte | (first_part << bit_offset as u8);
|
||||
self.bytes.push(merged_byte);
|
||||
self.bit_len += first_part_length;
|
||||
|
||||
if first_part_length < count {
|
||||
let second_part = get_bits_from_usize::<E>(
|
||||
bits,
|
||||
first_part_length,
|
||||
count - first_part_length,
|
||||
);
|
||||
|
||||
self.push_bits(second_part, count - first_part_length);
|
||||
}
|
||||
} else {
|
||||
let first_part_length = min(USIZE_SIZE - bit_offset, count);
|
||||
let first_part = get_bits_from_usize::<LittleEndian>(
|
||||
bits,
|
||||
count - first_part_length,
|
||||
first_part_length,
|
||||
) as u8;
|
||||
|
||||
let last_written_byte = self.bytes.pop().unwrap_or(0);
|
||||
let merged_byte =
|
||||
last_written_byte | first_part << (8 - bit_offset - first_part_length) as u8;
|
||||
self.bytes.push(merged_byte);
|
||||
self.bit_len += first_part_length;
|
||||
|
||||
if first_part_length < count {
|
||||
let second_part =
|
||||
get_bits_from_usize::<LittleEndian>(bits, 0, count - first_part_length);
|
||||
self.push_bits(second_part, count - first_part_length);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Write a boolean into the buffer
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// # use bitbuffer::{BitReadBuffer, LittleEndian, Result};
|
||||
/// #
|
||||
/// # fn main() -> Result<()> {
|
||||
/// # use bitbuffer::{BitWriteStream, LittleEndian};
|
||||
///
|
||||
/// let mut stream = BitWriteStream::new(LittleEndian);
|
||||
/// stream.write_bool(true)?;
|
||||
/// #
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
/// ```
|
||||
#[inline]
|
||||
pub fn write_bool(&mut self, value: bool) -> Result<()> {
|
||||
self.push_bits(value as usize, 1);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Write an integer into the buffer
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// # use bitbuffer::{BitReadBuffer, LittleEndian, Result};
|
||||
/// #
|
||||
/// # fn main() -> Result<()> {
|
||||
/// # use bitbuffer::{BitWriteStream, LittleEndian};
|
||||
///
|
||||
/// let mut stream = BitWriteStream::new(LittleEndian);
|
||||
/// stream.write_int(123u16, 15)?;
|
||||
/// #
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
/// ```
|
||||
#[inline]
|
||||
pub fn write_int<T>(&mut self, value: T, count: usize) -> Result<()>
|
||||
where
|
||||
T: PrimInt + BitOrAssign + IsSigned + UncheckedPrimitiveInt + BitXor + IntoBytes,
|
||||
{
|
||||
let type_bit_size = size_of::<T>() * 8;
|
||||
|
||||
if type_bit_size < count {
|
||||
return Err(ReadError::TooManyBits {
|
||||
requested: count,
|
||||
max: type_bit_size,
|
||||
});
|
||||
}
|
||||
|
||||
if type_bit_size < USIZE_BITS {
|
||||
if T::is_signed() {
|
||||
todo!()
|
||||
} else {
|
||||
self.push_bits(value.into_usize_unchecked(), count);
|
||||
}
|
||||
} else {
|
||||
self.push_non_fit_bits(&value.into_bytes(), count)
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Write a float into the buffer
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// # use bitbuffer::{BitReadBuffer, LittleEndian, Result};
|
||||
/// #
|
||||
/// # fn main() -> Result<()> {
|
||||
/// # use bitbuffer::{BitWriteStream, LittleEndian};
|
||||
///
|
||||
/// let mut stream = BitWriteStream::new(LittleEndian);
|
||||
/// stream.write_float(123.15f32)?;
|
||||
/// #
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
/// ```
|
||||
#[inline]
|
||||
pub fn write_float<T>(&mut self, value: T) -> Result<()>
|
||||
where
|
||||
T: Float + UncheckedPrimitiveFloat,
|
||||
{
|
||||
if size_of::<T>() == 4 {
|
||||
if size_of::<T>() < USIZE_SIZE {
|
||||
self.push_bits(value.to_f32().unwrap().to_bits() as usize, 32);
|
||||
} else {
|
||||
self.push_non_fit_bits(&value.to_f32().unwrap().to_le_bytes(), 32)
|
||||
};
|
||||
} else {
|
||||
self.push_non_fit_bits(&value.to_f64().unwrap().to_le_bytes(), 64)
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Convert the write buffer into the written bytes
|
||||
pub fn finish(self) -> Vec<u8> {
|
||||
self.bytes
|
||||
}
|
||||
}
|
||||
|
|
@ -25,7 +25,9 @@ fn read_u8_le() {
|
|||
let buffer = BitReadBuffer::new(BYTES.to_vec(), LittleEndian);
|
||||
|
||||
assert_eq!(buffer.read_int::<u8>(0, 1).unwrap(), 0b1);
|
||||
assert_eq!(buffer.read_bool(0).unwrap(), true);
|
||||
assert_eq!(buffer.read_int::<u8>(1, 1).unwrap(), 0b0);
|
||||
assert_eq!(buffer.read_bool(1).unwrap(), false);
|
||||
assert_eq!(buffer.read_int::<u8>(2, 2).unwrap(), 0b01);
|
||||
assert_eq!(buffer.read_int::<u8>(0, 3).unwrap(), 0b101);
|
||||
assert_eq!(buffer.read_int::<u8>(7, 5).unwrap(), 0b1010_1);
|
||||
|
|
@ -43,6 +45,9 @@ fn read_u8_be() {
|
|||
assert_eq!(buffer.read_int::<u8>(0, 3).unwrap(), 0b101);
|
||||
assert_eq!(buffer.read_int::<u8>(7, 5).unwrap(), 0b1011_0);
|
||||
assert_eq!(buffer.read_int::<u8>(6, 5).unwrap(), 0b01_011);
|
||||
|
||||
assert_eq!(buffer.read_bool(0).unwrap(), true);
|
||||
assert_eq!(buffer.read_bool(8).unwrap(), false);
|
||||
}
|
||||
|
||||
#[test]
|
||||
115
tests/write_tests.rs
Normal file
115
tests/write_tests.rs
Normal file
|
|
@ -0,0 +1,115 @@
|
|||
use bitbuffer::{BigEndian, BitReadBuffer, BitReadStream, BitWriteStream, LittleEndian};
|
||||
|
||||
#[test]
|
||||
fn test_write_bool_le() {
|
||||
let mut stream = BitWriteStream::new(LittleEndian);
|
||||
|
||||
stream.write_bool(true).unwrap();
|
||||
stream.write_bool(true).unwrap();
|
||||
stream.write_bool(false).unwrap();
|
||||
stream.write_bool(true).unwrap();
|
||||
|
||||
let data = stream.finish();
|
||||
let mut read = BitReadStream::from(BitReadBuffer::new(data, LittleEndian));
|
||||
|
||||
assert_eq!(true, read.read_bool().unwrap());
|
||||
assert_eq!(true, read.read_bool().unwrap());
|
||||
assert_eq!(false, read.read_bool().unwrap());
|
||||
assert_eq!(true, read.read_bool().unwrap());
|
||||
|
||||
// 0 padded
|
||||
assert_eq!(false, read.read_bool().unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_write_bool_be() {
|
||||
let mut stream = BitWriteStream::new(BigEndian);
|
||||
|
||||
stream.write_bool(true).unwrap();
|
||||
stream.write_bool(true).unwrap();
|
||||
stream.write_bool(false).unwrap();
|
||||
stream.write_bool(true).unwrap();
|
||||
|
||||
let data = stream.finish();
|
||||
let mut read = BitReadStream::from(BitReadBuffer::new(data, BigEndian));
|
||||
|
||||
assert_eq!(true, read.read_bool().unwrap());
|
||||
assert_eq!(true, read.read_bool().unwrap());
|
||||
assert_eq!(false, read.read_bool().unwrap());
|
||||
assert_eq!(true, read.read_bool().unwrap());
|
||||
|
||||
// 0 padded
|
||||
assert_eq!(false, read.read_bool().unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_write_bool_number_le() {
|
||||
let mut stream = BitWriteStream::new(LittleEndian);
|
||||
|
||||
stream.write_bool(true).unwrap();
|
||||
stream.write_int(3253u16, 16).unwrap();
|
||||
stream.write_int(13253u64, 64).unwrap();
|
||||
|
||||
let data = stream.finish();
|
||||
let mut read = BitReadStream::from(BitReadBuffer::new(data, LittleEndian));
|
||||
|
||||
assert_eq!(true, read.read_bool().unwrap());
|
||||
assert_eq!(3253u16, read.read().unwrap());
|
||||
assert_eq!(13253u64, read.read().unwrap());
|
||||
|
||||
// 0 padded
|
||||
assert_eq!(false, read.read_bool().unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_write_bool_number_be() {
|
||||
let mut stream = BitWriteStream::new(BigEndian);
|
||||
|
||||
stream.write_bool(true).unwrap();
|
||||
stream.write_int(3253u16, 16).unwrap();
|
||||
stream.write_int(13253u64, 64).unwrap();
|
||||
|
||||
let data = stream.finish();
|
||||
let mut read = BitReadStream::from(BitReadBuffer::new(data, BigEndian));
|
||||
|
||||
assert_eq!(1u8, read.read_int(1).unwrap());
|
||||
assert_eq!(3253u16, read.read().unwrap());
|
||||
assert_eq!(13253u64, read.read().unwrap());
|
||||
|
||||
// 0 padded
|
||||
assert_eq!(false, read.read_bool().unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_write_float_le() {
|
||||
let mut stream = BitWriteStream::new(LittleEndian);
|
||||
|
||||
stream.write_bool(true).unwrap();
|
||||
stream.write_float(3253.12f32).unwrap();
|
||||
|
||||
let data = stream.finish();
|
||||
let mut read = BitReadStream::from(BitReadBuffer::new(data, LittleEndian));
|
||||
|
||||
assert_eq!(true, read.read_bool().unwrap());
|
||||
assert_eq!(3253.12f32, read.read().unwrap());
|
||||
|
||||
// 0 padded
|
||||
assert_eq!(false, read.read_bool().unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_write_float_be() {
|
||||
let mut stream = BitWriteStream::new(BigEndian);
|
||||
|
||||
stream.write_bool(true).unwrap();
|
||||
stream.write_float(3253.12f32).unwrap();
|
||||
|
||||
let data = stream.finish();
|
||||
let mut read = BitReadStream::from(BitReadBuffer::new(data, BigEndian));
|
||||
|
||||
assert_eq!(1u8, read.read_int(1).unwrap());
|
||||
assert_eq!(3253.12f32, read.read().unwrap());
|
||||
|
||||
// 0 padded
|
||||
assert_eq!(false, read.read_bool().unwrap());
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue