naia_serde/
file_bit_writer.rs1use crate::BitWrite;
2
3pub struct FileBitWriter {
6 scratch: u32,
7 scratch_bits: u32,
8 buffer: Vec<u8>,
9}
10
11impl FileBitWriter {
12 #[allow(clippy::new_without_default)]
13 pub fn new() -> Self {
14 Self {
15 scratch: 0,
16 scratch_bits: 0,
17 buffer: Vec::new(),
18 }
19 }
20
21 fn flush_word(&mut self) {
22 self.buffer.extend_from_slice(&self.scratch.to_le_bytes());
23 self.scratch = 0;
24 self.scratch_bits = 0;
25 }
26
27 fn finalize(&mut self) {
28 if self.scratch_bits > 0 {
29 let remaining_bytes = (self.scratch_bits as usize).div_ceil(8);
30 let word = self.scratch.to_le_bytes();
31 self.buffer.extend_from_slice(&word[..remaining_bytes]);
32 }
33 }
34
35 pub fn to_bytes(mut self) -> Box<[u8]> {
36 self.finalize();
37 Box::from(self.buffer)
38 }
39
40 pub fn to_vec(mut self) -> Vec<u8> {
41 self.finalize();
42 self.buffer
43 }
44}
45
46impl BitWrite for FileBitWriter {
47 #[inline(always)]
48 fn write_bit(&mut self, bit: bool) {
49 self.scratch |= (bit as u32) << self.scratch_bits;
50 self.scratch_bits += 1;
51 if self.scratch_bits == 32 {
52 self.flush_word();
53 }
54 }
55
56 #[inline(always)]
57 fn write_byte(&mut self, byte: u8) {
58 let available = 32 - self.scratch_bits;
59 if available >= 8 {
60 self.scratch |= (byte as u32) << self.scratch_bits;
61 self.scratch_bits += 8;
62 if self.scratch_bits == 32 {
63 self.flush_word();
64 }
65 } else {
66 let lo = (byte as u32) & ((1 << available) - 1);
67 self.scratch |= lo << self.scratch_bits;
68 self.flush_word();
69 self.scratch = (byte as u32) >> available;
70 self.scratch_bits = 8 - available;
71 }
72 }
73
74 fn count_bits(&mut self, _: u32) {
75 panic!("This method should not be called for FileBitWriter!");
76 }
77
78 fn is_counter(&self) -> bool {
79 panic!("This method should not be called for FileBitWriter!");
80 }
81}