mirror of
https://codeberg.org/icewind/bitbuffer.git
synced 2026-06-04 00:54:07 +02:00
add traits for determining the number of bits required to read a type
This commit is contained in:
parent
be689d05a4
commit
fe95592d57
1 changed files with 89 additions and 0 deletions
89
src/read.rs
89
src/read.rs
|
|
@ -87,6 +87,12 @@ pub trait BitRead<E: Endianness>: Sized {
|
||||||
fn read(stream: &mut BitStream<E>) -> Result<Self>;
|
fn read(stream: &mut BitStream<E>) -> Result<Self>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Trait to get the number of bits needed to read types that can be read from a stream without requiring the size to be configured.
|
||||||
|
pub trait BitSize {
|
||||||
|
/// How many bits are required to read this type
|
||||||
|
fn bit_size() -> usize;
|
||||||
|
}
|
||||||
|
|
||||||
macro_rules! impl_read_int {
|
macro_rules! impl_read_int {
|
||||||
($type:ty, $len:expr) => {
|
($type:ty, $len:expr) => {
|
||||||
impl<E: Endianness> BitRead<E> for $type {
|
impl<E: Endianness> BitRead<E> for $type {
|
||||||
|
|
@ -95,6 +101,13 @@ macro_rules! impl_read_int {
|
||||||
stream.read_int::<$type>($len)
|
stream.read_int::<$type>($len)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl BitSize for $type {
|
||||||
|
#[inline(always)]
|
||||||
|
fn bit_size() -> usize {
|
||||||
|
$len
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -116,6 +129,13 @@ impl<E: Endianness> BitRead<E> for f32 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl BitSize for f32 {
|
||||||
|
#[inline(always)]
|
||||||
|
fn bit_size() -> usize {
|
||||||
|
32
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<E: Endianness> BitRead<E> for f64 {
|
impl<E: Endianness> BitRead<E> for f64 {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn read(stream: &mut BitStream<E>) -> Result<f64> {
|
fn read(stream: &mut BitStream<E>) -> Result<f64> {
|
||||||
|
|
@ -123,6 +143,13 @@ impl<E: Endianness> BitRead<E> for f64 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl BitSize for f64 {
|
||||||
|
#[inline(always)]
|
||||||
|
fn bit_size() -> usize {
|
||||||
|
64
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<E: Endianness> BitRead<E> for bool {
|
impl<E: Endianness> BitRead<E> for bool {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn read(stream: &mut BitStream<E>) -> Result<bool> {
|
fn read(stream: &mut BitStream<E>) -> Result<bool> {
|
||||||
|
|
@ -130,6 +157,13 @@ impl<E: Endianness> BitRead<E> for bool {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl BitSize for bool {
|
||||||
|
#[inline(always)]
|
||||||
|
fn bit_size() -> usize {
|
||||||
|
1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<E: Endianness> BitRead<E> for String {
|
impl<E: Endianness> BitRead<E> for String {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn read(stream: &mut BitStream<E>) -> Result<String> {
|
fn read(stream: &mut BitStream<E>) -> Result<String> {
|
||||||
|
|
@ -206,6 +240,12 @@ pub trait BitReadSized<E: Endianness>: Sized {
|
||||||
fn read(stream: &mut BitStream<E>, size: usize) -> Result<Self>;
|
fn read(stream: &mut BitStream<E>, size: usize) -> Result<Self>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Trait to get the number of bits needed to read types that can be read from a stream requiring the size to be configured.
|
||||||
|
pub trait BitSizeSized {
|
||||||
|
/// How many bits are required to read this type
|
||||||
|
fn bit_size(size: usize) -> usize;
|
||||||
|
}
|
||||||
|
|
||||||
macro_rules! impl_read_int_sized {
|
macro_rules! impl_read_int_sized {
|
||||||
($type:ty) => {
|
($type:ty) => {
|
||||||
impl<E: Endianness> BitReadSized<E> for $type {
|
impl<E: Endianness> BitReadSized<E> for $type {
|
||||||
|
|
@ -214,6 +254,13 @@ macro_rules! impl_read_int_sized {
|
||||||
stream.read_int::<$type>(size)
|
stream.read_int::<$type>(size)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl BitSizeSized for $type {
|
||||||
|
#[inline(always)]
|
||||||
|
fn bit_size(size: usize) -> usize {
|
||||||
|
size
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -235,6 +282,13 @@ impl<E: Endianness> BitReadSized<E> for String {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl BitSizeSized for String {
|
||||||
|
#[inline(always)]
|
||||||
|
fn bit_size(size: usize) -> usize {
|
||||||
|
8 * size
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Read a boolean, if true, read `T`, else return `None`
|
/// Read a boolean, if true, read `T`, else return `None`
|
||||||
impl<E: Endianness, T: BitRead<E>> BitRead<E> for Option<T> {
|
impl<E: Endianness, T: BitRead<E>> BitRead<E> for Option<T> {
|
||||||
fn read(stream: &mut BitStream<E>) -> Result<Self> {
|
fn read(stream: &mut BitStream<E>) -> Result<Self> {
|
||||||
|
|
@ -246,6 +300,13 @@ impl<E: Endianness, T: BitRead<E>> BitRead<E> for Option<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<T: BitSize> BitSize for Option<T> {
|
||||||
|
#[inline(always)]
|
||||||
|
fn bit_size() -> usize {
|
||||||
|
1 + T::bit_size()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<E: Endianness, T: BitReadSized<E>> BitReadSized<E> for Option<T> {
|
impl<E: Endianness, T: BitReadSized<E>> BitReadSized<E> for Option<T> {
|
||||||
fn read(stream: &mut BitStream<E>, size: usize) -> Result<Self> {
|
fn read(stream: &mut BitStream<E>, size: usize) -> Result<Self> {
|
||||||
if stream.read()? {
|
if stream.read()? {
|
||||||
|
|
@ -256,6 +317,13 @@ impl<E: Endianness, T: BitReadSized<E>> BitReadSized<E> for Option<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<T: BitSizeSized> BitSizeSized for Option<T> {
|
||||||
|
#[inline(always)]
|
||||||
|
fn bit_size(size: usize) -> usize {
|
||||||
|
1 + T::bit_size(size)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<E: Endianness> BitReadSized<E> for BitStream<E> {
|
impl<E: Endianness> BitReadSized<E> for BitStream<E> {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn read(stream: &mut BitStream<E>, size: usize) -> Result<Self> {
|
fn read(stream: &mut BitStream<E>, size: usize) -> Result<Self> {
|
||||||
|
|
@ -263,6 +331,13 @@ impl<E: Endianness> BitReadSized<E> for BitStream<E> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<E: Endianness> BitSizeSized for BitStream<E> {
|
||||||
|
#[inline(always)]
|
||||||
|
fn bit_size(size: usize) -> usize {
|
||||||
|
size
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Read `T` `size` times and return as `Vec<T>`
|
/// Read `T` `size` times and return as `Vec<T>`
|
||||||
impl<E: Endianness, T: BitRead<E>> BitReadSized<E> for Vec<T> {
|
impl<E: Endianness, T: BitRead<E>> BitReadSized<E> for Vec<T> {
|
||||||
fn read(stream: &mut BitStream<E>, size: usize) -> Result<Self> {
|
fn read(stream: &mut BitStream<E>, size: usize) -> Result<Self> {
|
||||||
|
|
@ -274,6 +349,13 @@ impl<E: Endianness, T: BitRead<E>> BitReadSized<E> for Vec<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<T: BitSize> BitSizeSized for Vec<T> {
|
||||||
|
#[inline(always)]
|
||||||
|
fn bit_size(size: usize) -> usize {
|
||||||
|
size * T::bit_size()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Once we have something like https://github.com/rust-lang/rfcs/issues/1053 we can do this optimization
|
// Once we have something like https://github.com/rust-lang/rfcs/issues/1053 we can do this optimization
|
||||||
//impl<E: Endianness> ReadSized<E> for Vec<u8> {
|
//impl<E: Endianness> ReadSized<E> for Vec<u8> {
|
||||||
// #[inline(always)]
|
// #[inline(always)]
|
||||||
|
|
@ -294,3 +376,10 @@ impl<E: Endianness, K: BitRead<E> + Eq + Hash, T: BitRead<E>> BitReadSized<E> fo
|
||||||
Ok(map)
|
Ok(map)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<K: BitSize, T: BitSize> BitSizeSized for HashMap<K, T> {
|
||||||
|
#[inline(always)]
|
||||||
|
fn bit_size(size: usize) -> usize {
|
||||||
|
size * (K::bit_size() + T::bit_size())
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue