mirror of
https://codeberg.org/icewind/bitbuffer.git
synced 2026-06-03 08:34:07 +02:00
add write bytes and string and rename ReadError -> BitError
This commit is contained in:
parent
bce35aeb32
commit
e43b0b6bb2
7 changed files with 147 additions and 58 deletions
|
|
@ -9,6 +9,7 @@ repository = "https://github.com/icewind1991/bitbuffer"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
num-traits = "0.2"
|
num-traits = "0.2"
|
||||||
|
err-derive = "0.2.2"
|
||||||
bitbuffer_derive = { version = "0.7", path = "bitbuffer_derive" }
|
bitbuffer_derive = { version = "0.7", path = "bitbuffer_derive" }
|
||||||
memchr = "2.2"
|
memchr = "2.2"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -387,7 +387,7 @@ fn parse(data: Data, struct_name: &Ident, attrs: &[Attribute], unchecked: bool)
|
||||||
Ok(match discriminant {
|
Ok(match discriminant {
|
||||||
#(#match_arms)*
|
#(#match_arms)*
|
||||||
_ => {
|
_ => {
|
||||||
return Err(::bitbuffer::ReadError::UnmatchedDiscriminant{discriminant, enum_name: #enum_name.to_string()})
|
return Err(::bitbuffer::BitError::UnmatchedDiscriminant{discriminant, enum_name: #enum_name.to_string()})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
76
src/lib.rs
76
src/lib.rs
|
|
@ -54,9 +54,7 @@
|
||||||
|
|
||||||
#![warn(missing_docs)]
|
#![warn(missing_docs)]
|
||||||
|
|
||||||
use std::error::Error;
|
use err_derive::Error;
|
||||||
use std::fmt;
|
|
||||||
use std::fmt::Display;
|
|
||||||
pub use std::string::FromUtf8Error;
|
pub use std::string::FromUtf8Error;
|
||||||
|
|
||||||
pub use bitbuffer_derive::{BitRead, BitReadSized};
|
pub use bitbuffer_derive::{BitRead, BitReadSized};
|
||||||
|
|
@ -74,9 +72,14 @@ mod readstream;
|
||||||
mod writestream;
|
mod writestream;
|
||||||
|
|
||||||
/// Errors that can be returned when trying to read from a buffer
|
/// Errors that can be returned when trying to read from a buffer
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Error)]
|
||||||
pub enum ReadError {
|
pub enum BitError {
|
||||||
/// Too many bits requested to fit in the requested data type
|
/// Too many bits requested to fit in the requested data type
|
||||||
|
#[error(
|
||||||
|
display = "Too many bits requested to fit in the requested data type, requested to read {} bits while only {} fit in the datatype",
|
||||||
|
requested,
|
||||||
|
max
|
||||||
|
)]
|
||||||
TooManyBits {
|
TooManyBits {
|
||||||
/// The number of bits requested to read
|
/// The number of bits requested to read
|
||||||
requested: usize,
|
requested: usize,
|
||||||
|
|
@ -84,6 +87,11 @@ pub enum ReadError {
|
||||||
max: usize,
|
max: usize,
|
||||||
},
|
},
|
||||||
/// Not enough data in the buffer to read all requested bits
|
/// Not enough data in the buffer to read all requested bits
|
||||||
|
#[error(
|
||||||
|
display = "Not enough data in the buffer to read all requested bits, requested to read {} bits while only {} bits are left",
|
||||||
|
requested,
|
||||||
|
bits_left
|
||||||
|
)]
|
||||||
NotEnoughData {
|
NotEnoughData {
|
||||||
/// The number of bits requested to read
|
/// The number of bits requested to read
|
||||||
requested: usize,
|
requested: usize,
|
||||||
|
|
@ -91,6 +99,11 @@ pub enum ReadError {
|
||||||
bits_left: usize,
|
bits_left: usize,
|
||||||
},
|
},
|
||||||
/// The requested position is outside the bounds of the stream or buffer
|
/// The requested position is outside the bounds of the stream or buffer
|
||||||
|
#[error(
|
||||||
|
display = "The requested position is outside the bounds of the stream, requested position {} while the stream or buffer is only {} bits long",
|
||||||
|
pos,
|
||||||
|
size
|
||||||
|
)]
|
||||||
IndexOutOfBounds {
|
IndexOutOfBounds {
|
||||||
/// The requested position
|
/// The requested position
|
||||||
pos: usize,
|
pos: usize,
|
||||||
|
|
@ -98,6 +111,11 @@ pub enum ReadError {
|
||||||
size: usize,
|
size: usize,
|
||||||
},
|
},
|
||||||
/// Unmatched discriminant found while trying to read an enum
|
/// Unmatched discriminant found while trying to read an enum
|
||||||
|
#[error(
|
||||||
|
display = "Unmatched discriminant '{}' found while trying to read enum '{}'",
|
||||||
|
discriminant,
|
||||||
|
enum_name
|
||||||
|
)]
|
||||||
UnmatchedDiscriminant {
|
UnmatchedDiscriminant {
|
||||||
/// The read discriminant
|
/// The read discriminant
|
||||||
discriminant: usize,
|
discriminant: usize,
|
||||||
|
|
@ -105,42 +123,24 @@ pub enum ReadError {
|
||||||
enum_name: String,
|
enum_name: String,
|
||||||
},
|
},
|
||||||
/// The read slice of bytes are not valid utf8
|
/// The read slice of bytes are not valid utf8
|
||||||
Utf8Error(FromUtf8Error),
|
#[error(display = "The read slice of bytes are not valid utf8: {}", _0)]
|
||||||
}
|
Utf8Error(#[error(source)] FromUtf8Error),
|
||||||
|
/// The string that was requested to be written does not fit in the specified fixed length
|
||||||
impl Display for ReadError {
|
#[error(
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
display = "The string that was requested to be written does not fit in the specified fixed length, string is {} bytes long, while a size of {} has been specified",
|
||||||
match self {
|
string_length,
|
||||||
ReadError::TooManyBits { requested, max } =>
|
requested_length
|
||||||
write!(f, "Too many bits requested to fit in the requested data type, requested to read {} bits while only {} fit in the datatype", requested, max),
|
)]
|
||||||
ReadError::NotEnoughData { requested, bits_left } =>
|
StringToLong {
|
||||||
write!(f, "Not enough data in the buffer to read all requested bits, requested to read {} bits while only {} bits are left", requested, bits_left),
|
/// Length of the string that was requested to be written
|
||||||
ReadError::IndexOutOfBounds { pos, size } =>
|
string_length: usize,
|
||||||
write!(f, "The requested position is outside the bounds of the stream, requested position {} while the stream or buffer is only {} bits long", pos, size),
|
/// The requested fixed size to encode the string into
|
||||||
ReadError::UnmatchedDiscriminant { discriminant, enum_name } =>
|
requested_length: usize,
|
||||||
write!(f, "Unmatched discriminant '{}' found while trying to read enum '{}'", discriminant, enum_name),
|
},
|
||||||
ReadError::Utf8Error(err) => err.fmt(f)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<FromUtf8Error> for ReadError {
|
|
||||||
fn from(err: FromUtf8Error) -> ReadError {
|
|
||||||
ReadError::Utf8Error(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Error for ReadError {
|
|
||||||
fn cause(&self) -> Option<&dyn Error> {
|
|
||||||
match self {
|
|
||||||
ReadError::Utf8Error(err) => Some(err),
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Either the read bits in the requested format or a [`ReadError`](enum.ReadError.html)
|
/// Either the read bits in the requested format or a [`ReadError`](enum.ReadError.html)
|
||||||
pub type Result<T> = std::result::Result<T, ReadError>;
|
pub type Result<T> = std::result::Result<T, BitError>;
|
||||||
|
|
||||||
/// Get the number of bits required to read a type from stream
|
/// Get the number of bits required to read a type from stream
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ use num_traits::{Float, PrimInt};
|
||||||
|
|
||||||
use crate::endianness::Endianness;
|
use crate::endianness::Endianness;
|
||||||
use crate::num_traits::{IsSigned, UncheckedPrimitiveFloat, UncheckedPrimitiveInt};
|
use crate::num_traits::{IsSigned, UncheckedPrimitiveFloat, UncheckedPrimitiveInt};
|
||||||
use crate::{ReadError, Result};
|
use crate::{BitError, Result};
|
||||||
use std::convert::TryInto;
|
use std::convert::TryInto;
|
||||||
|
|
||||||
const USIZE_SIZE: usize = size_of::<usize>();
|
const USIZE_SIZE: usize = size_of::<usize>();
|
||||||
|
|
@ -176,7 +176,7 @@ where
|
||||||
Ok(shifted & 0b1000_0000u8 == 0b1000_0000u8)
|
Ok(shifted & 0b1000_0000u8 == 0b1000_0000u8)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Err(ReadError::NotEnoughData {
|
Err(BitError::NotEnoughData {
|
||||||
requested: 1,
|
requested: 1,
|
||||||
bits_left: self.bit_len().saturating_sub(position),
|
bits_left: self.bit_len().saturating_sub(position),
|
||||||
})
|
})
|
||||||
|
|
@ -229,7 +229,7 @@ where
|
||||||
let type_bit_size = size_of::<T>() * 8;
|
let type_bit_size = size_of::<T>() * 8;
|
||||||
|
|
||||||
if type_bit_size < count {
|
if type_bit_size < count {
|
||||||
return Err(ReadError::TooManyBits {
|
return Err(BitError::TooManyBits {
|
||||||
requested: count,
|
requested: count,
|
||||||
max: type_bit_size,
|
max: type_bit_size,
|
||||||
});
|
});
|
||||||
|
|
@ -237,12 +237,12 @@ where
|
||||||
|
|
||||||
if position + count > self.bit_len() {
|
if position + count > self.bit_len() {
|
||||||
return if position > self.bit_len() {
|
return if position > self.bit_len() {
|
||||||
Err(ReadError::IndexOutOfBounds {
|
Err(BitError::IndexOutOfBounds {
|
||||||
pos: position,
|
pos: position,
|
||||||
size: self.bit_len(),
|
size: self.bit_len(),
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
Err(ReadError::NotEnoughData {
|
Err(BitError::NotEnoughData {
|
||||||
requested: count,
|
requested: count,
|
||||||
bits_left: self.bit_len() - position,
|
bits_left: self.bit_len() - position,
|
||||||
})
|
})
|
||||||
|
|
@ -363,12 +363,12 @@ where
|
||||||
pub fn read_bytes(&self, position: usize, byte_count: usize) -> Result<Vec<u8>> {
|
pub fn read_bytes(&self, position: usize, byte_count: usize) -> Result<Vec<u8>> {
|
||||||
if position + byte_count * 8 > self.bit_len() {
|
if position + byte_count * 8 > self.bit_len() {
|
||||||
if position > self.bit_len() {
|
if position > self.bit_len() {
|
||||||
return Err(ReadError::IndexOutOfBounds {
|
return Err(BitError::IndexOutOfBounds {
|
||||||
pos: position,
|
pos: position,
|
||||||
size: self.bit_len(),
|
size: self.bit_len(),
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
return Err(ReadError::NotEnoughData {
|
return Err(BitError::NotEnoughData {
|
||||||
requested: byte_count * 8,
|
requested: byte_count * 8,
|
||||||
bits_left: self.bit_len() - position,
|
bits_left: self.bit_len() - position,
|
||||||
});
|
});
|
||||||
|
|
@ -453,7 +453,7 @@ where
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
let bytes = self.read_string_bytes(position)?;
|
let bytes = self.read_string_bytes(position)?;
|
||||||
String::from_utf8(bytes).map_err(ReadError::from)
|
String::from_utf8(bytes).map_err(BitError::from)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -535,12 +535,12 @@ where
|
||||||
let type_bit_size = size_of::<T>() * 8;
|
let type_bit_size = size_of::<T>() * 8;
|
||||||
if position + type_bit_size > self.bit_len() {
|
if position + type_bit_size > self.bit_len() {
|
||||||
if position > self.bit_len() {
|
if position > self.bit_len() {
|
||||||
return Err(ReadError::IndexOutOfBounds {
|
return Err(BitError::IndexOutOfBounds {
|
||||||
pos: position,
|
pos: position,
|
||||||
size: self.bit_len(),
|
size: self.bit_len(),
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
return Err(ReadError::NotEnoughData {
|
return Err(BitError::NotEnoughData {
|
||||||
requested: size_of::<T>() * 8,
|
requested: size_of::<T>() * 8,
|
||||||
bits_left: self.bit_len() - position,
|
bits_left: self.bit_len() - position,
|
||||||
});
|
});
|
||||||
|
|
@ -571,7 +571,7 @@ where
|
||||||
|
|
||||||
pub(crate) fn get_sub_buffer(&self, bit_len: usize) -> Result<Self> {
|
pub(crate) fn get_sub_buffer(&self, bit_len: usize) -> Result<Self> {
|
||||||
if bit_len > self.bit_len() {
|
if bit_len > self.bit_len() {
|
||||||
return Err(ReadError::NotEnoughData {
|
return Err(BitError::NotEnoughData {
|
||||||
requested: bit_len,
|
requested: bit_len,
|
||||||
bits_left: self.bit_len(),
|
bits_left: self.bit_len(),
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ use num_traits::{Float, PrimInt};
|
||||||
use crate::endianness::Endianness;
|
use crate::endianness::Endianness;
|
||||||
use crate::num_traits::{IsSigned, UncheckedPrimitiveFloat, UncheckedPrimitiveInt};
|
use crate::num_traits::{IsSigned, UncheckedPrimitiveFloat, UncheckedPrimitiveInt};
|
||||||
use crate::BitReadBuffer;
|
use crate::BitReadBuffer;
|
||||||
use crate::{BitRead, BitReadSized, ReadError, Result};
|
use crate::{BitError, BitRead, BitReadSized, Result};
|
||||||
use std::cmp::min;
|
use std::cmp::min;
|
||||||
|
|
||||||
/// Stream that provides an easy way to iterate trough a [`BitBuffer`]
|
/// Stream that provides an easy way to iterate trough a [`BitBuffer`]
|
||||||
|
|
@ -303,7 +303,7 @@ where
|
||||||
|
|
||||||
let result = self.buffer.read_string(self.pos, byte_len).map_err(|err| {
|
let result = self.buffer.read_string(self.pos, byte_len).map_err(|err| {
|
||||||
// still advance the stream on malformed utf8
|
// still advance the stream on malformed utf8
|
||||||
if let ReadError::Utf8Error(err) = &err {
|
if let BitError::Utf8Error(err) = &err {
|
||||||
self.pos += match byte_len {
|
self.pos += match byte_len {
|
||||||
Some(len) => len * 8,
|
Some(len) => len * 8,
|
||||||
None => min((err.as_bytes().len() + 1) * 8, max_length),
|
None => min((err.as_bytes().len() + 1) * 8, max_length),
|
||||||
|
|
@ -408,7 +408,7 @@ where
|
||||||
self.pos += count;
|
self.pos += count;
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
Err(ReadError::NotEnoughData {
|
Err(BitError::NotEnoughData {
|
||||||
requested: count,
|
requested: count,
|
||||||
bits_left: self.bits_left(),
|
bits_left: self.bits_left(),
|
||||||
})
|
})
|
||||||
|
|
@ -444,7 +444,7 @@ where
|
||||||
/// [`ReadError::IndexOutOfBounds`]: enum.ReadError.html#variant.IndexOutOfBounds
|
/// [`ReadError::IndexOutOfBounds`]: enum.ReadError.html#variant.IndexOutOfBounds
|
||||||
pub fn set_pos(&mut self, pos: usize) -> Result<()> {
|
pub fn set_pos(&mut self, pos: usize) -> Result<()> {
|
||||||
if pos > self.bit_len() {
|
if pos > self.bit_len() {
|
||||||
return Err(ReadError::IndexOutOfBounds {
|
return Err(BitError::IndexOutOfBounds {
|
||||||
pos,
|
pos,
|
||||||
size: self.bit_len(),
|
size: self.bit_len(),
|
||||||
});
|
});
|
||||||
|
|
@ -642,7 +642,7 @@ where
|
||||||
/// Check if we can read a number of bits from the stream
|
/// Check if we can read a number of bits from the stream
|
||||||
pub fn check_read(&self, count: usize) -> Result<()> {
|
pub fn check_read(&self, count: usize) -> Result<()> {
|
||||||
if self.bits_left() < count {
|
if self.bits_left() < count {
|
||||||
Err(ReadError::NotEnoughData {
|
Err(BitError::NotEnoughData {
|
||||||
requested: count,
|
requested: count,
|
||||||
bits_left: self.bits_left(),
|
bits_left: self.bits_left(),
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ use std::ops::{BitOrAssign, BitXor};
|
||||||
|
|
||||||
use crate::endianness::Endianness;
|
use crate::endianness::Endianness;
|
||||||
use crate::num_traits::{IntoBytes, IsSigned, UncheckedPrimitiveFloat, UncheckedPrimitiveInt};
|
use crate::num_traits::{IntoBytes, IsSigned, UncheckedPrimitiveFloat, UncheckedPrimitiveInt};
|
||||||
use crate::{ReadError, Result};
|
use crate::{BitError, Result};
|
||||||
|
|
||||||
const USIZE_SIZE: usize = size_of::<usize>();
|
const USIZE_SIZE: usize = size_of::<usize>();
|
||||||
const USIZE_BITS: usize = USIZE_SIZE * 8;
|
const USIZE_BITS: usize = USIZE_SIZE * 8;
|
||||||
|
|
@ -79,7 +79,6 @@ where
|
||||||
I: ExactSizeIterator,
|
I: ExactSizeIterator,
|
||||||
I: DoubleEndedIterator<Item = u8>,
|
I: DoubleEndedIterator<Item = u8>,
|
||||||
{
|
{
|
||||||
debug_assert!(bits.len() == count / 8);
|
|
||||||
let counts = repeat(8)
|
let counts = repeat(8)
|
||||||
.take(bits.len() - 1)
|
.take(bits.len() - 1)
|
||||||
.chain(once(count - (bits.len() - 1) * 8));
|
.chain(once(count - (bits.len() - 1) * 8));
|
||||||
|
|
@ -160,7 +159,7 @@ where
|
||||||
let type_bit_size = size_of::<T>() * 8;
|
let type_bit_size = size_of::<T>() * 8;
|
||||||
|
|
||||||
if type_bit_size < count {
|
if type_bit_size < count {
|
||||||
return Err(ReadError::TooManyBits {
|
return Err(BitError::TooManyBits {
|
||||||
requested: count,
|
requested: count,
|
||||||
max: type_bit_size,
|
max: type_bit_size,
|
||||||
});
|
});
|
||||||
|
|
@ -213,6 +212,74 @@ where
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Write a number of bytes into the buffer
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// # use bitbuffer::{BitReadBuffer, LittleEndian, Result};
|
||||||
|
/// #
|
||||||
|
/// # fn main() -> Result<()> {
|
||||||
|
/// # use bitbuffer::{BitWriteStream, LittleEndian};
|
||||||
|
///
|
||||||
|
/// let mut stream = BitWriteStream::new(LittleEndian);
|
||||||
|
/// stream.write_bytes(&[0, 1, 2 ,3])?;
|
||||||
|
/// #
|
||||||
|
/// # Ok(())
|
||||||
|
/// # }
|
||||||
|
/// ```
|
||||||
|
#[inline]
|
||||||
|
pub fn write_bytes(&mut self, bytes: &[u8]) -> Result<()> {
|
||||||
|
self.push_non_fit_bits(bytes.iter().copied(), bytes.len() * 8);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Add a number of padding bytes
|
||||||
|
fn zero_pad(&mut self, count: usize) {
|
||||||
|
// since partly written bytes are already 0 padded, we don't need to go trough all the hoop
|
||||||
|
// of merging the padding bits into the partly written bytes
|
||||||
|
// (also because x | 0 == x)
|
||||||
|
self.bytes.resize(self.bytes.len() + count, 0);
|
||||||
|
self.bit_len += count * 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Write a string into the buffer
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// # use bitbuffer::{BitReadBuffer, LittleEndian, Result};
|
||||||
|
/// #
|
||||||
|
/// # fn main() -> Result<()> {
|
||||||
|
/// # use bitbuffer::{BitWriteStream, LittleEndian};
|
||||||
|
///
|
||||||
|
/// let mut stream = BitWriteStream::new(LittleEndian);
|
||||||
|
/// stream.write_string("zero terminated string", None)?;
|
||||||
|
/// stream.write_string("fixed size string, zero padded", Some(64))?;
|
||||||
|
/// #
|
||||||
|
/// # Ok(())
|
||||||
|
/// # }
|
||||||
|
/// ```
|
||||||
|
pub fn write_string(&mut self, string: &str, length: Option<usize>) -> Result<()> {
|
||||||
|
match length {
|
||||||
|
Some(length) => {
|
||||||
|
if length < string.len() {
|
||||||
|
return Err(BitError::StringToLong {
|
||||||
|
string_length: string.len(),
|
||||||
|
requested_length: length,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
self.write_bytes(&string.as_bytes())?;
|
||||||
|
self.zero_pad(length - string.len());
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
self.write_bytes(&string.as_bytes())?;
|
||||||
|
self.zero_pad(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
/// Convert the write buffer into the written bytes
|
/// Convert the write buffer into the written bytes
|
||||||
pub fn finish(self) -> Vec<u8> {
|
pub fn finish(self) -> Vec<u8> {
|
||||||
self.bytes
|
self.bytes
|
||||||
|
|
|
||||||
|
|
@ -113,3 +113,24 @@ fn test_write_float_be() {
|
||||||
// 0 padded
|
// 0 padded
|
||||||
assert_eq!(false, read.read_bool().unwrap());
|
assert_eq!(false, read.read_bool().unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_write_string_le() {
|
||||||
|
let mut stream = BitWriteStream::new(LittleEndian);
|
||||||
|
|
||||||
|
stream.write_bool(true).unwrap();
|
||||||
|
stream.write_string("null terminated", None).unwrap();
|
||||||
|
stream.write_string("fixed length1", Some(16)).unwrap();
|
||||||
|
stream.write_string("fixed length2", Some(16)).unwrap();
|
||||||
|
|
||||||
|
let data = stream.finish();
|
||||||
|
let mut read = BitReadStream::from(BitReadBuffer::new(data, LittleEndian));
|
||||||
|
|
||||||
|
assert_eq!(true, read.read_bool().unwrap());
|
||||||
|
assert_eq!("null terminated", read.read_string(None).unwrap());
|
||||||
|
assert_eq!("fixed length1", read.read_string(Some(16)).unwrap());
|
||||||
|
assert_eq!("fixed length2", read.read_string(Some(16)).unwrap());
|
||||||
|
|
||||||
|
// 0 padded
|
||||||
|
assert_eq!(false, read.read_bool().unwrap());
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue