Struct BitReader

struct BitReader<R: io::Read, E: Endianness> { ... }

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

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

fn seek_bits(self: &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());
fn position_in_bits(self: &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);

impl<R: io::Read, E: Endianness> BitReader<R, E>

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

Wraps a BitReader around something that implements Read

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

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

fn into_reader(self: Self) -> R

Unwraps internal reader and disposes of BitReader.

Warning

Any unread partial bits are discarded.

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

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

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

Converts BitReader to ByteReader in the same endianness.

Warning

Any unread partial bits are discarded.

fn bytereader(self: &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.

fn into_unread(self: 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);

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

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>

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

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

impl<R: $crate::clone::Clone + io::Read, E: $crate::clone::Clone + Endianness> Clone for BitReader<R, E>

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

impl<R: $crate::fmt::Debug + io::Read, E: $crate::fmt::Debug + Endianness> Debug for BitReader<R, E>

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

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

fn read_bit(self: &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);
fn read<U>(self: &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
fn read_in<BITS: u32, U>(self: &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);
fn read_signed<S>(self: &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
fn read_signed_in<BITS: u32, S>(self: &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);
fn read_to<V>(self: &mut Self) -> Result<V>
where
    V: Primitive
fn read_as_to<F, V>(self: &mut Self) -> Result<V>
where
    F: Endianness,
    V: Primitive
fn skip(self: &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);
fn read_bytes(self: &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");
fn read_unary0(self: &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);
fn read_unary1(self: &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);
fn byte_aligned(self: &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);
fn byte_align(self: &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);

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

fn read_huffman<T>(self: &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');

impl<T> Any for BitReader<R, E>

fn type_id(self: &Self) -> TypeId

impl<T> Borrow for BitReader<R, E>

fn borrow(self: &Self) -> &T

impl<T> BorrowMut for BitReader<R, E>

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

impl<T> CloneToUninit for BitReader<R, E>

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

impl<T> From for BitReader<R, E>

fn from(t: T) -> T

Returns the argument unchanged.

impl<T> ToOwned for BitReader<R, E>

fn to_owned(self: &Self) -> T
fn clone_into(self: &Self, target: &mut T)

impl<T, U> Into for BitReader<R, E>

fn into(self: Self) -> U

Calls U::from(self).

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

impl<T, U> TryFrom for BitReader<R, E>

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

impl<T, U> TryInto for BitReader<R, E>

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