Struct bitstream_io::read::BitReader[][src]

pub struct BitReader<R: Read, E: Endianness> { /* fields omitted */ }

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.

Methods

impl<R: Read, E: Endianness> BitReader<R, E>
[src]

Wraps a BitReader around something that implements Read

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

Unwraps internal reader and disposes of BitReader. Any unread partial bits are discarded.

Reads a single bit from the stream. true indicates 1, false indicates 0

Errors

Passes along any I/O error from the underlying stream.

Examples

use std::io::{Read, Cursor};
use bitstream_io::{BigEndian, BitReader};
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};
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);

Reads an unsigned value from the stream with the given number of bits.

Errors

Passes along any I/O error from the underlying stream. Also returns an error if the output type is too small to hold the requested number of bits.

Examples

use std::io::{Read, Cursor};
use bitstream_io::{BigEndian, BitReader};
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};
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};
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

Skips the given number of bits in the stream. Since this method does not need an accumulator, it may be slightly faster than reading to an empty variable. In addition, since there is no accumulator, there is no upper limit on the number of bits which may be skipped. These bits are still read from the stream, however, and are never skipped via a seek method.

Errors

Passes along any I/O error from the underlying stream.

Examples

use std::io::{Read, Cursor};
use bitstream_io::{BigEndian, BitReader};
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};
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);

Completely fills the given buffer with whole bytes. 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.

Errors

Passes along any I/O error from the underlying stream.

Example

use std::io::{Read, Cursor};
use bitstream_io::{BigEndian, BitReader};
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");

Counts the number of 1 bits in the stream until the next 0 bit and returns the amount read. Because this field is variably-sized and may be large, its output is always a u32 type.

Errors

Passes along any I/O error from the underlying stream.

Examples

use std::io::{Read, Cursor};
use bitstream_io::{BigEndian, BitReader};
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};
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);

Counts the number of 0 bits in the stream until the next 1 bit and returns the amount read. Because this field is variably-sized and may be large, its output is always a u32 type.

Errors

Passes along any I/O error from the underlying stream.

Examples

use std::io::{Read, Cursor};
use bitstream_io::{BigEndian, BitReader};
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};
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);

Returns true if the stream is aligned at a whole byte.

Example

use std::io::{Read, Cursor};
use bitstream_io::{BigEndian, BitReader};
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);

Throws away all unread bit values until the next whole byte. Does nothing if the stream is already aligned.

Example

use std::io::{Read, Cursor};
use bitstream_io::{BigEndian, BitReader};
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);

Given a compiled Huffman tree, reads bits from the stream until the next symbol is encountered.

Errors

Passes along any I/O error from the underlying stream.

Example

use std::io::{Read, Cursor};
use bitstream_io::{BigEndian, BitReader};
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');

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};
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};
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: Read> BitReader<R, BigEndian>
[src]

Reads a twos-complement signed value from the stream with the given number of bits.

Errors

Passes along any I/O error from the underlying stream. Also returns an error if the output type is too small to hold the requested number of bits.

Examples

use std::io::{Read, Cursor};
use bitstream_io::{BigEndian, BitReader};
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::{BigEndian, BitReader};
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

impl<R: Read> BitReader<R, LittleEndian>
[src]

Reads a twos-complement signed value from the stream with the given number of bits.

Errors

Passes along any I/O error from the underlying stream. Also returns an error if the output type is too small to hold the requested number of bits.

Examples

use std::io::{Read, Cursor};
use bitstream_io::{LittleEndian, BitReader};
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::{LittleEndian, BitReader};
let data = [0;10];
let mut r = BitReader::endian(Cursor::new(&data), LittleEndian);
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

Auto Trait Implementations

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

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