use std::iter::Map;
use std::slice::Iter;
pub struct RevBitReader<I> {
bytes: I,
byte: Option<u8>,
bit_idx: u8,
}
impl<I> RevBitReader<I> {
pub fn from_iter(bytes: I) -> Self {
RevBitReader {
bytes,
byte: None,
bit_idx: 7,
}
}
}
#[derive(Debug, PartialEq)]
pub struct NoError;
type MapFn = fn(&u8) -> Result<u8, NoError>;
type WrappedIter<'a> = Map<Iter<'a, u8>, MapFn>;
impl<'a> RevBitReader<WrappedIter<'a>> {
pub fn from_bytes(bytes: &'a [u8]) -> Self {
let bytes = bytes.iter().map((|b| Ok(*b)) as MapFn);
RevBitReader {
bytes,
byte: None,
bit_idx: 7,
}
}
}
impl<I, E> RevBitReader<I>
where
I: Iterator<Item = Result<u8, E>>,
{
pub fn take(&mut self, n: u8) -> Option<Result<u64, E>> {
let mut res = 0u64;
if self.byte.is_none() {
nested_try!(self.next()?);
}
let mut i = 0;
while i < n && self.byte.is_some() {
let mask = 1u64 << self.bit_idx;
let masked = (self.byte? as u64) & mask;
let bit = (masked >> self.bit_idx) << i;
res |= bit;
i += 1;
if self.bit_idx == 0 {
self.bit_idx = 7;
if let Some(Err(e)) = self.next() {
return Some(Err(e));
}
} else {
self.bit_idx -= 1;
}
}
Some(Ok(res))
}
fn next(&mut self) -> Option<Result<u8, E>> {
self.byte = None;
let byte = nested_try!(self.bytes.next()?);
self.byte = Some(byte);
Some(Ok(byte))
}
}
#[cfg(test)]
mod test {
use super::RevBitReader;
#[test]
fn empty() {
let data = b"";
let mut reader = RevBitReader::from_bytes(data);
assert_eq!(reader.take(1), None);
}
#[test]
fn single_byte() {
let data = &[0x88];
let mut reader = RevBitReader::from_bytes(data);
assert_eq!(reader.take(5), Some(Ok(0x11)));
assert_eq!(reader.take(5), Some(Ok(0x00)));
assert_eq!(reader.take(5), None);
}
#[test]
fn multiple_bytes() {
let data = &[0x7E, 0x87];
let mut reader = RevBitReader::from_bytes(data);
assert_eq!(reader.take(6), Some(Ok(0x03E)));
assert_eq!(reader.take(9), Some(Ok(0x185)));
assert_eq!(reader.take(5), Some(Ok(0x001)));
assert_eq!(reader.take(2), None);
}
#[test]
fn invalid() {
#[derive(Debug, PartialEq)]
struct Error;
struct InvalidIterator;
impl Iterator for InvalidIterator {
type Item = Result<u8, Error>;
fn next(&mut self) -> Option<Self::Item> {
Some(Err(Error))
}
}
let iterator = InvalidIterator;
let mut reader = RevBitReader::from_iter(iterator);
assert_eq!(reader.take(1), Some(Err(Error)));
}
}