use std::boxed::Box;
use stream::Write;
use Bit;
#[derive(Debug, Default)]
pub struct BufferedWriter {
buf: Vec<u8>,
pos: u32, }
impl BufferedWriter {
pub fn new() -> Self {
BufferedWriter {
buf: Vec::new(),
pos: 8,
}
}
pub fn with_capacity(capacity: usize) -> Self {
BufferedWriter {
buf: Vec::with_capacity(capacity),
pos: 8,
}
}
fn grow(&mut self) {
self.buf.push(0);
}
fn last_index(&self) -> usize {
self.buf.len() - 1
}
}
impl Write for BufferedWriter {
fn write_bit(&mut self, bit: Bit) {
if self.pos == 8 {
self.grow();
self.pos = 0;
}
let i = self.last_index();
match bit {
Bit::Zero => (),
Bit::One => self.buf[i] |= 1u8.wrapping_shl(7 - self.pos),
};
self.pos += 1;
}
fn write_byte(&mut self, byte: u8) {
if self.pos == 8 {
self.grow();
let i = self.last_index();
self.buf[i] = byte;
return;
}
let i = self.last_index();
let mut b = byte.wrapping_shr(self.pos);
self.buf[i] |= b;
self.grow();
b = byte.wrapping_shl(8 - self.pos);
self.buf[i + 1] |= b;
}
fn write_bits(&mut self, mut bits: u64, mut num: u32) {
if num > 64 {
num = 64;
}
bits = bits.wrapping_shl(64 - num);
while num >= 8 {
let byte = bits.wrapping_shr(56);
self.write_byte(byte as u8);
bits = bits.wrapping_shl(8);
num -= 8;
}
while num > 0 {
let byte = bits.wrapping_shr(63);
if byte == 1 {
self.write_bit(Bit::One);
} else {
self.write_bit(Bit::Zero);
}
bits = bits.wrapping_shl(1);
num -= 1;
}
}
fn close(self) -> Box<[u8]> {
self.buf.into_boxed_slice()
}
}
#[cfg(test)]
mod tests {
use super::BufferedWriter;
use stream::Write;
use Bit;
#[test]
fn write_bit() {
let mut b = BufferedWriter::new();
for i in 0..8 {
if i % 2 == 0 {
b.write_bit(Bit::One);
continue;
}
b.write_bit(Bit::Zero);
}
for i in 0..8 {
if i % 3 == 0 {
b.write_bit(Bit::One);
continue;
}
b.write_bit(Bit::Zero);
}
for i in 0..8 {
if i % 4 == 0 {
b.write_bit(Bit::One);
continue;
}
b.write_bit(Bit::Zero);
}
assert_eq!(b.buf.len(), 3);
assert_eq!(b.buf[0], 170);
assert_eq!(b.buf[1], 146);
assert_eq!(b.buf[2], 136);
}
#[test]
fn write_byte() {
let mut b = BufferedWriter::new();
b.write_byte(234);
b.write_byte(188);
b.write_byte(77);
assert_eq!(b.buf.len(), 3);
assert_eq!(b.buf[0], 234);
assert_eq!(b.buf[1], 188);
assert_eq!(b.buf[2], 77);
b.write_bit(Bit::One);
b.write_bit(Bit::One);
b.write_bit(Bit::One);
b.write_bit(Bit::One);
b.write_byte(0b11110000); b.write_byte(0b00001111); b.write_byte(0b00001111);
assert_eq!(b.buf.len(), 7);
assert_eq!(b.buf[3], 255); assert_eq!(b.buf[4], 0); assert_eq!(b.buf[5], 240); }
#[test]
fn write_bits() {
let mut b = BufferedWriter::new();
b.write_bits(43, 6);
b.write_bits(2, 3);
b.write_bits(1, 1);
b.write_bits(708157, 20);
b.write_bits(3, 2);
assert_eq!(b.buf.len(), 4);
assert_eq!(b.buf[0], 173); assert_eq!(b.buf[1], 107); assert_eq!(b.buf[2], 56); assert_eq!(b.buf[3], 247); }
#[test]
fn write_mixed() {
let mut b = BufferedWriter::new();
for i in 0..8 {
if i % 2 == 0 {
b.write_bit(Bit::One);
continue;
}
b.write_bit(Bit::Zero);
}
b.write_byte(9);
b.write_bits(2508, 12);
println!("{:?}", b.buf);
for _ in 0..4 {
b.write_bit(Bit::One);
}
assert_eq!(b.buf.len(), 4);
println!("{:?}", b.buf);
assert_eq!(b.buf[0], 170); assert_eq!(b.buf[1], 9); assert_eq!(b.buf[2], 156); assert_eq!(b.buf[3], 207); }
}