1
0
Fork 0
mirror of https://codeberg.org/icewind/bitbuffer.git synced 2026-06-03 16:44:06 +02:00

adds structs that allow lazy reading of values

This commit is contained in:
Robin Appelman 2019-03-03 17:58:39 +01:00
commit f96bd78f30
2 changed files with 81 additions and 2 deletions

View file

@ -61,10 +61,10 @@ use std::fmt;
use std::fmt::Display; use std::fmt::Display;
pub use std::string::FromUtf8Error; pub use std::string::FromUtf8Error;
pub use bitstream_reader_derive::{BitRead, BitReadSized}; pub use bitstream_reader_derive::{BitRead, BitReadSized, BitSize, BitSizeSized};
pub use buffer::BitBuffer; pub use buffer::BitBuffer;
pub use endianness::*; pub use endianness::*;
pub use read::{BitRead, BitReadSized}; pub use read::{BitRead, BitReadSized, BitSize, BitSizeSized, LazyBitRead, LazyBitReadSized};
pub use stream::BitStream; pub use stream::BitStream;
mod buffer; mod buffer;
@ -142,3 +142,15 @@ impl Error for ReadError {
/// 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, ReadError>;
/// Get the number of bits required to read a type from stream
#[inline(always)]
pub fn bit_size_of<T: BitSize>() -> usize {
T::bit_size()
}
/// Get the number of bits required to read a type from stream
#[inline(always)]
pub fn bit_size_of_sized<T: BitSizeSized>(size: usize) -> usize {
T::bit_size(size)
}

View file

@ -1,6 +1,9 @@
use crate::{BitStream, Endianness, Result}; use crate::{BitStream, Endianness, Result};
use std::collections::HashMap; use std::collections::HashMap;
use std::hash::Hash; use std::hash::Hash;
use std::marker::PhantomData;
use std::fmt::{Debug, Formatter};
use std::cell::RefCell;
/// Trait for types that can be read from a stream without requiring the size to be configured /// Trait for types that can be read from a stream without requiring the size to be configured
/// ///
@ -383,3 +386,67 @@ impl<K: BitSize, T: BitSize> BitSizeSized for HashMap<K, T> {
size * (K::bit_size() + T::bit_size()) size * (K::bit_size() + T::bit_size())
} }
} }
#[derive(Clone, Debug)]
pub struct LazyBitRead<T: BitRead<E> + BitSize, E: Endianness> {
source: RefCell<BitStream<E>>,
inner_type: PhantomData<T>
}
impl<T: BitRead<E> + BitSize, E: Endianness> LazyBitRead<T, E> {
#[inline(always)]
fn read(self) -> Result<T> {
self.source.borrow_mut().read::<T>()
}
}
impl<T: BitRead<E> + BitSize, E: Endianness> BitRead<E> for LazyBitRead<T, E> {
#[inline(always)]
fn read(stream: &mut BitStream<E>) -> Result<Self> {
let bit_size = T::bit_size();
Ok(LazyBitRead {
source: RefCell::new(stream.read_bits(bit_size)?),
inner_type: PhantomData
})
}
}
impl<T: BitRead<E> + BitSize, E: Endianness> BitSize for LazyBitRead<T, E> {
#[inline(always)]
fn bit_size() -> usize {
T::bit_size()
}
}
#[derive(Clone, Debug)]
pub struct LazyBitReadSized<T: BitReadSized<E> + BitSizeSized, E: Endianness> {
source: RefCell<BitStream<E>>,
size: usize,
inner_type: PhantomData<T>
}
impl<T: BitReadSized<E> + BitSizeSized, E: Endianness> LazyBitReadSized<T, E> {
#[inline(always)]
fn value(self) -> Result<T> {
self.source.borrow_mut().read_sized::<T>(self.size)
}
}
impl<T: BitReadSized<E> + BitSizeSized, E: Endianness> BitReadSized<E> for LazyBitReadSized<T, E> {
#[inline(always)]
fn read(stream: &mut BitStream<E>, size: usize) -> Result<Self> {
let bit_size = T::bit_size(size);
Ok(LazyBitReadSized {
source: RefCell::new(stream.read_bits(bit_size)?),
inner_type: PhantomData,
size
})
}
}
impl<T: BitReadSized<E> + BitSizeSized, E: Endianness> BitSizeSized for LazyBitReadSized<T, E> {
#[inline(always)]
fn bit_size(size: usize) -> usize {
T::bit_size(size)
}
}