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:
parent
fe91298c1f
commit
f96bd78f30
2 changed files with 81 additions and 2 deletions
16
src/lib.rs
16
src/lib.rs
|
|
@ -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)
|
||||||
|
}
|
||||||
67
src/read.rs
67
src/read.rs
|
|
@ -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
|
||||||
///
|
///
|
||||||
|
|
@ -382,4 +385,68 @@ impl<K: BitSize, T: BitSize> BitSizeSized for HashMap<K, T> {
|
||||||
fn bit_size(size: usize) -> usize {
|
fn bit_size(size: usize) -> usize {
|
||||||
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)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue