//! Bitstream reader functionality.
//!
-//! Bitstream reader operates on `&[u8]` and allows to read bits from the slice in different modes.
+//! Bitstream reader operates on `&[u8]` and allows to read bits from the slice in different modes.
//!
//! # Examples
//!
//! use nihav_core::io::bitreader::{BitReader,BitReaderMode};
//!
//! # use nihav_core::io::bitreader::BitReaderResult;
-//! # fn foo() -> BitReaderResult<u32> {
+//! # fn foo() -> BitReaderResult<u32> {
//! let bits: [u8; 4] = [ 42, 43, 44, 45 ];
//! let mut br = BitReader::new(&bits, BitReaderMode::BE);
//! let value = br.read(17)?;
//! use nihav_core::io::bitreader::{BitReader,BitReaderMode};
//!
//! # use nihav_core::io::bitreader::BitReaderResult;
-//! # fn foo() -> BitReaderResult<()> {
+//! # fn foo() -> BitReaderResult<()> {
//! let bits: [u8; 4] = [ 42, 43, 44, 45 ];
//! let mut br = BitReader::new(&bits, BitReaderMode::BE);
//! let num_skip_bits = br.read(3)?;
/// Bitstream reading modes.
-#[derive(Debug)]
+#[derive(Debug,Clone,Copy)]
pub enum BitReaderMode {
/// The stream is big endian MSB first.
BE,
}
/// A list specifying general bitstream reading errors.
-#[derive(Debug)]
+#[derive(Debug,Clone,Copy)]
pub enum BitReaderError {
/// The reader is at the end of bitstream.
BitstreamEnd,
pub type BitReaderResult<T> = Result<T, BitReaderError>;
/// Bitstream reader.
-#[derive(Debug)]
+#[derive(Debug,Clone)]
pub struct BitReader<'a> {
cache: u64,
bits: u8,
impl<'a> BitReader<'a> {
/// Constructs a new instance of bitstream reader.
- ///
+ ///
/// # Examples
///
/// ```
BitReader{ cache: 0, pos: 0, bits: 0, src, mode }
}
+ /// Returns the data bitstream reader uses.
+ pub fn get_data(&self) -> &'a [u8] { self.src }
+
/// Reports the current bit position in the bitstream (usually simply the number of bits read so far).
pub fn tell(&self) -> usize {
self.pos * 8 - (self.bits as usize)
/// use nihav_core::io::bitreader::{BitReader,BitReaderMode};
///
/// # use nihav_core::io::bitreader::BitReaderResult;
- /// # fn foo() -> BitReaderResult<u32> {
+ /// # fn foo() -> BitReaderResult<u32> {
/// let bits: [u8; 4] = [ 42, 43, 44, 45 ];
/// let mut br = BitReader::new(&bits, BitReaderMode::BE);
/// let value = br.read(17)?;
if nbits == 0 { return Ok(0) }
if nbits > 32 { return Err(TooManyBitsRequested) }
if self.bits < nbits {
- if let Err(err) = self.refill() { return Err(err) }
+ self.refill()?;
if self.bits < nbits { return Err(BitstreamEnd) }
}
let res = self.read_cache(nbits);
pub fn read_s(&mut self, nbits: u8) -> BitReaderResult<i32> {
if nbits == 0 || nbits > 32 { return Err(TooManyBitsRequested) }
if self.bits < nbits {
- if let Err(err) = self.refill() { return Err(err) }
+ self.refill()?;
if self.bits < nbits { return Err(BitstreamEnd) }
}
let res = self.read_cache_s(nbits);
#[inline(always)]
pub fn read_bool(&mut self) -> BitReaderResult<bool> {
if self.bits < 1 {
- if let Err(err) = self.refill() { return Err(err) }
+ self.refill()?;
if self.bits < 1 { return Err(BitstreamEnd) }
}
let res = self.read_cache(1);
/// use nihav_core::io::bitreader::{BitReader,BitReaderMode};
///
/// # use nihav_core::io::bitreader::BitReaderResult;
- /// # fn foo() -> BitReaderResult<u32> {
+ /// # fn foo() -> BitReaderResult<u32> {
/// let bits: [u8; 4] = [ 42, 43, 44, 45 ];
/// let mut br = BitReader::new(&bits, BitReaderMode::BE);
/// let peek_value = br.peek(8); // this should return 42
self.reset_cache();
self.pos += ((skip_bits / 32) * 4) as usize;
skip_bits &= 0x1F;
- self.refill()?;
if skip_bits > 0 {
+ self.refill()?;
+ if u32::from(self.bits) < skip_bits {
+ return Err(BitstreamEnd);
+ }
self.skip_cache(skip_bits as u8);
}
Ok(())
/// use nihav_core::io::bitreader::{BitReader,BitReaderMode};
///
/// # use nihav_core::io::bitreader::BitReaderResult;
- /// # fn foo() -> BitReaderResult<u32> {
+ /// # fn foo() -> BitReaderResult<u32> {
/// let bits: [u8; 4] = [ 42, 43, 44, 45 ];
/// let mut br = BitReader::new(&bits, BitReaderMode::BE);
/// br.seek(16)?;
/// use nihav_core::io::bitreader::{BitReader,BitReaderMode};
///
/// # use nihav_core::io::bitreader::BitReaderResult;
- /// # fn foo() -> BitReaderResult<()> {
+ /// # fn foo() -> BitReaderResult<()> {
/// let bits: [u8; 4] = [ 42, 43, 44, 45 ];
/// let mut br = BitReader::new(&bits, BitReaderMode::BE);
/// br.skip(17)?; // now reader is at bit position 17