pub trait BitRead {
Show 25 methods
// Required methods
fn read_unsigned_counted<const MAX: u32, U>(
&mut self,
bits: BitCount<MAX>,
) -> Result<U>
where U: UnsignedInteger;
fn read_signed_counted<const MAX: u32, S>(
&mut self,
bits: impl TryInto<SignedBitCount<MAX>>,
) -> Result<S>
where S: SignedInteger;
fn read_to<V>(&mut self) -> Result<V>
where V: Primitive;
fn read_as_to<F, V>(&mut self) -> Result<V>
where F: Endianness,
V: Primitive;
fn byte_aligned(&self) -> bool;
fn byte_align(&mut self);
// Provided methods
fn read_bit(&mut self) -> Result<bool> { ... }
fn read<const BITS: u32, I>(&mut self) -> Result<I>
where I: Integer { ... }
fn read_var<I>(&mut self, bits: u32) -> Result<I>
where I: Integer + Sized { ... }
fn read_count<const MAX: u32>(&mut self) -> Result<BitCount<MAX>> { ... }
fn read_counted<const MAX: u32, I>(
&mut self,
bits: BitCount<MAX>,
) -> Result<I>
where I: Integer + Sized { ... }
fn read_unsigned<const BITS: u32, U>(&mut self) -> Result<U>
where U: UnsignedInteger { ... }
fn read_unsigned_var<U>(&mut self, bits: u32) -> Result<U>
where U: UnsignedInteger { ... }
fn read_signed<const BITS: u32, S>(&mut self) -> Result<S>
where S: SignedInteger { ... }
fn read_signed_var<S>(&mut self, bits: u32) -> Result<S>
where S: SignedInteger { ... }
fn read_const<const BITS: u32, const VALUE: u32, E>(
&mut self,
err: E,
) -> Result<(), E>
where E: From<Error> { ... }
fn skip(&mut self, bits: u32) -> Result<()> { ... }
fn read_bytes(&mut self, buf: &mut [u8]) -> Result<()> { ... }
fn read_to_bytes<const SIZE: usize>(&mut self) -> Result<[u8; SIZE]> { ... }
fn read_to_vec(&mut self, bytes: usize) -> Result<Vec<u8>> { ... }
fn read_unary<const STOP_BIT: u8>(&mut self) -> Result<u32> { ... }
fn parse<F: FromBitStream>(&mut self) -> Result<F, F::Error> { ... }
fn parse_with<'a, F: FromBitStreamWith<'a>>(
&mut self,
context: &F::Context,
) -> Result<F, F::Error> { ... }
fn read_huffman<T>(&mut self) -> Result<T::Symbol>
where T: FromBits { ... }
fn by_ref(&mut self) -> &mut Self { ... }
}
Expand description
A trait for anything that can read a variable number of potentially un-aligned values from an input stream
Required Methods§
Sourcefn read_unsigned_counted<const MAX: u32, U>(
&mut self,
bits: BitCount<MAX>,
) -> Result<U>where
U: UnsignedInteger,
fn read_unsigned_counted<const MAX: u32, U>(
&mut self,
bits: BitCount<MAX>,
) -> Result<U>where
U: UnsignedInteger,
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 bitstream_io::{BitReader, BitRead, BigEndian, BitCount};
let bytes: &[u8] = &[0b1111_0000];
let mut r = BitReader::endian(bytes, BigEndian);
// reading 4 bits with a maximum of 4 will fit into a u8
// so no runtime check needed
assert_eq!(r.read_unsigned_counted::<4, u8>(BitCount::new::<4>()).unwrap(), 0b1111);
// reading 4 bits with a maximum of 64 might not fit into a u8
// so we need to verify this at runtime
assert_eq!(r.read_unsigned_counted::<64, u8>(BitCount::new::<4>()).unwrap(), 0b0000);
Sourcefn read_signed_counted<const MAX: u32, S>(
&mut self,
bits: impl TryInto<SignedBitCount<MAX>>,
) -> Result<S>where
S: SignedInteger,
fn read_signed_counted<const MAX: u32, S>(
&mut self,
bits: impl TryInto<SignedBitCount<MAX>>,
) -> Result<S>where
S: SignedInteger,
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. Returns an error if the number of bits is 0, since one bit is always needed for the sign. Also returns an error if the output type is too small to hold the requested number of bits.
§Examples
use bitstream_io::{BitReader, BitRead, BigEndian, BitCount};
let bytes: &[u8] = &[0b0001_1111];
let mut r = BitReader::endian(bytes, BigEndian);
// reading 4 bits with a maximum of 4 will fit into an i8
// so no runtime check needed
assert_eq!(r.read_signed_counted::<4, i8>(BitCount::new::<4>()).unwrap(), 1);
// reading 4 bits with a maximum of 64 might not fit into an i8
// so we need to verify this at runtime
assert_eq!(r.read_signed_counted::<64, i8>(BitCount::new::<4>()).unwrap(), -1);
Sourcefn read_to<V>(&mut self) -> Result<V>where
V: Primitive,
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.
§Errors
Passes along any I/O error from the underlying stream.
§Examples
use bitstream_io::{BitReader, BitRead, BigEndian};
let bytes: &[u8] = &[0x12, 0x34, 0x56, 0x78];
let mut r = BitReader::endian(bytes, BigEndian);
assert_eq!(r.read_to::<u32>().unwrap(), 0x12_34_56_78);
use bitstream_io::{BitReader, BitRead, BigEndian};
let bytes: &[u8] = &[0x12, 0x34, 0x56, 0x78];
let mut r = BitReader::endian(bytes, BigEndian);
assert_eq!(r.read_to::<[u8; 4]>().unwrap(), [0x12, 0x34, 0x56, 0x78]);
Sourcefn read_as_to<F, V>(&mut self) -> Result<V>where
F: Endianness,
V: Primitive,
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.
§Errors
Passes along any I/O error from the underlying stream.
§Example
use bitstream_io::{BitReader, BitRead, BigEndian, LittleEndian};
let bytes: &[u8] = &[0x12, 0x34, 0x56, 0x78];
let mut r = BitReader::endian(bytes, BigEndian);
assert_eq!(r.read_as_to::<LittleEndian, u32>().unwrap(), 0x78_56_34_12);
Sourcefn byte_aligned(&self) -> bool
fn byte_aligned(&self) -> bool
Returns true if the stream is aligned at a whole byte.
§Example
use std::io::Read;
use bitstream_io::{BigEndian, BitReader, BitRead};
let data = [0];
let mut reader = BitReader::endian(data.as_slice(), 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);
Sourcefn byte_align(&mut self)
fn byte_align(&mut self)
Throws away all unread bit values until the next whole byte. Does nothing if the stream is already aligned.
§Example
use bitstream_io::{BigEndian, BitReader, BitRead};
let data: &[u8] = &[0x00, 0xFF];
let mut reader = BitReader::endian(data, BigEndian);
assert_eq!(reader.read::<4, u8>().unwrap(), 0);
reader.byte_align();
assert_eq!(reader.read::<8, u8>().unwrap(), 0xFF);
Provided Methods§
Sourcefn read_bit(&mut self) -> Result<bool>
fn read_bit(&mut self) -> Result<bool>
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 bitstream_io::{BitReader, BitRead, BigEndian};
let bytes: &[u8] = &[0b1000_1110];
let mut r = BitReader::endian(bytes, BigEndian);
assert_eq!(r.read_bit().unwrap(), true);
assert_eq!(r.read_bit().unwrap(), false);
assert_eq!(r.read_bit().unwrap(), false);
assert_eq!(r.read_bit().unwrap(), false);
assert_eq!(r.read_bit().unwrap(), true);
assert_eq!(r.read_bit().unwrap(), true);
assert_eq!(r.read_bit().unwrap(), true);
assert_eq!(r.read_bit().unwrap(), false);
assert!(r.read_bit().is_err()); // no more bits to read
use bitstream_io::{BitReader, BitRead, LittleEndian};
let bytes: &[u8] = &[0b1000_1110];
let mut r = BitReader::endian(bytes, LittleEndian);
assert_eq!(r.read_bit().unwrap(), false);
assert_eq!(r.read_bit().unwrap(), true);
assert_eq!(r.read_bit().unwrap(), true);
assert_eq!(r.read_bit().unwrap(), true);
assert_eq!(r.read_bit().unwrap(), false);
assert_eq!(r.read_bit().unwrap(), false);
assert_eq!(r.read_bit().unwrap(), false);
assert_eq!(r.read_bit().unwrap(), true);
assert!(r.read_bit().is_err()); // no more bits to read
Sourcefn read<const BITS: u32, I>(&mut self) -> Result<I>where
I: Integer,
fn read<const BITS: u32, I>(&mut self) -> Result<I>where
I: Integer,
Reads a signed or unsigned value from the stream with the given constant number of bits.
§Errors
Passes along any I/O error from the underlying stream. A compile-time error occurs if the given number of bits is larger than the output type.
§Examples
use bitstream_io::{BitReader, BitRead, BigEndian};
let bytes: &[u8] = &[0b0001_1111, 0b1011_11_00];
let mut r = BitReader::endian(bytes, BigEndian);
// reading unsigned value is ok
assert_eq!(r.read::<4, u8>().unwrap(), 1);
// reading signed value is also ok
assert_eq!(r.read::<4, i8>().unwrap(), -1);
// reading an array of bits is ok too
assert_eq!(r.read::<1, [bool; 4]>().unwrap(), [true, false, true, true]);
// reading an array of any Integer type is ok
assert_eq!(r.read::<2, [u8; 2]>().unwrap(), [0b11, 0b00]);
// reading more bytes than we have is an error
assert!(r.read::<4, u8>().is_err());
use bitstream_io::{BitReader, BitRead, BigEndian};
let bytes: &[u8] = &[0b0001_1111, 0, 0];
let mut r = BitReader::endian(bytes, BigEndian);
// reading 9 bits to a u8 is a compile-time error
r.read::<9, u8>();
Examples found in repository?
21 fn from_reader<R: BitRead + ?Sized>(r: &mut R) -> std::io::Result<Self> {
22 Ok(Self {
23 last_block: r.read_bit()?,
24 block_type: r.read::<7, _>()?,
25 block_size: r.read::<24, _>()?,
26 })
27 }
28}
29
30#[derive(Debug, PartialEq, Eq)]
31struct Streaminfo {
32 minimum_block_size: u16, // 16 bits
33 maximum_block_size: u16, // 16 bits
34 minimum_frame_size: u32, // 24 bits
35 maximum_frame_size: u32, // 24 bits
36 sample_rate: u32, // 20 bits
37 channels: NonZero<u8>, // 3 bits
38 bits_per_sample: NonZero<u8>, // 5 bits
39 total_samples: u64, // 36 bits
40 md5: [u8; 16], // 16 bytes
41}
42
43impl FromBitStream for Streaminfo {
44 type Error = std::io::Error;
45
46 fn from_reader<R: BitRead + ?Sized>(r: &mut R) -> std::io::Result<Self> {
47 Ok(Self {
48 minimum_block_size: r.read_to()?,
49 maximum_block_size: r.read_to()?,
50 minimum_frame_size: r.read::<24, _>()?,
51 maximum_frame_size: r.read::<24, _>()?,
52 sample_rate: r.read::<20, _>()?,
53 channels: r.read::<3, _>()?,
54 bits_per_sample: r.read::<5, _>()?,
55 total_samples: r.read::<36, _>()?,
56 md5: r.read_to()?,
57 })
58 }
Sourcefn read_var<I>(&mut self, bits: u32) -> Result<I>
fn read_var<I>(&mut self, bits: u32) -> Result<I>
Reads a signed or unsigned value from the stream with the given variable 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 bitstream_io::{BitReader, BitRead, BigEndian};
let bytes: &[u8] = &[0b0001_1111];
let mut r = BitReader::endian(bytes, BigEndian);
// reading unsigned value is ok
assert_eq!(r.read_var::<u8>(4).unwrap(), 1);
// reading signed value is also ok
assert_eq!(r.read_var::<i8>(4).unwrap(), -1);
// reading more bytes than we have is an error
assert!(r.read_var::<u8>(4).is_err());
use bitstream_io::{BitReader, BitRead, BigEndian};
let bytes: &[u8] = &[0, 0, 0, 0, 0];
let mut r = BitReader::endian(bytes, BigEndian);
// reading 9 bits to a u8 is a runtime error
// no matter how much data is left
assert!(r.read_var::<u8>(9).is_err());
Sourcefn read_count<const MAX: u32>(&mut self) -> Result<BitCount<MAX>>
fn read_count<const MAX: u32>(&mut self) -> Result<BitCount<MAX>>
Given a desired maximum value for a bit count, reads the necessary bits to fill up to that amount.
For example, if the maximum bit count is 15 - or 0b1111
-
reads a 4-bit unsigned value from the stream and returns a BitCount
which can be used in subsequent reads.
Note that MAX
must be greater than 0, and MAX + 1
must be
an exact power of two.
§Errors
Passes along an I/O error from the underlying stream.
§Examples
use bitstream_io::{BigEndian, BitReader, BitRead};
let bytes: &[u8] = &[0b100_11110];
let mut r = BitReader::endian(bytes, BigEndian);
let count = r.read::<3, u32>().unwrap();
assert_eq!(count, 4); // reads 0b100 - or 4
// may need to verify count is not larger than u8 at runtime
assert_eq!(r.read_var::<u8>(count).unwrap(), 0b1111);
use bitstream_io::{BigEndian, BitReader, BitRead, BitCount};
let bytes: &[u8] = &[0b100_11110];
let mut r = BitReader::endian(bytes, BigEndian);
let count = r.read_count::<0b111>().unwrap();
assert_eq!(count, BitCount::new::<4>()); // reads 0b100 - or 4
// maximum size of bit count is known to be 7 at compile-time,
// so no runtime check needed to know 7 bits is not larger than a u8
assert_eq!(r.read_counted::<0b111, u8>(count).unwrap(), 0b1111);
use bitstream_io::{BigEndian, BitReader, BitRead};
let bytes: &[u8] = &[0b100_11110];
let mut r = BitReader::endian(bytes, BigEndian);
// maximum bit count is 6 (0b110), so we need to read 3 bits
// but no idea what to do if a value of 7 (0b111) is read,
// so this does not compile at all
let count = r.read_count::<0b110>();
Sourcefn read_counted<const MAX: u32, I>(&mut self, bits: BitCount<MAX>) -> Result<I>
fn read_counted<const MAX: u32, I>(&mut self, bits: BitCount<MAX>) -> Result<I>
Reads a signed or 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 bitstream_io::{BitReader, BitRead, BigEndian, BitCount};
let bytes: &[u8] = &[0b1111_0000];
let mut r = BitReader::endian(bytes, BigEndian);
// reading 4 bits with a maximum of 4 will fit into a u8
// so no runtime check needed
assert_eq!(r.read_counted::<4, u8>(BitCount::new::<4>()).unwrap(), 0b1111);
// reading 4 bits with a maximum of 64 might not fit into a u8
// so we need to verify this at runtime
assert_eq!(r.read_counted::<64, u8>(BitCount::new::<4>()).unwrap(), 0b0000);
Sourcefn read_unsigned<const BITS: u32, U>(&mut self) -> Result<U>where
U: UnsignedInteger,
fn read_unsigned<const BITS: u32, U>(&mut self) -> Result<U>where
U: UnsignedInteger,
Reads an unsigned value from the stream with the given constant number of bits.
§Errors
Passes along any I/O error from the underlying stream. A compile-time error occurs if the given number of bits is larger than the output type.
§Examples
use bitstream_io::{BigEndian, BitReader, BitRead};
let data: &[u8] = &[0b1_01_10111];
let mut reader = BitReader::endian(data, BigEndian);
assert_eq!(reader.read_unsigned::<1, u8>().unwrap(), 0b1);
assert_eq!(reader.read_unsigned::<2, u8>().unwrap(), 0b01);
assert_eq!(reader.read_unsigned::<5, u8>().unwrap(), 0b10111);
use bitstream_io::{LittleEndian, BitReader, BitRead};
let data: &[u8] = &[0b10110_11_1];
let mut reader = BitReader::endian(data, LittleEndian);
assert_eq!(reader.read_unsigned::<1, u8>().unwrap(), 0b1);
assert_eq!(reader.read_unsigned::<2, u8>().unwrap(), 0b11);
assert_eq!(reader.read_unsigned::<5, u8>().unwrap(), 0b10110);
use bitstream_io::{BigEndian, BitReader, BitRead};
let data: &[u8] = &[0, 0, 0, 0, 0];
let mut reader = BitReader::endian(data, BigEndian);
// doesn't compile at all
reader.read_unsigned::<9, u8>(); // can't read 9 bits to u8
Sourcefn read_unsigned_var<U>(&mut self, bits: u32) -> Result<U>where
U: UnsignedInteger,
fn read_unsigned_var<U>(&mut self, bits: u32) -> Result<U>where
U: UnsignedInteger,
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 bitstream_io::{BigEndian, BitReader, BitRead};
let data: &[u8] = &[0b1_01_10111];
let mut reader = BitReader::endian(data, BigEndian);
assert_eq!(reader.read_unsigned_var::<u8>(1).unwrap(), 0b1);
assert_eq!(reader.read_unsigned_var::<u8>(2).unwrap(), 0b01);
assert_eq!(reader.read_unsigned_var::<u8>(5).unwrap(), 0b10111);
use bitstream_io::{LittleEndian, BitReader, BitRead};
let data: &[u8] = &[0b10110_11_1];
let mut reader = BitReader::endian(data, LittleEndian);
assert_eq!(reader.read_unsigned_var::<u8>(1).unwrap(), 0b1);
assert_eq!(reader.read_unsigned_var::<u8>(2).unwrap(), 0b11);
assert_eq!(reader.read_unsigned_var::<u8>(5).unwrap(), 0b10110);
use bitstream_io::{BigEndian, BitReader, BitRead};
let data: &[u8] = &[0, 0, 0, 0, 0];
let mut reader = BitReader::endian(data, BigEndian);
assert!(reader.read_unsigned_var::<u8>(9).is_err()); // can't read 9 bits to u8
assert!(reader.read_unsigned_var::<u16>(17).is_err()); // can't read 17 bits to u16
assert!(reader.read_unsigned_var::<u32>(33).is_err()); // can't read 33 bits to u32
assert!(reader.read_unsigned_var::<u64>(65).is_err()); // can't read 65 bits to u64
Sourcefn read_signed<const BITS: u32, S>(&mut self) -> Result<S>where
S: SignedInteger,
fn read_signed<const BITS: u32, S>(&mut self) -> Result<S>where
S: SignedInteger,
Reads a twos-complement signed value from the stream with the given constant number of bits.
§Errors
Passes along any I/O error from the underlying stream. A compile-time error occurs if the number of bits is 0, since one bit is always needed for the sign. A compile-time error occurs if the given number of bits is larger than the output type.
§Examples
use bitstream_io::{BigEndian, BitReader, BitRead};
let data: &[u8] = &[0b1011_0111];
let mut reader = BitReader::endian(data, BigEndian);
assert_eq!(reader.read_signed::<4, i8>().unwrap(), -5);
assert_eq!(reader.read_signed::<4, i8>().unwrap(), 7);
assert!(reader.read_signed::<4, i8>().is_err());
use bitstream_io::{LittleEndian, BitReader, BitRead};
let data: &[u8] = &[0b1011_0111];
let mut reader = BitReader::endian(data, LittleEndian);
assert_eq!(reader.read_signed::<4, i8>().unwrap(), 7);
assert_eq!(reader.read_signed::<4, i8>().unwrap(), -5);
assert!(reader.read_signed::<4, i8>().is_err());
use bitstream_io::{LittleEndian, BitReader, BitRead};
let data: &[u8] = &[0, 0, 0, 0, 0];
let mut reader = BitReader::endian(data, LittleEndian);
// reading 9 bits to an i8 is a compile-time error
reader.read_signed::<9, i8>();
Sourcefn read_signed_var<S>(&mut self, bits: u32) -> Result<S>where
S: SignedInteger,
fn read_signed_var<S>(&mut self, bits: u32) -> Result<S>where
S: SignedInteger,
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. Returns an error if the number of bits is 0, since one bit is always needed for the sign. Also returns an error if the output type is too small to hold the requested number of bits.
§Examples
use bitstream_io::{BigEndian, BitReader, BitRead};
let data: &[u8] = &[0b1011_0111];
let mut reader = BitReader::endian(data, BigEndian);
assert_eq!(reader.read_signed_var::<i8>(4).unwrap(), -5);
assert_eq!(reader.read_signed_var::<i8>(4).unwrap(), 7);
use bitstream_io::{LittleEndian, BitReader, BitRead};
let data: &[u8] = &[0b1011_0111];
let mut reader = BitReader::endian(data, LittleEndian);
assert_eq!(reader.read_signed_var::<i8>(4).unwrap(), 7);
assert_eq!(reader.read_signed_var::<i8>(4).unwrap(), -5);
use std::io::Read;
use bitstream_io::{BigEndian, BitReader, BitRead};
let data: &[u8] = &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
let mut r = BitReader::endian(data, BigEndian);
assert!(r.read_signed_var::<i8>(9).is_err()); // can't read 9 bits to i8
assert!(r.read_signed_var::<i16>(17).is_err()); // can't read 17 bits to i16
assert!(r.read_signed_var::<i32>(33).is_err()); // can't read 33 bits to i32
assert!(r.read_signed_var::<i64>(65).is_err()); // can't read 65 bits to i64
Sourcefn read_const<const BITS: u32, const VALUE: u32, E>(
&mut self,
err: E,
) -> Result<(), E>
fn read_const<const BITS: u32, const VALUE: u32, E>( &mut self, err: E, ) -> Result<(), E>
Reads the given constant value from the stream with the given number of bits.
Due to current limitations of constant paramters,
this is limited to u32
values.
If the constant read from the stream doesn’t match the expected value, returns the generated error from the closure.
§Errors
Passes along any I/O error from the underlying stream, converted to the mismatch error. Returns the generated error if the read value doesn’t match the expected constant.
§Examples
use bitstream_io::{BitReader, BitRead, BigEndian};
enum Error {
Mismatch,
Io,
}
impl From<std::io::Error> for Error {
fn from(_err: std::io::Error) -> Self {
Self::Io
}
}
let data: &[u8] = &[0b1000_1011, 0b0000_0001];
let mut r = BitReader::endian(data, BigEndian);
assert!(r.read_const::<4, 0b1000, _>(Error::Mismatch).is_ok());
assert!(r.read_const::<4, 0b1011, _>(Error::Mismatch).is_ok());
// 0b1000 doesn't match 0b0000
assert!(matches!(r.read_const::<4, 0b1000, _>(Error::Mismatch), Err(Error::Mismatch)));
// 0b1011 doesn't match 0b0001
assert!(matches!(r.read_const::<4, 0b1011, _>(Error::Mismatch), Err(Error::Mismatch)));
// run out of bits to check
assert!(matches!(r.read_const::<4, 0b0000, _>(Error::Mismatch), Err(Error::Io)));
Sourcefn skip(&mut self, bits: u32) -> Result<()>
fn skip(&mut self, bits: u32) -> Result<()>
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.
§Example
use bitstream_io::{BitReader, BitRead, BigEndian};
let bytes: &[u8] = &[0b1_00000_10];
let mut r = BitReader::endian(bytes, BigEndian);
assert_eq!(r.read_bit().unwrap(), true);
assert!(r.skip(5).is_ok());
assert_eq!(r.read_bit().unwrap(), true);
assert_eq!(r.read_bit().unwrap(), false);
assert!(r.read_bit().is_err());
Sourcefn read_bytes(&mut self, buf: &mut [u8]) -> Result<()>
fn read_bytes(&mut self, buf: &mut [u8]) -> Result<()>
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 bitstream_io::{BitReader, BitRead, BigEndian};
let bytes: &[u8] = &[0x00, 0x01, 0x02, 0x03, 0x04];
let mut r = BitReader::endian(bytes, BigEndian);
let mut buf = [0; 3];
assert_eq!(r.read::<8, u8>().unwrap(), 0x00);
assert!(r.read_bytes(&mut buf).is_ok());
assert_eq!(&buf, &[0x01, 0x02, 0x03]);
assert_eq!(r.read::<8, u8>().unwrap(), 0x04);
Sourcefn read_to_bytes<const SIZE: usize>(&mut self) -> Result<[u8; SIZE]>
👎Deprecated since 1.8.0: use read_to() method instead
fn read_to_bytes<const SIZE: usize>(&mut self) -> Result<[u8; SIZE]>
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.
§Errors
Passes along any I/O error from the underlying stream.
Sourcefn read_to_vec(&mut self, bytes: usize) -> Result<Vec<u8>>
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.
§Errors
Passes along any I/O error from the underlying stream.
§Example
use bitstream_io::{BitReader, BitRead, BigEndian};
let bytes: &[u8] = &[0x00, 0x01, 0x02, 0x03, 0x04];
let mut r = BitReader::endian(bytes, BigEndian);
let mut buf = [0; 3];
assert_eq!(r.read::<8, u8>().unwrap(), 0x00);
assert_eq!(r.read_to_vec(3).unwrap().as_slice(), &[0x01, 0x02, 0x03]);
assert_eq!(r.read::<8, u8>().unwrap(), 0x04);
Sourcefn read_unary<const STOP_BIT: u8>(&mut self) -> Result<u32>
fn read_unary<const STOP_BIT: u8>(&mut self) -> Result<u32>
Counts the number of bits in the stream until STOP_BIT
and returns the amount read.
STOP_BIT
must be 0 or 1.
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.
May panic if the number of bits exceeds u32
.
§Examples
use bitstream_io::{BitReader, BitRead, BigEndian};
let bytes: &[u8] = &[0b0_10_11111, 0b10_000000];
let mut r = BitReader::endian(bytes, BigEndian);
// read 1 bits until stop bit of 0, big-endian order
assert_eq!(r.read_unary::<0>().unwrap(), 0);
assert_eq!(r.read_unary::<0>().unwrap(), 1);
assert_eq!(r.read_unary::<0>().unwrap(), 6);
use bitstream_io::{BitReader, BitRead, BigEndian};
let bytes: &[u8] = &[0b1_01_00000, 0b01_000000];
let mut r = BitReader::endian(bytes, BigEndian);
// read 0 bits until stop bit of 1, big-endian order
assert_eq!(r.read_unary::<1>().unwrap(), 0);
assert_eq!(r.read_unary::<1>().unwrap(), 1);
assert_eq!(r.read_unary::<1>().unwrap(), 6);
use bitstream_io::{BitReader, BitRead, LittleEndian};
let bytes: &[u8] = &[0b11111_01_0, 0b000000_01];
let mut r = BitReader::endian(bytes, LittleEndian);
// read 1 bits until stop bit of 0, little-endian order
assert_eq!(r.read_unary::<0>().unwrap(), 0);
assert_eq!(r.read_unary::<0>().unwrap(), 1);
assert_eq!(r.read_unary::<0>().unwrap(), 6);
use bitstream_io::{BitReader, BitRead, LittleEndian};
let bytes: &[u8] = &[0b00000_10_1, 0b111111_10];
let mut r = BitReader::endian(bytes, LittleEndian);
// read 0 bits until stop bit of 1, little-endian order
assert_eq!(r.read_unary::<1>().unwrap(), 0);
assert_eq!(r.read_unary::<1>().unwrap(), 1);
assert_eq!(r.read_unary::<1>().unwrap(), 6);
Sourcefn parse<F: FromBitStream>(&mut self) -> Result<F, F::Error>
fn parse<F: FromBitStream>(&mut self) -> Result<F, F::Error>
Parses and returns complex type
Examples found in repository?
90fn main() {
91 // test FLAC file data
92 let flac = include_bytes!("data/metadata-only.flac");
93
94 let mut reader = BitReader::endian(flac.as_slice(), BigEndian);
95
96 // stream marker
97 assert_eq!(&reader.read_to::<[u8; 4]>().unwrap(), b"fLaC");
98
99 // metadata block header
100 assert_eq!(
101 reader.parse::<BlockHeader>().unwrap(),
102 BlockHeader {
103 last_block: false,
104 block_type: 0,
105 block_size: 34
106 }
107 );
108
109 // STREAMINFO block
110 assert_eq!(
111 dbg!(reader.parse::<Streaminfo>().unwrap()),
112 Streaminfo {
113 minimum_block_size: 4096,
114 maximum_block_size: 4096,
115 minimum_frame_size: 1542,
116 maximum_frame_size: 8546,
117 sample_rate: 44100,
118 channels: NonZero::new(2).unwrap(),
119 bits_per_sample: NonZero::new(16).unwrap(),
120 total_samples: 304844,
121 md5: *b"\xFA\xF2\x69\x2F\xFD\xEC\x2D\x5B\x30\x01\x76\xB4\x62\x88\x7D\x92",
122 }
123 );
124
125 // metadata block header
126 assert_eq!(
127 dbg!(reader.parse::<BlockHeader>().unwrap()),
128 BlockHeader {
129 last_block: false,
130 block_type: 4,
131 block_size: 122
132 }
133 );
134
135 // VORBIS_COMMENT block
136 assert_eq!(
137 dbg!(reader.parse::<VorbisComment>().unwrap()),
138 VorbisComment {
139 vendor: "reference libFLAC 1.1.4 20070213".to_string(),
140 comment: vec![
141 "title=2ch 44100 16bit".to_string(),
142 "album=Test Album".to_string(),
143 "artist=Assorted".to_string(),
144 "tracknumber=1".to_string(),
145 ],
146 }
147 );
148}
Sourcefn parse_with<'a, F: FromBitStreamWith<'a>>(
&mut self,
context: &F::Context,
) -> Result<F, F::Error>
fn parse_with<'a, F: FromBitStreamWith<'a>>( &mut self, context: &F::Context, ) -> Result<F, F::Error>
Parses and returns complex type with context
Sourcefn read_huffman<T>(&mut self) -> Result<T::Symbol>where
T: FromBits,
fn read_huffman<T>(&mut self) -> Result<T::Symbol>where
T: FromBits,
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 bitstream_io::{BitReader, BitRead, BigEndian, define_huffman_tree, huffman::FromBits};
define_huffman_tree!(TreeName : char = ['a', ['b', ['c', 'd']]]);
// 'a' is 0
// 'b' is 1 -> 0
// 'c' is 1 -> 1 -> 0
// 'd' is 1 -> 1 -> 1
let data: &[u8] = &[0b0_10_110_11, 0b1_0000000];
let mut r = BitReader::endian(data, BigEndian);
assert_eq!(r.read_huffman::<TreeName>().unwrap(), 'a');
assert_eq!(r.read_huffman::<TreeName>().unwrap(), 'b');
assert_eq!(r.read_huffman::<TreeName>().unwrap(), 'c');
assert_eq!(r.read_huffman::<TreeName>().unwrap(), 'd');
Sourcefn by_ref(&mut self) -> &mut Self
fn by_ref(&mut self) -> &mut Self
Creates a “by reference” adaptor for this BitRead
The returned adapter also implements BitRead
and will borrow the current reader.
§Example
use bitstream_io::{BitReader, BitRead, BigEndian};
fn parse<R: BitRead>(r: R) {
// perform some parsing
}
let data: &[u8] = &[0];
let mut reader = BitReader::endian(data, BigEndian);
// performing parsing by reference
parse(reader.by_ref());
// original owned reader still available
assert_eq!(reader.read::<8, u8>().unwrap(), 0);
Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.