#[macro_use] extern crate log;
use std::io::{Error, ErrorKind, Read, Result};
pub struct BitReader<R> {
buf: i32,
src: R,
start: usize,
end: usize
}
impl<R: Read> BitReader<R> {
pub fn new(source: R) -> BitReader<R> {
BitReader {
buf: 0,
src: source,
start: 0,
end: 0
}
}
pub fn read_bit(&mut self) -> Result<bool> {
let bit = try!(self.read_bits(1));
Ok(bit > 0)
}
pub fn read_bits(&mut self, bit_count: usize) -> Result<i32> {
assert!(bit_count < 32);
self.expand_buffer(bit_count as isize);
let result = (self.buf >> self.start) & ((1 << bit_count) - 1);
self.start += bit_count;
if self.end == self.start {
self.end = 0;
self.start = self.end;
self.buf = 0;
}
else if self.start >= 8 {
self.buf >>= self.start;
self.end -= self.start;
self.start = 0;
}
Ok(result)
}
pub fn read_byte(&mut self) -> Result<u8> {
match self.read_bits(8) {
Ok(byte) => Ok(byte as u8),
_ => Err(Error::new(ErrorKind::Other, "Reached EOF"))
}
}
pub fn read_bytes(&mut self, buf: &mut [u8], byte_count: usize) -> Result<usize> {
assert!(byte_count <= buf.len());
let mut count = 0usize;
while count < byte_count {
match self.read_byte() {
Ok(byte) => buf[count] = byte,
_ => return Err(Error::new(ErrorKind::Other, "Reached EOF"))
}
count += 1;
}
Ok(count)
}
fn buf_len(&self) -> isize {
(self.end - self.start) as isize
}
fn expand_buffer(&mut self, b_count: isize) {
assert!(b_count > 0 && b_count < 32);
let mut bits_to_read: isize = b_count - self.buf_len();
let mut buf = [0u8; 1];
while bits_to_read > 0 {
match self.src.read(&mut buf) {
Ok(_) => {
self.buf |= (buf[0] as i32) << self.end;
self.end += 8;
bits_to_read -= 8;
debug!("Expanded buffer! {} bits remaining", bits_to_read)
}
_ => panic!("Error! Unexpected EOF!")
}
}
}
}
impl<R: Read> Read for BitReader<R> {
fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
let len = buf.len();
self.read_bytes(buf, len)
}
}
#[allow(dead_code)]
struct BitWriter<W> {
buf: u64,
targ: W,
start: u64,
end: u64
}