#![deny(missing_docs)]
pub mod prelude;
pub mod conversions;
use std::error;
use std::result;
use std::fmt;
use std::io;
use std::mem;
use conversions::*;
#[derive(Debug)]
pub enum Error {
BufferEmpty,
BufferFull,
BufferClosed,
ConversionFailed,
}
impl fmt::Display for Error {
fn fmt(&self, formatter: &mut fmt::Formatter) -> result::Result<(), fmt::Error> {
write!(formatter, "{}", (self as &error::Error).description())
}
}
impl error::Error for Error {
fn description(&self) -> &'static str {
match *self {
Error::BufferEmpty => "buffer empty",
Error::BufferFull => "buffer full",
Error::BufferClosed => "buffer closed",
Error::ConversionFailed => "conversion failed",
}
}
}
pub type Result<T> = result::Result<T, Error>;
#[derive(Debug)]
pub enum Precision {
Byte,
Bit,
}
#[derive(Debug, Clone)]
pub struct BitBuffer {
buffer: u64,
bits: u8,
}
impl BitBuffer {
pub fn new() -> BitBuffer {
BitBuffer {
buffer: 0,
bits: 0,
}
}
pub fn push_right(&mut self, value: u8) -> Result<()> {
if self.bits > 56 {
return Err(Error::BufferFull);
}
self.buffer = self.buffer << 8 | value as u64;
self.bits += 8;
Ok(())
}
pub fn pop_right(&mut self) -> Result<u8> {
if self.bits < 8 {
return Err(Error::BufferEmpty);
}
let value = (self.buffer & 0xff) as u8;
self.buffer >>= 8;
self.bits -= 8;
Ok(value)
}
pub fn push_left(&mut self, value: u8) -> Result<()> {
if self.bits > 56 {
return Err(Error::BufferFull);
}
self.buffer |= (value as u64) << self.bits;
self.bits += 8;
Ok(())
}
pub fn pop_left(&mut self) -> Result<u8> {
if self.bits < 8 {
return Err(Error::BufferEmpty);
}
let value = (self.buffer >> self.bits-8 & 0xff) as u8;
self.buffer &= !((0xff as u64) << self.bits-8);
self.bits -= 8;
Ok(value)
}
pub fn push_bit_right(&mut self, value: bool) -> Result<()> {
if self.bits > 63 {
return Err(Error::BufferFull);
}
if value {
self.buffer = self.buffer << 1 | 1;
} else {
self.buffer <<= 1;
}
self.bits += 1;
Ok(())
}
pub fn pop_bit_right(&mut self) -> Result<bool> {
if self.bits < 1 {
return Err(Error::BufferEmpty);
}
let value = self.buffer & 1 == 1;
self.buffer >>= 1;
self.bits -= 1;
Ok(value)
}
pub fn push_bit_left(&mut self, value: bool) -> Result<()> {
if self.bits > 63 {
return Err(Error::BufferFull);
}
if value {
self.buffer |= 1 << self.bits;
}
self.bits += 1;
Ok(())
}
pub fn pop_bit_left(&mut self) -> Result<bool> {
if self.bits < 1 {
return Err(Error::BufferEmpty);
}
let value = self.buffer >> self.bits-1 & 1 == 1;
self.buffer &= !(1 << self.bits-1);
self.bits -= 1;
Ok(value)
}
pub fn bits(&self) -> u8 {
self.bits
}
pub fn bytes(&self) -> u8 {
self.bits/8
}
pub fn is_empty(&self) -> bool {
self.bits == 0
}
pub fn has_byte(&self) -> bool {
self.bits >= 8
}
pub fn has_bit(&self) -> bool {
self.bits >= 1
}
pub fn can_take_byte(&self) -> bool {
self.bits <= 56
}
pub fn can_take_bit(&self) -> bool {
self.bits <= 63
}
pub fn byte_space(&self) -> u8 {
(64-self.bits) / 8
}
pub fn bit_space(&self) -> u8 {
64-self.bits
}
}
impl fmt::Display for BitBuffer {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
if self.bits == 0 {
write!(f, "[]")
} else {
let mut buf_str = format!("{:b}", self.buffer);
while (buf_str.len() as u8) < self.bits {
buf_str.insert(0, '0');
}
write!(f, "[{}]", buf_str)
}
}
}
pub struct BitReader<T: io::Read> {
input: T,
buffer: BitBuffer,
precision: Precision,
closed: bool,
}
impl<T: io::Read> BitReader<T> {
pub fn new(reader: T) -> BitReader<T> {
BitReader::new_with_precision(reader, Precision::Byte)
}
pub fn new_with_precision(reader: T, precision: Precision) -> BitReader<T> {
BitReader {
input: reader,
buffer: BitBuffer::new(),
precision,
closed: false,
}
}
pub fn read<V: BitReadable>(&mut self) -> Result<V> {
V::read_from(self)
}
pub fn read_using<V, C>(&mut self, converter: &C) -> Result<V> where C: BitRead<V> {
converter.read_value_from(self)
}
pub fn read_bit(&mut self) -> Result<bool> {
self.update();
Ok(self.buffer.pop_bit_left()?)
}
pub fn read_bits(&mut self, buffer: &mut [bool]) -> Result<usize> {
let mut read: usize = 0;
for i in buffer.iter_mut() {
self.update();
match self.buffer.pop_bit_left() {
Ok(bit) => {
*i = bit;
read += 1;
},
Err(_) if read > 0 => return Ok(read),
Err(error) => return Err(error),
}
}
Ok(read)
}
pub fn read_byte(&mut self) -> Result<u8> {
self.update();
Ok(self.buffer.pop_left()?)
}
pub fn read_bytes(&mut self, buffer: &mut [u8]) -> Result<usize> {
let mut read: usize = 0;
for i in buffer.iter_mut() {
self.update();
match self.buffer.pop_left() {
Ok(byte) => {
*i = byte;
read += 1;
},
Err(_) if read > 0 => return Ok(read),
Err(error) => return Err(error),
}
}
Ok(read)
}
fn update(&mut self) {
if !self.closed && self.buffer.can_take_byte() {
let mut buf: Vec<u8> = Vec::new();
for _ in 0..self.buffer.byte_space() {
buf.push(0);
}
if let Ok(n) = self.input.read(&mut buf) {
if n > 0 {
for i in 0..n {
self.buffer.push_right(buf[i]).unwrap();
}
return;
}
}
self.close();
}
}
fn close(&mut self) {
self.closed = true;
if let Precision::Bit = self.precision {
loop {
if self.buffer.pop_bit_right().unwrap_or(true) {
break;
}
}
self.precision = Precision::Byte;
}
}
}
pub struct BitWriter<T: io::Write> {
output: Option<T>,
buffer: BitBuffer,
precision: Precision,
}
impl<T: io::Write> BitWriter<T> {
pub fn new(writer: T) -> BitWriter<T> {
BitWriter::new_with_precision(writer, Precision::Byte)
}
pub fn new_with_precision(writer: T, precision: Precision) -> BitWriter<T> {
BitWriter {
output: Some(writer),
buffer: BitBuffer::new(),
precision,
}
}
pub fn write<V: BitWritable>(&mut self, value: V) -> Result<()> {
value.write_to(self)
}
pub fn write_using<V, C>(&mut self, value: V, converter: &C) -> Result<()> where C: BitWrite<V> {
converter.write_value_to(value, self)
}
pub fn write_bit(&mut self, bit: bool) -> Result<()> {
self.buffer.push_bit_right(bit)?;
self.flush().and(Ok(()))
}
pub fn write_bits(&mut self, bits: &[bool]) -> Result<usize> {
let mut written = 0;
for bit in bits.iter() {
match self.write_bit(*bit) {
Ok(_) => {
written += 1;
},
Err(_) if written > 0 => return Ok(written),
Err(error) => return Err(error),
}
}
Ok(written)
}
pub fn write_byte(&mut self, byte: u8) -> Result<()> {
self.buffer.push_right(byte)?;
self.flush().and(Ok(()))
}
pub fn write_bytes(&mut self, bytes: &[u8]) -> Result<usize> {
let mut written = 0;
for byte in bytes.iter() {
match self.write_byte(*byte) {
Ok(_) => {
written += 1;
},
Err(_) if written > 0 => return Ok(written),
Err(error) => return Err(error),
}
}
Ok(written)
}
pub fn flush(&mut self) -> Result<usize> {
if self.output.is_some() {
let mut buf: Vec<u8> = Vec::new();
while let Ok(byte) = self.buffer.pop_left() {
buf.push(byte);
}
match self.output.as_mut().unwrap().write(&buf) {
Ok(n) if n == buf.len() => Ok(self.buffer.bits as usize),
_ => {
self.output = None;
Err(Error::BufferClosed)
},
}
} else {
Err(Error::BufferClosed)
}
}
fn close_mut(&mut self) -> Result<()> {
if self.output.is_some() {
if let Precision::Bit = self.precision {
self.buffer.push_bit_right(true)?;
self.precision = Precision::Byte;
}
while self.buffer.bits() & 7 != 0 {
self.buffer.push_bit_right(false)?;
}
self.flush().and(Ok(()))
} else {
Err(Error::BufferClosed)
}
}
pub fn into_inner(mut self) -> Result<T> {
if let Err(e) = self.close_mut() {
return Err(e);
}
match mem::replace(&mut self.output, None) {
Some(v) => Ok(v),
None => Err(Error::BufferClosed),
}
}
pub fn close(mut self) -> Result<()> {
self.close_mut()?;
self.output = None;
Ok(())
}
}
impl<T: io::Write> Drop for BitWriter<T> {
#[allow(unused_must_use)]
fn drop(&mut self) {
self.close_mut();
}
}
pub trait BitReadable: Sized {
fn read_from<R: io::Read>(reader: &mut BitReader<R>) -> Result<Self>;
}
impl BitReadable for bool {
fn read_from<R: io::Read>(reader: &mut BitReader<R>) -> Result<Self> {
reader.read_bit()
}
}
impl BitReadable for u8 {
fn read_from<R: io::Read>(reader: &mut BitReader<R>) -> Result<Self> {
reader.read_byte()
}
}
pub trait BitWritable: Sized {
fn write_to<W: io::Write>(self, writer: &mut BitWriter<W>) -> Result<()>;
}
impl BitWritable for bool {
fn write_to<W: io::Write>(self, writer: &mut BitWriter<W>) -> Result<()> {
writer.write_bit(self)
}
}
impl BitWritable for u8 {
fn write_to<W: io::Write>(self, writer: &mut BitWriter<W>) -> Result<()> {
writer.write_byte(self)
}
}
impl<'a> BitWritable for &'a bool {
fn write_to<W: io::Write>(self, writer: &mut BitWriter<W>) -> Result<()> {
writer.write_bit(*self)
}
}
impl<'a> BitWritable for &'a u8 {
fn write_to<W: io::Write>(self, writer: &mut BitWriter<W>) -> Result<()> {
writer.write_byte(*self)
}
}