Struct BitReader

Source
pub struct BitReader<R: AsyncRead + Unpin + Send + Sync, E: Endianness> { /* private fields */ }
Expand description

For reading non-aligned bits from a stream of bytes in a given endianness.

This will read exactly as many whole bytes needed to return the requested number of bits. It may cache up to a single partial byte but no more.

Implementations§

Source§

impl<R: AsyncRead + Unpin + Send + Sync, E: Endianness> BitReader<R, E>

Source

pub fn new(reader: R) -> BitReader<R, E>

Wraps a BitReader around something that implements Read

Source

pub fn endian(reader: R, _endian: E) -> BitReader<R, E>

Wraps a BitReader around something that implements Read with the given endianness.

Source

pub fn into_reader(self) -> R

Unwraps internal reader and disposes of BitReader.

§Warning

Any unread partial bits are discarded.

Source

pub fn reader(&mut self) -> Option<&mut R>

If stream is byte-aligned, provides mutable reference to internal reader. Otherwise returns None

Source

pub fn into_bytereader(self) -> ByteReader<R, E>

Converts BitReader to ByteReader in the same endianness.

§Warning

Any unread partial bits are discarded.

Source

pub fn bytereader(&mut self) -> Option<ByteReader<&mut R, E>>

If stream is byte-aligned, provides temporary ByteReader in the same endianness. Otherwise returns None

§Warning

Any reader bits left over when ByteReader is dropped are lost.

Source

pub fn into_unread(self) -> (u32, u8)

Consumes reader and returns any un-read partial byte as a (bits, value) tuple.

§Examples
use std::io::Cursor;
use tokio_bitstream_io::{BigEndian, BitReader, BitRead};
let data = [0b1010_0101, 0b0101_1010];
let mut reader = BitReader::endian(Cursor::new(&data), BigEndian);
assert_eq!(reader.read::<u16>(9).await.unwrap(), 0b1010_0101_0);
let (bits, value) = reader.into_unread();
assert_eq!(bits, 7);
assert_eq!(value, 0b101_1010);
use std::io::Cursor;
use tokio_bitstream_io::{BigEndian, BitReader, BitRead};
let data = [0b1010_0101, 0b0101_1010];
let mut reader = BitReader::endian(Cursor::new(&data), BigEndian);
assert_eq!(reader.read::<u16>(8).await.unwrap(), 0b1010_0101);
let (bits, value) = reader.into_unread();
assert_eq!(bits, 0);
assert_eq!(value, 0);
Source§

impl<R, E> BitReader<R, E>

Source

pub async fn seek_bits(&mut self, from: SeekFrom) -> Result<u64>

§Example
use std::io::{Cursor, SeekFrom};
use tokio_bitstream_io::{BigEndian, BitReader, BitRead};
let data = [0x00, 0xFF];
let mut reader = BitReader::endian(Cursor::new(&data), BigEndian);
assert_eq!(reader.position_in_bits().await.unwrap(), 0);

let pos = reader.seek_bits(SeekFrom::Start(5)).await.unwrap();
assert!(pos == 5 && 5 == reader.position_in_bits().await.unwrap());

let pos = reader.seek_bits(SeekFrom::Current(-2)).await.unwrap();
assert!(pos == 3 && 3 == reader.position_in_bits().await.unwrap());    ///

let pos = reader.seek_bits(SeekFrom::End(5)).await.unwrap();
assert!(pos == 11 && 11 == reader.position_in_bits().await.unwrap());
Source

pub async fn position_in_bits(&mut self) -> Result<u64>

§Example
use std::fs::read;
use std::io::{Cursor, SeekFrom};
use tokio_bitstream_io::{BigEndian, BitReader, BitRead};
let data = [0x00, 0xFF];
let mut reader = BitReader::endian(Cursor::new(&data), BigEndian);
assert_eq!(reader.position_in_bits().await.unwrap(), 0);

let _: i32 = reader.read_signed(5).await.unwrap();
assert_eq!(reader.position_in_bits().await.unwrap(), 5);

reader.read_bit().await.unwrap();
assert_eq!(reader.position_in_bits().await.unwrap(), 6);

Trait Implementations§

Source§

impl<R: AsyncRead + Unpin + Send + Sync, E: Endianness> BitRead for BitReader<R, E>

Source§

fn read_bit<'life0, 'async_trait>( &'life0 mut self, ) -> Pin<Box<dyn Future<Output = Result<bool>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

§Examples
use std::io::Cursor;
use tokio_bitstream_io::{BigEndian, BitReader, BitRead};
let data = [0b10110111];
let mut reader = BitReader::endian(Cursor::new(&data), BigEndian);
assert_eq!(reader.read_bit().await.unwrap(), true);
assert_eq!(reader.read_bit().await.unwrap(), false);
assert_eq!(reader.read_bit().await.unwrap(), true);
assert_eq!(reader.read_bit().await.unwrap(), true);
assert_eq!(reader.read_bit().await.unwrap(), false);
assert_eq!(reader.read_bit().await.unwrap(), true);
assert_eq!(reader.read_bit().await.unwrap(), true);
assert_eq!(reader.read_bit().await.unwrap(), true);
use std::io::Cursor;
use tokio_bitstream_io::{LittleEndian, BitReader, BitRead};
let data = [0b10110111];
let mut reader = BitReader::endian(Cursor::new(&data), LittleEndian);
assert_eq!(reader.read_bit().await.unwrap(), true);
assert_eq!(reader.read_bit().await.unwrap(), true);
assert_eq!(reader.read_bit().await.unwrap(), true);
assert_eq!(reader.read_bit().await.unwrap(), false);
assert_eq!(reader.read_bit().await.unwrap(), true);
assert_eq!(reader.read_bit().await.unwrap(), true);
assert_eq!(reader.read_bit().await.unwrap(), false);
assert_eq!(reader.read_bit().await.unwrap(), true);
Source§

fn read<'life0, 'async_trait, U>( &'life0 mut self, bits: u32, ) -> Pin<Box<dyn Future<Output = Result<U>> + Send + 'async_trait>>
where U: Numeric + 'async_trait, Self: 'async_trait, 'life0: 'async_trait,

§Examples
use std::io::Cursor;
use tokio_bitstream_io::{BigEndian, BitReader, BitRead};
let data = [0b10110111];
let mut reader = BitReader::endian(Cursor::new(&data), BigEndian);
assert_eq!(reader.read::<u8>(1).await.unwrap(), 0b1);
assert_eq!(reader.read::<u8>(2).await.unwrap(), 0b01);
assert_eq!(reader.read::<u8>(5).await.unwrap(), 0b10111);
use std::io::Cursor;
use tokio_bitstream_io::{LittleEndian, BitReader, BitRead};
let data = [0b10110111];
let mut reader = BitReader::endian(Cursor::new(&data), LittleEndian);
assert_eq!(reader.read::<u8>(1).await.unwrap(), 0b1);
assert_eq!(reader.read::<u8>(2).await.unwrap(), 0b11);
assert_eq!(reader.read::<u8>(5).await.unwrap(), 0b10110);
use std::io::Cursor;
use tokio_bitstream_io::{BigEndian, BitReader, BitRead};
let data = [0;10];
let mut reader = BitReader::endian(Cursor::new(&data), BigEndian);
assert!(reader.read::<u8>(9).await.is_err());    // can't read  9 bits to u8
assert!(reader.read::<u16>(17).await.is_err());  // can't read 17 bits to u16
assert!(reader.read::<u32>(33).await.is_err());  // can't read 33 bits to u32
assert!(reader.read::<u64>(65).await.is_err());  // can't read 65 bits to u64
Source§

fn read_signed<'life0, 'async_trait, S>( &'life0 mut self, bits: u32, ) -> Pin<Box<dyn Future<Output = Result<S>> + Send + 'async_trait>>
where S: SignedNumeric + 'async_trait, Self: 'async_trait, 'life0: 'async_trait,

§Examples
use std::io::Cursor;
use tokio_bitstream_io::{BigEndian, BitReader, BitRead};
let data = [0b10110111];
let mut reader = BitReader::endian(Cursor::new(&data), BigEndian);
assert_eq!(reader.read_signed::<i8>(4).await.unwrap(), -5);
assert_eq!(reader.read_signed::<i8>(4).await.unwrap(), 7);
use std::io::Cursor;
use tokio_bitstream_io::{LittleEndian, BitReader, BitRead};
let data = [0b10110111];
let mut reader = BitReader::endian(Cursor::new(&data), LittleEndian);
assert_eq!(reader.read_signed::<i8>(4).await.unwrap(), 7);
assert_eq!(reader.read_signed::<i8>(4).await.unwrap(), -5);
use std::io::Cursor;
use tokio_bitstream_io::{BigEndian, BitReader, BitRead};
let data = [0;10];
let mut r = BitReader::endian(Cursor::new(&data), BigEndian);
assert!(r.read_signed::<i8>(9).await.is_err());   // can't read 9 bits to i8
assert!(r.read_signed::<i16>(17).await.is_err()); // can't read 17 bits to i16
assert!(r.read_signed::<i32>(33).await.is_err()); // can't read 33 bits to i32
assert!(r.read_signed::<i64>(65).await.is_err()); // can't read 65 bits to i64
Source§

fn skip<'life0, 'async_trait>( &'life0 mut self, bits: u32, ) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

§Examples
use std::io::Cursor;
use tokio_bitstream_io::{BigEndian, BitReader, BitRead};
let data = [0b10110111];
let mut reader = BitReader::endian(Cursor::new(&data), BigEndian);
assert!(reader.skip(3).await.is_ok());
assert_eq!(reader.read::<u8>(5).await.unwrap(), 0b10111);
use std::io::Cursor;
use tokio_bitstream_io::{LittleEndian, BitReader, BitRead};
let data = [0b10110111];
let mut reader = BitReader::endian(Cursor::new(&data), LittleEndian);
assert!(reader.skip(3).await.is_ok());
assert_eq!(reader.read::<u8>(5).await.unwrap(), 0b10110);
Source§

fn read_bytes<'life0, 'life1, 'async_trait>( &'life0 mut self, buf: &'life1 mut [u8], ) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

§Example
use std::io::Cursor;
use tokio_bitstream_io::{BigEndian, BitReader, BitRead};
let data = b"foobar";
let mut reader = BitReader::endian(Cursor::new(data), BigEndian);
assert!(reader.skip(24).await.is_ok());
let mut buf = [0;3];
assert!(reader.read_bytes(&mut buf).await.is_ok());
assert_eq!(&buf, b"bar");
Source§

fn read_unary0<'life0, 'async_trait>( &'life0 mut self, ) -> Pin<Box<dyn Future<Output = Result<u32>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

§Examples
use std::io::Cursor;
use tokio_bitstream_io::{BigEndian, BitReader, BitRead};
let data = [0b01110111, 0b11111110];
let mut reader = BitReader::endian(Cursor::new(&data), BigEndian);
assert_eq!(reader.read_unary0().await.unwrap(), 0);
assert_eq!(reader.read_unary0().await.unwrap(), 3);
assert_eq!(reader.read_unary0().await.unwrap(), 10);
use std::io::Cursor;
use tokio_bitstream_io::{LittleEndian, BitReader, BitRead};
let data = [0b11101110, 0b01111111];
let mut reader = BitReader::endian(Cursor::new(&data), LittleEndian);
assert_eq!(reader.read_unary0().await.unwrap(), 0);
assert_eq!(reader.read_unary0().await.unwrap(), 3);
assert_eq!(reader.read_unary0().await.unwrap(), 10);
Source§

fn read_unary1<'life0, 'async_trait>( &'life0 mut self, ) -> Pin<Box<dyn Future<Output = Result<u32>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

§Examples
use std::io::Cursor;
use tokio_bitstream_io::{BigEndian, BitReader, BitRead};
let data = [0b10001000, 0b00000001];
let mut reader = BitReader::endian(Cursor::new(&data), BigEndian);
assert_eq!(reader.read_unary1().await.unwrap(), 0);
assert_eq!(reader.read_unary1().await.unwrap(), 3);
assert_eq!(reader.read_unary1().await.unwrap(), 10);
use std::io::Cursor;
use tokio_bitstream_io::{LittleEndian, BitReader, BitRead};
let data = [0b00010001, 0b10000000];
let mut reader = BitReader::endian(Cursor::new(&data), LittleEndian);
assert_eq!(reader.read_unary1().await.unwrap(), 0);
assert_eq!(reader.read_unary1().await.unwrap(), 3);
assert_eq!(reader.read_unary1().await.unwrap(), 10);
Source§

fn byte_aligned(&self) -> bool

§Example
use std::io::Cursor;
use tokio_bitstream_io::{BigEndian, BitReader, BitRead};
let data = [0];
let mut reader = BitReader::endian(Cursor::new(&data), BigEndian);
assert_eq!(reader.byte_aligned(), true);
assert!(reader.skip(1).await.is_ok());
assert_eq!(reader.byte_aligned(), false);
assert!(reader.skip(7).await.is_ok());
assert_eq!(reader.byte_aligned(), true);
Source§

fn byte_align(&mut self)

§Example
use std::io::Cursor;
use tokio_bitstream_io::{BigEndian, BitReader, BitRead};
let data = [0x00, 0xFF];
let mut reader = BitReader::endian(Cursor::new(&data), BigEndian);
assert_eq!(reader.read::<u8>(4).await.unwrap(), 0);
reader.byte_align();
assert_eq!(reader.read::<u8>(8).await.unwrap(), 0xFF);
Source§

fn read_to_bytes<'life0, 'async_trait, const SIZE: usize>( &'life0 mut self, ) -> Pin<Box<dyn Future<Output = Result<[u8; SIZE]>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Completely fills a whole buffer with bytes and returns it. If the stream is already byte-aligned, it will map to a faster read_exact call. Otherwise it will read bytes individually in 8-bit increments. Read more
Source§

fn read_to_vec<'life0, 'async_trait>( &'life0 mut self, bytes: usize, ) -> Pin<Box<dyn Future<Output = Result<Vec<u8>>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Completely fills a vector of bytes and returns it. If the stream is already byte-aligned, it will map to a faster read_exact call. Otherwise it will read bytes individually in 8-bit increments. Read more
Source§

impl<R: Clone + AsyncRead + Unpin + Send + Sync, E: Clone + Endianness> Clone for BitReader<R, E>

Source§

fn clone(&self) -> BitReader<R, E>

Returns a duplicate of the value. Read more
1.0.0 · Source§

const fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<R: AsyncRead + Unpin + Send + Sync, E: Endianness> HuffmanRead<E> for BitReader<R, E>

Source§

fn read_huffman<'life0, 'life1, 'async_trait, T>( &'life0 mut self, tree: &'life1 [ReadHuffmanTree<E, T>], ) -> Pin<Box<dyn Future<Output = Result<T>> + Send + 'async_trait>>
where T: Clone + Send + Sync + 'async_trait, Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

§Example
use std::io::Cursor;
use tokio_bitstream_io::{BigEndian, BitReader, HuffmanRead};
use tokio_bitstream_io::huffman::compile_read_tree;
let tree = compile_read_tree(
    vec![('a', vec![0]),
         ('b', vec![1, 0]),
         ('c', vec![1, 1, 0]),
         ('d', vec![1, 1, 1])]).unwrap();
let data = [0b10110111];
let mut reader = BitReader::endian(Cursor::new(&data), BigEndian);
assert_eq!(reader.read_huffman(&tree).await.unwrap(), 'b');
assert_eq!(reader.read_huffman(&tree).await.unwrap(), 'c');
assert_eq!(reader.read_huffman(&tree).await.unwrap(), 'd');

Auto Trait Implementations§

§

impl<R, E> Freeze for BitReader<R, E>
where R: Freeze,

§

impl<R, E> RefUnwindSafe for BitReader<R, E>

§

impl<R, E> Send for BitReader<R, E>

§

impl<R, E> Sync for BitReader<R, E>

§

impl<R, E> Unpin for BitReader<R, E>
where E: Unpin,

§

impl<R, E> UnwindSafe for BitReader<R, E>
where R: UnwindSafe, E: UnwindSafe,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.