1use std::io::{self, Write};
7
8#[cfg(target_pointer_width = "64")]
9#[macro_use]
10mod arch_dep {
11 pub type AccType = u64;
16 pub const FLUSH_AT: u8 = 48;
17 macro_rules! push {
22 ($s:ident) => {
23 $s.w.extend_from_slice(
24 &[
25 $s.acc as u8,
26 ($s.acc >> 8) as u8,
27 ($s.acc >> 16) as u8,
28 ($s.acc >> 24) as u8,
29 ($s.acc >> 32) as u8,
30 ($s.acc >> 40) as u8,
31 ][..],
32 )
33 };
34 }
35}
36#[cfg(not(target_pointer_width = "64"))]
37#[macro_use]
38mod arch_dep {
39 pub type AccType = u32;
40 pub const FLUSH_AT: u8 = 16;
41 macro_rules! push {
42 ($s:ident) => {
43 $s.w.push($s.acc as u8);
46 $s.w.push(($s.acc >> 8) as u8);
47 };
48 }
49}
50
51use self::arch_dep::*;
52
53pub struct LsbWriter {
55 pub w: Vec<u8>,
57 bits: u8,
58 acc: AccType,
59}
60
61impl LsbWriter {
62 pub const fn new(writer: Vec<u8>) -> LsbWriter {
64 LsbWriter {
65 w: writer,
66 bits: 0,
67 acc: 0,
68 }
69 }
70
71 pub const fn pending_bits(&self) -> u8 {
72 self.bits
73 }
74
75 pub fn write_bits(&mut self, v: u16, n: u8) {
77 self.acc |= (AccType::from(v)) << self.bits;
79 self.bits += n;
80 while self.bits >= FLUSH_AT {
82 push!(self);
83 self.acc >>= FLUSH_AT;
84 self.bits -= FLUSH_AT;
85 }
86 }
87
88 fn write_bits_finish(&mut self, v: u16, n: u8) {
89 self.acc |= (AccType::from(v)) << self.bits;
91 self.bits += n % 8;
92 while self.bits >= 8 {
93 self.w.push(self.acc as u8);
94 self.acc >>= 8;
95 self.bits -= 8;
96 }
97 }
98
99 pub fn flush_raw(&mut self) {
100 let missing = FLUSH_AT - self.bits;
101 if missing > 0 && self.bits > 0 {
104 self.write_bits_finish(0, missing);
105 }
106 }
107}
108
109impl Write for LsbWriter {
110 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
111 if self.acc == 0 {
112 self.w.extend_from_slice(buf)
113 } else {
114 for &byte in buf.iter() {
115 self.write_bits(u16::from(byte), 8)
116 }
117 }
118 Ok(buf.len())
119 }
120
121 fn flush(&mut self) -> io::Result<()> {
122 self.flush_raw();
123 Ok(())
124 }
125}
126
127#[cfg(test)]
128mod test {
129 use super::LsbWriter;
130
131 #[test]
132 fn write_bits() {
133 let input = [
134 (3, 3),
135 (10, 8),
136 (88, 7),
137 (0, 2),
138 (0, 5),
139 (0, 0),
140 (238, 8),
141 (126, 8),
142 (161, 8),
143 (10, 8),
144 (238, 8),
145 (174, 8),
146 (126, 8),
147 (174, 8),
148 (65, 8),
149 (142, 8),
150 (62, 8),
151 (10, 8),
152 (1, 8),
153 (161, 8),
154 (78, 8),
155 (62, 8),
156 (158, 8),
157 (206, 8),
158 (10, 8),
159 (64, 7),
160 (0, 0),
161 (24, 5),
162 (0, 0),
163 (174, 8),
164 (126, 8),
165 (193, 8),
166 (174, 8),
167 ];
168 let expected = [
169 83, 192, 2, 220, 253, 66, 21, 220, 93, 253, 92, 131, 28, 125, 20, 2, 66, 157, 124, 60,
170 157, 21, 128, 216, 213, 47, 216, 21,
171 ];
172 let mut writer = LsbWriter::new(Vec::new());
173 for v in input.iter() {
174 writer.write_bits(v.0, v.1);
175 }
176 writer.flush_raw();
177 assert_eq!(writer.w, expected);
178 }
179}
180
181#[cfg(all(test, feature = "benchmarks"))]
182mod bench {
183 use super::LsbWriter;
184 use test_std::Bencher;
185 #[bench]
186 fn bit_writer(b: &mut Bencher) {
187 let input = [
188 (3, 3),
189 (10, 8),
190 (88, 7),
191 (0, 2),
192 (0, 5),
193 (0, 0),
194 (238, 8),
195 (126, 8),
196 (161, 8),
197 (10, 8),
198 (238, 8),
199 (174, 8),
200 (126, 8),
201 (174, 8),
202 (65, 8),
203 (142, 8),
204 (62, 8),
205 (10, 8),
206 (1, 8),
207 (161, 8),
208 (78, 8),
209 (62, 8),
210 (158, 8),
211 (206, 8),
212 (10, 8),
213 (64, 7),
214 (0, 0),
215 (24, 5),
216 (0, 0),
217 (174, 8),
218 (126, 8),
219 (193, 8),
220 (174, 8),
221 ];
222 let mut writer = LsbWriter::new(Vec::with_capacity(100));
223 b.iter(|| {
224 for v in input.iter() {
225 let _ = writer.write_bits(v.0, v.1);
226 }
227 });
228 }
229}