1use std::io::Write;
2
3use crate::enc::Encoding;
4use crate::{Error, ErrorKind};
5
6pub struct Writer<W: Write + ?Sized, E: Encoding> {
8 acc: u64,
9 len: u8,
10 enc: E,
11 dst: W,
12}
13
14impl<W: Write, E: Encoding> Writer<W, E> {
15 pub fn new(dst: W, enc: E) -> Self {
17 Self {
18 acc: 0,
19 len: 0,
20 enc,
21 dst,
22 }
23 }
24
25 pub fn write(&mut self, value: i64) -> Result<(), Error> {
27 let stage = self
28 .enc
29 .stage_by_value(value)
30 .ok_or_else(|| Error::new(ErrorKind::InvalidInput))?;
31 let prefix = stage.prefix() as u64;
32 let value = (value - stage.ordinal_min()) as u64;
33
34 let buf = match stage.bits() < 64 {
35 true => ((prefix << stage.ordinal_bits()) | value) << (64 - stage.bits()),
36 false => (prefix << (64 - stage.prefix_bits())) | (value >> (stage.bits() - 64)),
37 };
38
39 let len = self.len & 127;
40 self.acc |= buf >> len;
41
42 let len = len + stage.bits();
43 self.len = 128
44 | if len < 64 {
45 len
46 } else {
47 let left = len - 64;
48
49 self.len = 0;
50 self.dst.write_all(&self.acc.to_be_bytes())?;
51 self.acc = if stage.bits() <= 64 {
52 buf << (stage.bits() - left)
53 } else {
54 value << (stage.bits() - left)
55 };
56
57 left
58 };
59
60 Ok(())
61 }
62}
63
64impl<W: Write + ?Sized, E: Encoding> Drop for Writer<W, E> {
65 fn drop(&mut self) {
66 if self.len > 0 {
67 let len = (self.len as usize & 127).div_ceil(8);
68 let acc = &self.acc.to_be_bytes()[..len];
69
70 _ = self.dst.write_all(acc);
71 }
72 }
73}