Trait bitter::BitReader [−][src]
pub trait BitReader {
Show methods
fn read_bit(&mut self) -> Option<bool>;
fn read_u8(&mut self) -> Option<u8>;
fn read_i8(&mut self) -> Option<i8>;
fn read_u16(&mut self) -> Option<u16>;
fn read_i16(&mut self) -> Option<i16>;
fn read_u32(&mut self) -> Option<u32>;
fn read_i32(&mut self) -> Option<i32>;
fn read_u64(&mut self) -> Option<u64>;
fn read_i64(&mut self) -> Option<i64>;
fn read_f32(&mut self) -> Option<f32>;
fn read_f64(&mut self) -> Option<f64>;
fn read_bits(&mut self, bits: i32) -> Option<u64>;
fn read_signed_bits(&mut self, bits: i32) -> Option<i64>;
fn if_get<T, F>(&mut self, f: F) -> Option<Option<T>>
where
F: FnMut(&mut Self) -> Option<T>;
fn read_bits_max(&mut self, max: u64) -> Option<u64>;
fn read_bits_max_computed(&mut self, bits: i32, max: u64) -> Option<u64>;
fn read_bit_unchecked(&mut self) -> bool;
fn read_u8_unchecked(&mut self) -> u8;
fn read_i8_unchecked(&mut self) -> i8;
fn read_u16_unchecked(&mut self) -> u16;
fn read_i16_unchecked(&mut self) -> i16;
fn read_u32_unchecked(&mut self) -> u32;
fn read_i32_unchecked(&mut self) -> i32;
fn read_u64_unchecked(&mut self) -> u64;
fn read_i64_unchecked(&mut self) -> i64;
fn read_f32_unchecked(&mut self) -> f32;
fn read_f64_unchecked(&mut self) -> f64;
fn read_bits_unchecked(&mut self, bits: i32) -> u64;
fn read_signed_bits_unchecked(&mut self, bits: i32) -> i64;
fn if_get_unchecked<T, F>(&mut self, f: F) -> Option<T>
where
F: FnMut(&mut Self) -> T;
fn read_bits_max_unchecked(&mut self, max: u64) -> u64;
fn read_bits_max_computed_unchecked(&mut self, bits: i32, max: u64) -> u64;
fn approx_bytes_remaining(&self) -> usize;
fn bits_remaining(&self) -> Option<usize>;
fn has_bits_remaining(&self, bits: usize) -> bool;
fn read_bytes(&mut self, buf: &mut [u8]) -> bool;
fn is_empty(&self) -> bool;
}Expand description
Read bits in a given endian order
Required methods
Consume a bit and return if the bit was enabled
use bitter::{BitReader, BigEndianReader}; let mut bits = BigEndianReader::new(&[0b1001_0011]); assert_eq!(bits.read_bit(), Some(true)); assert_eq!(bits.read_bit(), Some(false));
Consume 8 bits and return the deserialized byte
use bitter::{BitReader, BigEndianReader}; let mut bits = BigEndianReader::new(&[0b1001_0011]); assert_eq!(bits.read_u8(), Some(0b1001_0011));
Consume 8 bits and return the deserialized byte
use bitter::{BitReader, BigEndianReader}; let mut bits = BigEndianReader::new(&[0b1001_0011]); assert_eq!(bits.read_i8(), Some(-109));
Consume 16 bits and return the deserialized short
use bitter::{BitReader, LittleEndianReader}; let mut bits = LittleEndianReader::new(&[0b1001_0011, 0b1111_1111]); assert_eq!(bits.read_u16(), Some(0xff93));
Consume 16 bits and return the deserialized short
use bitter::{BitReader, LittleEndianReader}; let data = (-500i16).to_le_bytes(); let mut bits = LittleEndianReader::new(&data); assert_eq!(bits.read_i16(), Some(-500));
Consume 32 bits and return the deserialized int
use bitter::{BitReader, LittleEndianReader}; let data = (22000u32).to_le_bytes(); let mut bits = LittleEndianReader::new(&data); assert_eq!(bits.read_u32(), Some(22000u32));
Consume 32 bits and return the deserialized int
use bitter::{BitReader, BigEndianReader}; let data = (-22000i32).to_be_bytes(); let mut bits = BigEndianReader::new(&data); assert_eq!(bits.read_i32(), Some(-22000i32));
Consume 64 bits and return the deserialized long
use bitter::{BitReader, BigEndianReader}; let data = (22000u64).to_be_bytes(); let mut bits = BigEndianReader::new(&data); assert_eq!(bits.read_u64(), Some(22000u64));
Consume 64 bits and return the deserialized long
use bitter::{BitReader, BigEndianReader}; let data = (-22000i64).to_be_bytes(); let mut bits = BigEndianReader::new(&data); assert_eq!(bits.read_i64(), Some(-22000i64));
Consume 32 bits and return the deserialized floating point
use bitter::{BitReader, BigEndianReader}; let data = 12.5f32.to_be_bytes(); let mut bits = BigEndianReader::new(&data); assert_eq!(bits.read_f32(), Some(12.5f32));
Consume 64 bits and return the deserialized double floating point
use bitter::{BitReader, BigEndianReader}; let data = 12.5f64.to_be_bytes(); let mut bits = BigEndianReader::new(&data); assert_eq!(bits.read_f64(), Some(12.5f64));
Reads an arbitrary number of bits from 1 to 64 (inclusive) and returns the unsigned result
use bitter::{BitReader, BigEndianReader}; let mut bitter = BigEndianReader::new(&[0xff, 0x00, 0xab, 0xcd]); assert_eq!(bitter.read_bits(32), Some(0xff00abcd));
fn read_signed_bits(&mut self, bits: i32) -> Option<i64>
fn read_signed_bits(&mut self, bits: i32) -> Option<i64>Reads an arbitrary number of bits from 1 to 64 (inclusive) and returns the signed result. If the most significant bit is enabled, the result will be negative. This can be somewhat counterintuitive so see the examples
use bitter::{BitReader, BigEndianReader}; let mut bitter = BigEndianReader::new(&[0xfa, 0x93]); assert_eq!(bitter.read_signed_bits(4), Some(-1)); assert_eq!(bitter.read_signed_bits(4), Some(-6)); assert_eq!(bitter.read_signed_bits(4), Some(-7)); assert_eq!(bitter.read_signed_bits(4), Some(3));
To think of it another way, reading the number of bits equivalent to a builtin type (i8, i16, etc), will always equal its associated ergonomic equivalent when casted.
use bitter::{BitReader, BigEndianReader}; let mut bitter = BigEndianReader::new(&[0xff]); let mut bitter2 = BigEndianReader::new(&[0xff]); assert_eq!( bitter.read_signed_bits(8).map(|x| x as i8), bitter2.read_i8() );
If the next bit is available and on, decode the next chunk of data (which can return None). The return value can be one of the following:
- None: Not enough data was available
- Some(None): Bit was off so data not decoded
- Some(x): Bit was on and data was decoded
use bitter::{LittleEndianReader, BitReader}; let mut bitter = LittleEndianReader::new(&[0xff, 0x04]); assert_eq!(bitter.if_get(BitReader::read_u8), Some(Some(0x7f))); assert_eq!(bitter.if_get(BitReader::read_u8), Some(None)); assert_eq!(bitter.if_get(BitReader::read_u8), None);
fn read_bits_max(&mut self, max: u64) -> Option<u64>
fn read_bits_max(&mut self, max: u64) -> Option<u64>Reads a value from the stream that consumes the same or fewer number of bits of a given max. The value read will always be less than the given max.
For example if one wants to read a value that is less than 20, bitter will read at least
4 bits from the stream. If the 5th bit would cause the accumulator to exceed the max, the
5th bit is not consumed. Else the 5th bit is consumed and added to accumulator. If the
necessary number of bits are not available, None is returned.
use bitter::{LittleEndianReader, BitReader}; let mut bitter = LittleEndianReader::new(&[0b1111_1000]); assert_eq!(bitter.read_bits_max(20), Some(8)); assert_eq!(bitter.read_bits_max(20), Some(15));
Same as read_bits_max except that this function accepts the already computed number of
bits to at least read. For instance, if 20 is the max, then 4 bits are at least needed.
In general, prefer read_bits_max for ease of use, as passing an incorrectly
computed max can lead to undefined behavior
use bitter::{LittleEndianReader, BitReader}; let mut bitter = LittleEndianReader::new(&[0b1111_1000]); assert_eq!(bitter.read_bits_max_computed(4, 20), Some(8)); assert_eq!(bitter.read_bits_max_computed(4, 20), Some(15));
fn read_bit_unchecked(&mut self) -> bool
fn read_bit_unchecked(&mut self) -> boolAssumes there is at least one bit left in the stream.
use bitter::{LittleEndianReader, BitReader}; let mut bitter = LittleEndianReader::new(&[0b1010_1010, 0b0101_0101]); assert_eq!(bitter.read_bit_unchecked(), false);
fn read_u8_unchecked(&mut self) -> u8
fn read_u8_unchecked(&mut self) -> u8Assumes there is at least 8 bits left in the stream.
use bitter::{BigEndianReader, BitReader}; let mut bitter = BigEndianReader::new(&[0b1010_1010, 0b0101_0101]); assert_eq!(bitter.read_u8_unchecked(), 0b1010_1010);
fn read_i8_unchecked(&mut self) -> i8
fn read_i8_unchecked(&mut self) -> i8Assumes there is at least 8 bits left in the stream.
use bitter::{BigEndianReader, BitReader}; let mut bitter = BigEndianReader::new(&[0b1010_1010, 0b0101_0101]); assert_eq!(bitter.read_i8_unchecked(), i8::from_be_bytes([0b1010_1010]));
fn read_u16_unchecked(&mut self) -> u16
fn read_u16_unchecked(&mut self) -> u16Consume 16 bits and return the deserialized short
use bitter::{BitReader, LittleEndianReader}; let mut bits = LittleEndianReader::new(&[0b1001_0011, 0b1111_1111]); assert_eq!(bits.read_u16_unchecked(), 0xff93);
fn read_i16_unchecked(&mut self) -> i16
fn read_i16_unchecked(&mut self) -> i16Consume 16 bits and return the deserialized short
use bitter::{BitReader, LittleEndianReader}; let data = (-500i16).to_le_bytes(); let mut bits = LittleEndianReader::new(&data); assert_eq!(bits.read_i16_unchecked(), -500);
fn read_u32_unchecked(&mut self) -> u32
fn read_u32_unchecked(&mut self) -> u32Consume 32 bits and return the deserialized int
use bitter::{BitReader, LittleEndianReader}; let data = (22000u32).to_le_bytes(); let mut bits = LittleEndianReader::new(&data); assert_eq!(bits.read_u32_unchecked(), 22000u32);
fn read_i32_unchecked(&mut self) -> i32
fn read_i32_unchecked(&mut self) -> i32Consume 32 bits and return the deserialized int
use bitter::{BitReader, BigEndianReader}; let data = (-22000i32).to_be_bytes(); let mut bits = BigEndianReader::new(&data); assert_eq!(bits.read_i32_unchecked(), -22000i32);
fn read_u64_unchecked(&mut self) -> u64
fn read_u64_unchecked(&mut self) -> u64Consume 64 bits and return the deserialized long
use bitter::{BitReader, BigEndianReader}; let data = (22000u64).to_be_bytes(); let mut bits = BigEndianReader::new(&data); assert_eq!(bits.read_u64_unchecked(), 22000u64);
fn read_i64_unchecked(&mut self) -> i64
fn read_i64_unchecked(&mut self) -> i64Consume 64 bits and return the deserialized long
use bitter::{BitReader, BigEndianReader}; let data = (-22000i64).to_be_bytes(); let mut bits = BigEndianReader::new(&data); assert_eq!(bits.read_i64_unchecked(), -22000i64);
fn read_f32_unchecked(&mut self) -> f32
fn read_f32_unchecked(&mut self) -> f32Consume 32 bits and return the deserialized floating point
use bitter::{BitReader, BigEndianReader}; let data = 12.5f32.to_be_bytes(); let mut bits = BigEndianReader::new(&data); assert_eq!(bits.read_f32_unchecked(), 12.5f32);
fn read_f64_unchecked(&mut self) -> f64
fn read_f64_unchecked(&mut self) -> f64Consume 64 bits and return the deserialized double floating point
use bitter::{BitReader, BigEndianReader}; let data = 12.5f64.to_be_bytes(); let mut bits = BigEndianReader::new(&data); assert_eq!(bits.read_f64_unchecked(), 12.5f64);
fn read_bits_unchecked(&mut self, bits: i32) -> u64
fn read_bits_unchecked(&mut self, bits: i32) -> u64Reads an arbitrary number of bits from 1 to 64 (inclusive) and returns the unsigned result
use bitter::{BitReader, BigEndianReader}; let mut bitter = BigEndianReader::new(&[0xff, 0x00, 0xab, 0xcd]); assert_eq!(bitter.read_bits_unchecked(32), 0xff00abcd);
fn read_signed_bits_unchecked(&mut self, bits: i32) -> i64
fn read_signed_bits_unchecked(&mut self, bits: i32) -> i64Reads an arbitrary number of bits from 1 to 64 (inclusive) and returns the signed result. See the discussion for the checked version of this API.
use bitter::{BitReader, BigEndianReader}; let mut bitter = BigEndianReader::new(&[0xff, 0x00, 0xab, 0xcd]); let result = i64::from(i32::from_be_bytes([0xff, 0x00, 0xab, 0xcd])); assert_eq!(bitter.read_signed_bits_unchecked(32), result);
fn if_get_unchecked<T, F>(&mut self, f: F) -> Option<T> where
F: FnMut(&mut Self) -> T,
fn if_get_unchecked<T, F>(&mut self, f: F) -> Option<T> where
F: FnMut(&mut Self) -> T, If the next bit is available and on, decode the next chunk of data. The return value can be one of the following:
- Some(None): Bit was off so data not decoded
- Some(x): Bit was on and data was decoded
use bitter::{LittleEndianReader, BitReader}; let mut bitter = LittleEndianReader::new(&[0xff, 0x04]); assert_eq!(bitter.if_get_unchecked(LittleEndianReader::read_u8_unchecked), Some(0x7f)); assert_eq!(bitter.if_get_unchecked(LittleEndianReader::read_u8_unchecked), None);
fn read_bits_max_unchecked(&mut self, max: u64) -> u64
fn read_bits_max_unchecked(&mut self, max: u64) -> u64Reads a value from the stream that consumes the same or fewer number of bits of a given max. The value read will always be less than the given max.
For example if one wants to read a value that is less than 20, bitter will read at least
4 bits from the stream. If the 5th bit would cause the accumulator to exceed the max, the
5th bit is not consumed. Else the 5th bit is consumed and added to accumulator. If the
necessary number of bits are not available, None is returned.
use bitter::{LittleEndianReader, BitReader}; let mut bitter = LittleEndianReader::new(&[0b1111_1000]); assert_eq!(bitter.read_bits_max_unchecked(20), 8); assert_eq!(bitter.read_bits_max_unchecked(20), 15);
fn read_bits_max_computed_unchecked(&mut self, bits: i32, max: u64) -> u64
fn read_bits_max_computed_unchecked(&mut self, bits: i32, max: u64) -> u64Same as read_bits_max_unchecked except that this function accepts the already computed number of
bits to at least read. For instance, if 20 is the max, then 4 bits are at least needed.
In general, prefer read_bits_max_unchecked for ease of use, as passing an incorrectly
computed max can lead to undefined behavior
use bitter::{LittleEndianReader, BitReader}; let mut bitter = LittleEndianReader::new(&[0b1111_1000]); assert_eq!(bitter.read_bits_max_computed_unchecked(4, 20), 8); assert_eq!(bitter.read_bits_max_computed_unchecked(4, 20), 15);
fn approx_bytes_remaining(&self) -> usize
fn approx_bytes_remaining(&self) -> usizeReturn approximately how many bytes are left in the bitstream. This can overestimate by one when the reader is at a position that is not byte aligned. Thus it is recommended to always compare with a greater than sign to avoid undefined behavior with unchecked reads
let mut bitter = LittleEndianReader::new(&[0xff]); assert_eq!(bitter.approx_bytes_remaining(), 1); assert!(bitter.read_bit().is_some()); assert_eq!(bitter.approx_bytes_remaining(), 1); assert!(bitter.read_bits(7).is_some()); assert_eq!(bitter.approx_bytes_remaining(), 0);
fn bits_remaining(&self) -> Option<usize>
fn bits_remaining(&self) -> Option<usize>Returns the exact number of bits remaining in the bitstream if the number of bits can fit
within a usize. For large byte slices, the calculating the number of bits can cause an
overflow, hence an Option is returned. See has_bits_remaining for a more performant and
ergonomic alternative.
let mut bitter = LittleEndianReader::new(&[0xff]); assert_eq!(bitter.bits_remaining(), Some(8)); assert!(bitter.read_bit().is_some()); assert_eq!(bitter.bits_remaining(), Some(7)); assert!(bitter.read_bits(7).is_some()); assert_eq!(bitter.bits_remaining(), Some(0));
fn has_bits_remaining(&self, bits: usize) -> bool
fn has_bits_remaining(&self, bits: usize) -> boolReturns true if at least bits number of bits are left in the stream. A more performant
and ergonomic way than bits_remaining.
let mut bitter = LittleEndianReader::new(&[0xff]); assert!(bitter.has_bits_remaining(7)); assert!(bitter.has_bits_remaining(8)); assert!(!bitter.has_bits_remaining(9)); assert!(bitter.read_bit().is_some()); assert!(bitter.has_bits_remaining(7)); assert!(!bitter.has_bits_remaining(8)); assert!(bitter.read_bits(7).is_some()); assert!(!bitter.has_bits_remaining(7)); assert!(bitter.has_bits_remaining(0));
Read the number of bytes needed to fill the provided buffer. Returns whether the read was successful and the buffer has been filled.
let mut bitter = LittleEndianReader::new(&[0b1010_1010, 0b0101_0101]); let mut buf = [0; 1]; assert_eq!(bitter.read_bit_unchecked(), false); assert!(bitter.read_bytes(&mut buf)); assert_eq!(&buf, &[0b1101_0101]); assert!(!bitter.read_bytes(&mut buf));