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

some docs

This commit is contained in:
Robin Appelman 2019-03-05 16:01:55 +01:00
commit f54d8748ad
3 changed files with 91 additions and 44 deletions

View file

@ -5,7 +5,7 @@
//!
//! Once you have a BitStream, there are 2 different approaches of reading data
//!
//! - read primitives, Strings and byte arrays, using [`read_bool`], [`read_int`], [`read_float`], [`read_byes`] and [`read_string`]
//! - read primitives, Strings and byte arrays, using [`read_bool`], [`read_int`], [`read_float`], [`read_bytes`] and [`read_string`]
//! - read any type implementing the [`BitRead`] or [`BitReadSized`] traits using [`read`] and [`read_sized`]
//! - [`BitRead`] is for types that can be read without requiring any size info (e.g. null-terminal strings, floats, whole integers, etc)
//! - [`BitReadSized`] is for types that require external sizing information to be read (fixed length strings, arbitrary length integers
@ -45,16 +45,14 @@
//! [`read_bool`]: struct.BitStream.html#method.read_bool
//! [`read_int`]: struct.BitStream.html#method.read_int
//! [`read_float`]: struct.BitStream.html#method.read_float
//! [`read_byes`]: struct.BitStream.html#method.read_bytes
//! [`read_bytes`]: struct.BitStream.html#method.read_bytes
//! [`read_string`]: struct.BitStream.html#method.read_string
//! [`read`]: struct.BitStream.html#method.read
//! [`read_sized`]: struct.BitStream.html#method.read_sized
//! [`BitRead`]: trait.BitRead.html
//! [`BitReadSized`]: trait.BitReadSized.html
#![warn(missing_docs)]
//#![feature(test)]
// for bench on nightly
//extern crate test;
use std::error::Error;
use std::fmt;

View file

@ -1,8 +1,8 @@
use crate::{BitStream, Endianness, Result};
use std::cell::RefCell;
use std::collections::HashMap;
use std::hash::Hash;
use std::marker::PhantomData;
use std::cell::RefCell;
/// Trait for types that can be read from a stream without requiring the size to be configured
///
@ -18,7 +18,7 @@ use std::cell::RefCell;
/// The size for a field can be set using 3 different methods
/// - set the size as an integer using the `size` attribute,
/// - use a previously defined field as the size using the `size` attribute
/// - read a set number of bits as an integer, using the resulting value as size using the `read_bits` attribute
/// - read a set number of bits as an integer, using the resulting value as size using the `size_bits` attribute
///
/// ## Examples
///
@ -98,14 +98,14 @@ pub trait BitSize {
macro_rules! impl_read_int {
($type:ty, $len:expr) => {
impl<E: Endianness> BitRead<E> for $type {
#[inline(always)]
#[inline]
fn read(stream: &mut BitStream<E>) -> Result<$type> {
stream.read_int::<$type>($len)
}
}
impl BitSize for $type {
#[inline(always)]
#[inline]
fn bit_size() -> usize {
$len
}
@ -125,49 +125,49 @@ impl_read_int!(i64, 64);
impl_read_int!(i128, 128);
impl<E: Endianness> BitRead<E> for f32 {
#[inline(always)]
#[inline]
fn read(stream: &mut BitStream<E>) -> Result<f32> {
stream.read_float::<f32>()
}
}
impl BitSize for f32 {
#[inline(always)]
#[inline]
fn bit_size() -> usize {
32
}
}
impl<E: Endianness> BitRead<E> for f64 {
#[inline(always)]
#[inline]
fn read(stream: &mut BitStream<E>) -> Result<f64> {
stream.read_float::<f64>()
}
}
impl BitSize for f64 {
#[inline(always)]
#[inline]
fn bit_size() -> usize {
64
}
}
impl<E: Endianness> BitRead<E> for bool {
#[inline(always)]
#[inline]
fn read(stream: &mut BitStream<E>) -> Result<bool> {
stream.read_bool()
}
}
impl BitSize for bool {
#[inline(always)]
#[inline]
fn bit_size() -> usize {
1
}
}
impl<E: Endianness> BitRead<E> for String {
#[inline(always)]
#[inline]
fn read(stream: &mut BitStream<E>) -> Result<String> {
stream.read_string(None)
}
@ -189,7 +189,7 @@ impl<E: Endianness> BitRead<E> for String {
/// - set the size as an integer using the `size` attribute,
/// - use a previously defined field as the size using the `size` attribute
/// - based on the input size by setting `size` attribute to `"input_size"`
/// - read a set number of bits as an integer, using the resulting value as size using the `read_bits` attribute
/// - read a set number of bits as an integer, using the resulting value as size using the `size_bits` attribute
///
/// ## Examples
///
@ -251,14 +251,14 @@ pub trait BitSizeSized {
macro_rules! impl_read_int_sized {
($type:ty) => {
impl<E: Endianness> BitReadSized<E> for $type {
#[inline(always)]
#[inline]
fn read(stream: &mut BitStream<E>, size: usize) -> Result<$type> {
stream.read_int::<$type>(size)
}
}
impl BitSizeSized for $type {
#[inline(always)]
#[inline]
fn bit_size(size: usize) -> usize {
size
}
@ -278,14 +278,14 @@ impl_read_int_sized!(i64);
impl_read_int_sized!(i128);
impl<E: Endianness> BitReadSized<E> for String {
#[inline(always)]
#[inline]
fn read(stream: &mut BitStream<E>, size: usize) -> Result<String> {
stream.read_string(Some(size))
}
}
impl BitSizeSized for String {
#[inline(always)]
#[inline]
fn bit_size(size: usize) -> usize {
8 * size
}
@ -303,7 +303,7 @@ impl<E: Endianness, T: BitRead<E>> BitRead<E> for Option<T> {
}
impl<T: BitSize> BitSize for Option<T> {
#[inline(always)]
#[inline]
fn bit_size() -> usize {
1 + T::bit_size()
}
@ -320,21 +320,21 @@ impl<E: Endianness, T: BitReadSized<E>> BitReadSized<E> for Option<T> {
}
impl<T: BitSizeSized> BitSizeSized for Option<T> {
#[inline(always)]
#[inline]
fn bit_size(size: usize) -> usize {
1 + T::bit_size(size)
}
}
impl<E: Endianness> BitReadSized<E> for BitStream<E> {
#[inline(always)]
#[inline]
fn read(stream: &mut BitStream<E>, size: usize) -> Result<Self> {
stream.read_bits(size)
}
}
impl<E: Endianness> BitSizeSized for BitStream<E> {
#[inline(always)]
#[inline]
fn bit_size(size: usize) -> usize {
size
}
@ -352,7 +352,7 @@ impl<E: Endianness, T: BitRead<E>> BitReadSized<E> for Vec<T> {
}
impl<T: BitSize> BitSizeSized for Vec<T> {
#[inline(always)]
#[inline]
fn bit_size(size: usize) -> usize {
size * T::bit_size()
}
@ -360,7 +360,7 @@ impl<T: BitSize> BitSizeSized for Vec<T> {
// 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> {
// #[inline(always)]
// #[inline]
// fn read(stream: &mut BitStream<E>, size: usize) -> Result<Self> {
// stream.read_bytes(size)
// }
@ -380,7 +380,7 @@ impl<E: Endianness, K: BitRead<E> + Eq + Hash, T: BitRead<E>> BitReadSized<E> fo
}
impl<K: BitSize, T: BitSize> BitSizeSized for HashMap<K, T> {
#[inline(always)]
#[inline]
fn bit_size(size: usize) -> usize {
size * (K::bit_size() + T::bit_size())
}
@ -394,11 +394,11 @@ impl<K: BitSize, T: BitSize> BitSizeSized for HashMap<K, T> {
/// [`BitSize`]: trait.BitSize.html
pub struct LazyBitRead<T: BitRead<E> + BitSize, E: Endianness> {
source: RefCell<BitStream<E>>,
inner_type: PhantomData<T>
inner_type: PhantomData<T>,
}
impl<T: BitRead<E> + BitSize, E: Endianness> LazyBitRead<T, E> {
#[inline(always)]
#[inline]
/// Get the contents of the lazy struct
pub fn read(self) -> Result<T> {
self.source.borrow_mut().read::<T>()
@ -406,18 +406,18 @@ impl<T: BitRead<E> + BitSize, E: Endianness> LazyBitRead<T, E> {
}
impl<T: BitRead<E> + BitSize, E: Endianness> BitRead<E> for LazyBitRead<T, E> {
#[inline(always)]
#[inline]
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
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)]
#[inline]
fn bit_size() -> usize {
T::bit_size()
}
@ -432,11 +432,11 @@ impl<T: BitRead<E> + BitSize, E: Endianness> BitSize for LazyBitRead<T, E> {
pub struct LazyBitReadSized<T: BitReadSized<E> + BitSizeSized, E: Endianness> {
source: RefCell<BitStream<E>>,
size: usize,
inner_type: PhantomData<T>
inner_type: PhantomData<T>,
}
impl<T: BitReadSized<E> + BitSizeSized, E: Endianness> LazyBitReadSized<T, E> {
#[inline(always)]
#[inline]
/// Get the contents of the lazy struct
pub fn value(self) -> Result<T> {
self.source.borrow_mut().read_sized::<T>(self.size)
@ -444,19 +444,19 @@ impl<T: BitReadSized<E> + BitSizeSized, E: Endianness> LazyBitReadSized<T, E> {
}
impl<T: BitReadSized<E> + BitSizeSized, E: Endianness> BitReadSized<E> for LazyBitReadSized<T, E> {
#[inline(always)]
#[inline]
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
size,
})
}
}
impl<T: BitReadSized<E> + BitSizeSized, E: Endianness> BitSizeSized for LazyBitReadSized<T, E> {
#[inline(always)]
#[inline]
fn bit_size(size: usize) -> usize {
T::bit_size(size)
}

View file

@ -472,13 +472,45 @@ where
/// # Ok(())
/// # }
/// ```
/// #[inline(always)]
///
/// ```
/// # use bitstream_reader::{BitBuffer, BitStream, LittleEndian, Result};
/// use bitstream_reader::BitRead;
/// #
/// #[derive(BitRead, Debug, PartialEq)]
/// struct ComplexType {
/// first: u8,
/// #[size = 15]
/// second: u16,
/// third: bool,
/// }
/// #
/// # fn main() -> Result<()> {
/// # let bytes = vec![
/// # 0b1011_0101, 0b0110_1010, 0b1010_1100, 0b1001_1001,
/// # 0b1001_1001, 0b1001_1001, 0b1001_1001, 0b1110_0111
/// # ];
/// # let buffer = BitBuffer::new(bytes, LittleEndian);
/// # let mut stream = BitStream::new(buffer);
/// let data: ComplexType = stream.read()?;
/// assert_eq!(data, ComplexType {
/// first: 0b1011_0101,
/// second: 0b010_1100_0110_1010,
/// third: true,
/// });
/// #
/// # Ok(())
/// # }
/// ```
#[inline]
pub fn read<T: BitRead<E>>(&mut self) -> Result<T> {
T::read(self)
}
/// Read a value based on the provided type and size
///
/// The meaning of the size parameter differs depending on the type that is being read
///
/// # Examples
///
/// ```
@ -497,7 +529,24 @@ where
/// # Ok(())
/// # }
/// ```
#[inline(always)]
///
/// ```
/// # use bitstream_reader::{BitBuffer, BitStream, LittleEndian, Result};
/// #
/// # fn main() -> Result<()> {
/// # let bytes = vec![
/// # 0b1011_0101, 0b0110_1010, 0b1010_1100, 0b1001_1001,
/// # 0b1001_1001, 0b1001_1001, 0b1001_1001, 0b1110_0111
/// # ];
/// # let buffer = BitBuffer::new(bytes, LittleEndian);
/// # let mut stream = BitStream::new(buffer);
/// let data: Vec<u16> = stream.read_sized(3)?;
/// assert_eq!(data, vec![0b0110_1010_1011_0101, 0b1001_1001_1010_1100, 0b1001_1001_1001_1001]);
/// #
/// # Ok(())
/// # }
/// ```
#[inline]
pub fn read_sized<T: BitReadSized<E>>(&mut self, size: usize) -> Result<T> {
T::read(self, size)
}