1use std::io::{self, Write};
2
3const DEFAULT_BUFFER_SIZE: usize = 1023;
4
5pub struct Writer<W> {
8 buffer: Box<[u8]>,
9 size: usize, writer: W
11}
12
13impl<W> Writer<W> where W: Write {
14 pub fn new(writer: W) -> Self {
15 Self::with_capacity(DEFAULT_BUFFER_SIZE, writer)
16 }
17
18 pub fn with_capacity(capacity: usize, writer: W) -> Self {
19 Writer {
20 buffer: vec![0; capacity + 1].into_boxed_slice(),
21 size: 0,
22 writer
23 }
24 }
25
26 pub fn write_bit(&mut self, bit: bool) -> io::Result<()> {
27 let free_bits = self.buffer.len() * 8 - self.size;
28 if free_bits == 0 {
29 self.flush()?;
30 }
31
32 if bit {
33 let byte_index = self.size / 8;
34 let bit_index = 7 - self.size % 8;
35 self.buffer[byte_index] |= 1 << bit_index;
36 }
37
38 self.size += 1;
39 Ok(())
40 }
41
42 pub fn write_bits(&mut self, bits: u8, count: usize) -> io::Result<()> {
48 for i in 0..count {
49 let bit = bits & (1 << (7 - i)) != 0;
50 self.write_bit(bit)?
51 }
52
53 Ok(())
54 }
55
56 pub fn flush(&mut self) -> io::Result<()> {
59 let bytes = (self.size + 7) / 8;
60 self.writer.write_all(&self.buffer[..bytes])?;
61 self.reset(bytes);
62 Ok(())
63 }
64
65 fn reset(&mut self, bytes: usize) {
66 unsafe {
68 ::std::ptr::write_bytes(self.buffer.as_mut_ptr(), 0, bytes);
69 }
70 self.size = 0;
71 }
72
73 pub fn finish(mut self) -> io::Result<W> {
74 self.flush()?;
75 Ok(self.writer)
76 }
77}
78
79
80#[cfg(test)]
81mod tests {
82 use super::Writer;
83
84 #[test]
85 fn within_byte() {
86 let mut writer = Writer::new(Vec::new());
87 writer.write_bits(0b10100000, 4).unwrap();
88 writer.write_bits(0b01010000, 4).unwrap();
89 let buffer = writer.finish().unwrap();
90 assert_eq!(&buffer, &[0b10100101]);
91 }
92
93 #[test]
94 fn overlapping() {
95 let mut writer = Writer::new(Vec::new());
96 writer.write_bits(0b10101000, 6).unwrap();
97 writer.write_bits(0b10101000, 6).unwrap();
98 let buffer = writer.finish().unwrap();
99 assert_eq!(&buffer, &[0b10101010, 0b10100000]);
100 }
101
102 #[test]
103 fn buffer_overflow() {
104 let mut writer = Writer::with_capacity(0, Vec::new());
105 writer.write_bits(0b10101000, 6).unwrap();
106 writer.write_bits(0b10101000, 6).unwrap();
107 let buffer = writer.finish().unwrap();
108 assert_eq!(&buffer, &[0b10101010, 0b10100000]);
109 }
110}