bitstream_io::read

Struct BitReader

Source
pub struct BitReader<R: Read, 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: Read, 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::{Read, Cursor};
use 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).unwrap(), 0b1010_0101_0);
let (bits, value) = reader.into_unread();
assert_eq!(bits, 7);
assert_eq!(value, 0b101_1010);
use std::io::{Read, Cursor};
use 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).unwrap(), 0b1010_0101);
let (bits, value) = reader.into_unread();
assert_eq!(bits, 0);
assert_eq!(value, 0);
Source§

impl<R, E> BitReader<R, E>
where E: Endianness, R: Read + Seek,

Source

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

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

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

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

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

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

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

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

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

Trait Implementations§

Source§

impl<R: Read, E: Endianness> BitRead for BitReader<R, E>

Source§

fn read_bit(&mut self) -> Result<bool>

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

fn read<U>(&mut self, bits: u32) -> Result<U>
where U: Numeric,

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

fn read_in<const BITS: u32, U>(&mut self) -> Result<U>
where U: Numeric,

§Examples
use std::io::{Read, Cursor};
use bitstream_io::{BigEndian, BitReader, BitRead};
let data = [0b10110111];
let mut reader = BitReader::endian(Cursor::new(&data), BigEndian);
assert_eq!(reader.read_in::<1, u8>().unwrap(), 0b1);
assert_eq!(reader.read_in::<2, u8>().unwrap(), 0b01);
assert_eq!(reader.read_in::<5, u8>().unwrap(), 0b10111);
use std::io::{Read, Cursor};
use bitstream_io::{LittleEndian, BitReader, BitRead};
let data = [0b10110111];
let mut reader = BitReader::endian(Cursor::new(&data), LittleEndian);
assert_eq!(reader.read_in::<1, u8>().unwrap(), 0b1);
assert_eq!(reader.read_in::<2, u8>().unwrap(), 0b11);
assert_eq!(reader.read_in::<5, u8>().unwrap(), 0b10110);
Source§

fn read_signed<S>(&mut self, bits: u32) -> Result<S>
where S: SignedNumeric,

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

fn read_signed_in<const BITS: u32, S>(&mut self) -> Result<S>
where S: SignedNumeric,

§Examples
use std::io::{Read, Cursor};
use bitstream_io::{BigEndian, BitReader, BitRead};
let data = [0b10110111];
let mut reader = BitReader::endian(Cursor::new(&data), BigEndian);
assert_eq!(reader.read_signed_in::<4, i8>().unwrap(), -5);
assert_eq!(reader.read_signed_in::<4, i8>().unwrap(), 7);
use std::io::{Read, Cursor};
use bitstream_io::{LittleEndian, BitReader, BitRead};
let data = [0b10110111];
let mut reader = BitReader::endian(Cursor::new(&data), LittleEndian);
assert_eq!(reader.read_signed_in::<4, i8>().unwrap(), 7);
assert_eq!(reader.read_signed_in::<4, i8>().unwrap(), -5);
Source§

fn skip(&mut self, bits: u32) -> Result<()>

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

fn read_bytes(&mut self, buf: &mut [u8]) -> Result<()>

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

fn read_unary0(&mut self) -> Result<u32>

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

fn read_unary1(&mut self) -> Result<u32>

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

fn byte_aligned(&self) -> bool

§Example
use std::io::{Read, Cursor};
use 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).is_ok());
assert_eq!(reader.byte_aligned(), false);
assert!(reader.skip(7).is_ok());
assert_eq!(reader.byte_aligned(), true);
Source§

fn byte_align(&mut self)

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

fn read_to<V>(&mut self) -> Result<V>
where V: Primitive,

Reads whole value from the stream whose size in bits is equal to its type’s size. Read more
Source§

fn read_as_to<F, V>(&mut self) -> Result<V>
where F: Endianness, V: Primitive,

Reads whole value from the stream whose size in bits is equal to its type’s size in an endianness that may be different from the stream’s endianness. Read more
Source§

fn read_to_bytes<const SIZE: usize>(&mut self) -> Result<[u8; SIZE]>

👎Deprecated since 1.8.0: use read_to() method instead
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(&mut self, bytes: usize) -> Result<Vec<u8>>

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§

fn parse<F: FromBitStream>(&mut self) -> Result<F, F::Error>

Parses and returns complex type
Source§

fn parse_with<'a, F: FromBitStreamWith<'a>>( &mut self, context: &F::Context, ) -> Result<F, F::Error>

Parses and returns complex type with context
Source§

impl<R: Clone + Read, E: Clone + Endianness> Clone for BitReader<R, E>

Source§

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

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

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

Performs copy-assignment from source. Read more
Source§

impl<R: Debug + Read, E: Debug + Endianness> Debug for BitReader<R, E>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<R: Read, E: Endianness> HuffmanRead<E> for BitReader<R, E>

Source§

fn read_huffman<T>(&mut self, tree: &[ReadHuffmanTree<E, T>]) -> Result<T>
where T: Clone,

§Example
use std::io::{Read, Cursor};
use bitstream_io::{BigEndian, BitReader, HuffmanRead};
use 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).unwrap(), 'b');
assert_eq!(reader.read_huffman(&tree).unwrap(), 'c');
assert_eq!(reader.read_huffman(&tree).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>
where R: Send, E: Send,

§

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

§

impl<R, E> Unpin for BitReader<R, E>
where R: Unpin, 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, dst: *mut T)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dst. 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.