mirror of
https://codeberg.org/icewind/bitbuffer.git
synced 2026-06-03 16:44:06 +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 buffer::{BitBuffer, IsPadded, NonPadded, Padded};
|
||||||
pub use endianness::*;
|
pub use endianness::*;
|
||||||
pub use read::{Read, ReadSize};
|
pub use read::{Read, ReadSized};
|
||||||
pub use std::string::FromUtf8Error;
|
pub use std::string::FromUtf8Error;
|
||||||
pub use stream::BitStream;
|
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
|
/// 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
|
/// Read the type from stream
|
||||||
fn read(stream: &mut BitStream<'a, E, P>, size: usize) -> Result<Self>;
|
fn read(stream: &mut BitStream<'a, E, P>, size: usize) -> Result<Self>;
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! impl_read_int_sized {
|
macro_rules! impl_read_int_sized {
|
||||||
($type:ty) => {
|
($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)]
|
#[inline(always)]
|
||||||
fn read(stream: &mut BitStream<'a, E, P>, size: usize) -> Result<$type> {
|
fn read(stream: &mut BitStream<'a, E, P>, size: usize) -> Result<$type> {
|
||||||
stream.read_int::<$type>(size)
|
stream.read_int::<$type>(size)
|
||||||
|
|
@ -84,9 +84,38 @@ impl_read_int_sized!(i32);
|
||||||
impl_read_int_sized!(i64);
|
impl_read_int_sized!(i64);
|
||||||
impl_read_int_sized!(i128);
|
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)]
|
#[inline(always)]
|
||||||
fn read(stream: &mut BitStream<'a, E, P>, size: usize) -> Result<String> {
|
fn read(stream: &mut BitStream<'a, E, P>, size: usize) -> Result<String> {
|
||||||
stream.read_string(Some(size))
|
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::endianness::Endianness;
|
||||||
use crate::is_signed::IsSigned;
|
use crate::is_signed::IsSigned;
|
||||||
use crate::BitBuffer;
|
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
|
/// 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
|
/// 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)
|
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);
|
assert_eq!(-0b0010_1100_1001_1001, c);
|
||||||
let d: bool = stream.read().unwrap();
|
let d: bool = stream.read().unwrap();
|
||||||
assert_eq!(true, d);
|
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]
|
#[test]
|
||||||
fn read_sized_trait() {
|
fn read_sized_trait() {
|
||||||
let buffer = BitBuffer::new(BYTES, BigEndian);
|
let buffer = BitBuffer::new(BYTES, BigEndian);
|
||||||
let mut stream = BitStream::new(buffer, None, None);
|
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);
|
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
|
// for bench on nightly
|
||||||
//fn read_perf<P: IsPadded>(buffer: BitBuffer<LittleEndian, P>) -> u16 {
|
//fn read_perf<P: IsPadded>(buffer: BitBuffer<LittleEndian, P>) -> u16 {
|
||||||
// let size = 5;
|
// let size = 5;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue