mirror of
https://codeberg.org/icewind/bitbuffer.git
synced 2026-06-04 00:54:07 +02:00
implement read for Option<T> and Vec<T>
This commit is contained in:
parent
ad56d05dbe
commit
8d09284040
4 changed files with 67 additions and 7 deletions
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
pub use buffer::{BitBuffer, IsPadded, NonPadded, Padded};
|
||||
pub use endianness::*;
|
||||
pub use read::{Read, ReadSize};
|
||||
pub use read::{Read, ReadSized};
|
||||
pub use std::string::FromUtf8Error;
|
||||
pub use stream::BitStream;
|
||||
|
||||
|
|
|
|||
35
src/read.rs
35
src/read.rs
|
|
@ -57,14 +57,14 @@ impl<'a, E: Endianness, P: IsPadded> Read<'a, E, P> for String {
|
|||
}
|
||||
|
||||
/// Trait for types that can be read from a stream wit requiring the size to be configured
|
||||
pub trait ReadSize<'a, E: Endianness, P: IsPadded>: Sized {
|
||||
pub trait ReadSized<'a, E: Endianness, P: IsPadded>: Sized {
|
||||
/// Read the type from stream
|
||||
fn read(stream: &mut BitStream<'a, E, P>, size: usize) -> Result<Self>;
|
||||
}
|
||||
|
||||
macro_rules! impl_read_int_sized {
|
||||
($type:ty) => {
|
||||
impl<'a, E: Endianness, P: IsPadded> ReadSize<'a, E, P> for $type {
|
||||
impl<'a, E: Endianness, P: IsPadded> ReadSized<'a, E, P> for $type {
|
||||
#[inline(always)]
|
||||
fn read(stream: &mut BitStream<'a, E, P>, size: usize) -> Result<$type> {
|
||||
stream.read_int::<$type>(size)
|
||||
|
|
@ -84,9 +84,38 @@ impl_read_int_sized!(i32);
|
|||
impl_read_int_sized!(i64);
|
||||
impl_read_int_sized!(i128);
|
||||
|
||||
impl<'a, E: Endianness, P: IsPadded> ReadSize<'a, E, P> for String {
|
||||
impl<'a, E: Endianness, P: IsPadded> ReadSized<'a, E, P> for String {
|
||||
#[inline(always)]
|
||||
fn read(stream: &mut BitStream<'a, E, P>, size: usize) -> Result<String> {
|
||||
stream.read_string(Some(size))
|
||||
}
|
||||
}
|
||||
|
||||
/// Read a boolean, if true, read the value, else return None
|
||||
impl<'a, E: Endianness, P: IsPadded, T: Read<'a, E, P>> Read<'a, E, P> for Option<T> {
|
||||
fn read(stream: &mut BitStream<'a, E, P>) -> Result<Self> {
|
||||
if stream.read()? {
|
||||
Ok(Some(stream.read()?))
|
||||
} else {
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, E: Endianness, P: IsPadded, T: Read<'a, E, P>> ReadSized<'a, E, P> for Vec<T> {
|
||||
fn read(stream: &mut BitStream<'a, E, P>, size: usize) -> Result<Self> {
|
||||
let mut vec = Vec::with_capacity(size);
|
||||
for _ in 0..size {
|
||||
vec.push(stream.read()?)
|
||||
}
|
||||
Ok(vec)
|
||||
}
|
||||
}
|
||||
|
||||
// Once we have something like https://github.com/rust-lang/rfcs/issues/1053 we can do this optimization
|
||||
//impl<'a, E: Endianness, P: IsPadded> ReadSized<'a, E, P> for Vec<u8> {
|
||||
// #[inline(always)]
|
||||
// fn read(stream: &mut BitStream<'a, E, P>, size: usize) -> Result<Self> {
|
||||
// stream.read_bytes(size)
|
||||
// }
|
||||
//}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ use crate::buffer::IsPadded;
|
|||
use crate::endianness::Endianness;
|
||||
use crate::is_signed::IsSigned;
|
||||
use crate::BitBuffer;
|
||||
use crate::{Read, ReadError, ReadSize, Result};
|
||||
use crate::{Read, ReadError, ReadSized, Result};
|
||||
|
||||
/// Stream that provides an easy way to iterate trough a BitBuffer
|
||||
///
|
||||
|
|
@ -416,7 +416,7 @@ where
|
|||
}
|
||||
|
||||
/// Read a value based on the provided type and size
|
||||
pub fn read_size<T: ReadSize<'a, E, S>>(&mut self, size: usize) -> Result<T> {
|
||||
pub fn read_sized<T: ReadSized<'a, E, S>>(&mut self, size: usize) -> Result<T> {
|
||||
T::read(self, size)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
33
src/tests.rs
33
src/tests.rs
|
|
@ -236,16 +236,47 @@ fn read_trait() {
|
|||
assert_eq!(-0b0010_1100_1001_1001, c);
|
||||
let d: bool = stream.read().unwrap();
|
||||
assert_eq!(true, d);
|
||||
let e: Option<u8> = stream.read().unwrap();
|
||||
assert_eq!(None, e);
|
||||
stream.set_pos(0).unwrap();
|
||||
let f: Option<u8> = stream.read().unwrap();
|
||||
assert_eq!(Some(0b011_0101_0), f);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn read_sized_trait() {
|
||||
let buffer = BitBuffer::new(BYTES, BigEndian);
|
||||
let mut stream = BitStream::new(buffer, None, None);
|
||||
let a: u8 = stream.read_size(4).unwrap();
|
||||
let a: u8 = stream.read_sized(4).unwrap();
|
||||
assert_eq!(0b1011, a);
|
||||
stream.set_pos(0).unwrap();
|
||||
let vec: Vec<u16> = stream.read_sized(3).unwrap();
|
||||
assert_eq!(
|
||||
vec![
|
||||
0b1011_0101_0110_1010,
|
||||
0b1010_1100_1001_1001,
|
||||
0b1001_1001_1001_1001
|
||||
],
|
||||
vec
|
||||
);
|
||||
stream.set_pos(0).unwrap();
|
||||
let vec: Vec<u8> = stream.read_sized(3).unwrap();
|
||||
assert_eq!(vec![0b1011_0101, 0b0110_1010, 0b1010_1100], vec);
|
||||
}
|
||||
|
||||
//0b1011_0101,
|
||||
// 0b0110_1010,
|
||||
// 0b1010_1100,
|
||||
// 0b1001_1001,
|
||||
// 0b1001_1001,
|
||||
// 0b1001_1001,
|
||||
// 0b1001_1001,
|
||||
// 0b1110_0111,
|
||||
// 0b1001_1001,
|
||||
// 0b1001_1001,
|
||||
// 0b1001_1001,
|
||||
// 0b1110_0111,
|
||||
|
||||
// for bench on nightly
|
||||
//fn read_perf<P: IsPadded>(buffer: BitBuffer<LittleEndian, P>) -> u16 {
|
||||
// let size = 5;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue