use std::io::{self, Read};
const DEFAULT_BUFFER_SIZE: usize = 1023;
pub struct Reader<R> {
buffer: Box<[u8]>,
position: usize, size: usize, reader: R
}
impl<R> Reader<R> where R: Read {
pub fn new(reader: R) -> Self {
Self::with_capacity(DEFAULT_BUFFER_SIZE, reader)
}
pub fn with_capacity(capacity: usize, reader: R) -> Self {
Reader {
buffer: vec![0; capacity + 1].into_boxed_slice(),
position: 0,
size: 0,
reader
}
}
pub fn read_bit(&mut self) -> io::Result<bool> {
if self.size == self.position {
self.fill_buffer()?;
}
let byte_index = self.position / 8;
let bit_index = 7 - self.position % 8;
let bit = self.buffer[byte_index] & (1 << bit_index) != 0;
println!("Reading at {} -> {}", self.position, bit);
self.position += 1;
Ok(bit)
}
pub fn read_bits(&mut self, bits: &mut u8, count: usize) -> io::Result<()> {
for i in 0..count {
let bit = self.read_bit()?;
if bit {
*bits |= 1 << (7 - i);
}
}
Ok(())
}
fn fill_buffer(&mut self) -> io::Result<()> {
let n = self.reader.read(&mut self.buffer)?;
println!("Refill: {}", n);
if n == 0 {
return Err(io::Error::new(io::ErrorKind::UnexpectedEof, "Unexpected EOF"));
}
self.size = n * 8;
self.position = 0;
Ok(())
}
}
#[cfg(test)]
mod tests {
use std::io::Cursor;
use super::*;
#[test]
fn within_byte() {
let buffer = vec![0b10100101];
let cursor = Cursor::new(buffer);
let mut reader = Reader::new(cursor);
let mut bits = 0u8;
reader.read_bits(&mut bits, 4).unwrap();
assert_eq!(bits, 0b10100000);
bits = 0;
reader.read_bits(&mut bits, 4).unwrap();
assert_eq!(bits, 0b01010000);
let e = reader.read_bit();
assert!(e.is_err());
assert_eq!(e.unwrap_err().kind(), io::ErrorKind::UnexpectedEof);
}
#[test]
fn overlapping() {
let buffer = vec![0b10101010, 0b10100000];
let cursor = Cursor::new(buffer);
let mut reader = Reader::new(cursor);
let mut bits = 0u8;
reader.read_bits(&mut bits, 6).unwrap();
assert_eq!(bits, 0b10101000);
bits = 0;
reader.read_bits(&mut bits, 6).unwrap();
assert_eq!(bits, 0b10101000);
bits = 0;
reader.read_bits(&mut bits, 4).unwrap();
assert_eq!(bits, 0);
let e = reader.read_bit();
assert!(e.is_err());
assert_eq!(e.unwrap_err().kind(), io::ErrorKind::UnexpectedEof);
}
#[test]
fn buffer_overflow() {
let buffer = vec![0b10101010, 0b10100000];
let cursor = Cursor::new(buffer);
let mut reader = Reader::with_capacity(0, cursor);
let mut bits = 0u8;
reader.read_bits(&mut bits, 6).unwrap();
assert_eq!(bits, 0b10101000);
bits = 0;
reader.read_bits(&mut bits, 6).unwrap();
assert_eq!(bits, 0b10101000);
bits = 0;
reader.read_bits(&mut bits, 4).unwrap();
assert_eq!(bits, 0);
let e = reader.read_bit();
assert!(e.is_err());
assert_eq!(e.unwrap_err().kind(), io::ErrorKind::UnexpectedEof);
}
}