read_fonts/collections/int_set/
output_bit_stream.rs1use super::sparse_bit_set::BranchFactor;
4use alloc::vec::Vec;
5
6pub(crate) struct OutputBitStream {
7 data: Vec<u8>,
8 sub_index: u32,
9 branch_factor: BranchFactor,
10}
11
12impl OutputBitStream {
13 pub(crate) const MAX_HEIGHT: u8 = 31;
14
15 pub(crate) fn new(branch_factor: BranchFactor, height: u8) -> OutputBitStream {
16 let mut out = OutputBitStream {
17 data: Vec::new(),
18 sub_index: 0,
19 branch_factor,
20 };
21 if height > Self::MAX_HEIGHT {
22 panic!("Height value exceeds maximum for the branch factor.");
23 }
24 out.write_header(height);
25 out
26 }
27
28 pub fn into_bytes(self) -> Vec<u8> {
29 self.data
30 }
31
32 pub fn write_node(&mut self, bits: u32) {
36 for byte_index in 0..self.branch_factor.bytes_per_node() {
37 if self.branch_factor.nodes_per_byte() == 1 || self.sub_index == 0 {
38 self.data.push(0);
39 }
40
41 let bits = (bits >> (byte_index * 8)) & self.branch_factor.byte_mask();
42 let bits = (bits << (self.sub_index * self.branch_factor.value())) as u8;
43 *self.data.last_mut().unwrap() |= bits;
44
45 if self.branch_factor.nodes_per_byte() > 1 {
46 self.sub_index = (self.sub_index + 1) % self.branch_factor.nodes_per_byte();
47 }
48 }
49 }
50
51 fn write_header(&mut self, height: u8) {
55 let byte = (height & 0b00011111) << 2;
56 let byte = byte | self.branch_factor.bit_id();
57 self.data.push(byte);
58 }
59}
60
61impl BranchFactor {
62 fn nodes_per_byte(&self) -> u32 {
63 match self {
64 BranchFactor::Two => 4,
65 BranchFactor::Four => 2,
66 BranchFactor::Eight => 1,
67 BranchFactor::ThirtyTwo => 1,
68 }
69 }
70
71 fn bytes_per_node(&self) -> u32 {
72 match self {
73 BranchFactor::Two => 1,
74 BranchFactor::Four => 1,
75 BranchFactor::Eight => 1,
76 BranchFactor::ThirtyTwo => 4,
77 }
78 }
79
80 fn bit_id(&self) -> u8 {
81 match self {
82 BranchFactor::Two => 0b00,
83 BranchFactor::Four => 0b01,
84 BranchFactor::Eight => 0b10,
85 BranchFactor::ThirtyTwo => 0b11,
86 }
87 }
88}
89
90#[cfg(test)]
91#[allow(clippy::unusual_byte_groupings)]
92mod test {
93 use super::*;
94
95 #[test]
96 fn init() {
97 let os = OutputBitStream::new(BranchFactor::Two, 13);
98 assert_eq!(os.into_bytes(), vec![0b0_01101_00]);
99
100 let os = OutputBitStream::new(BranchFactor::Four, 23);
101 assert_eq!(os.into_bytes(), vec![0b0_10111_01]);
102
103 let os = OutputBitStream::new(BranchFactor::Eight, 1);
104 assert_eq!(os.into_bytes(), vec![0b0_00001_10]);
105
106 let os = OutputBitStream::new(BranchFactor::ThirtyTwo, 31);
107 assert_eq!(os.into_bytes(), vec![0b0_11111_11]);
108 }
109
110 #[test]
111 fn bf2() {
112 let mut os = OutputBitStream::new(BranchFactor::Two, 13);
113
114 os.write_node(0b10);
115 os.write_node(0b00);
116 os.write_node(0b11);
117 os.write_node(0b01);
118
119 os.write_node(0b01);
120 os.write_node(0b11);
121
122 assert_eq!(
123 os.into_bytes(),
124 vec![0b0_01101_00, 0b01_11_00_10, 0b00_00_11_01,]
125 );
126 }
127
128 #[test]
129 fn bf4() {
130 let mut os = OutputBitStream::new(BranchFactor::Four, 23);
131
132 os.write_node(0b0010);
133 os.write_node(0b0111);
134
135 os.write_node(0b1101);
136
137 assert_eq!(
138 os.into_bytes(),
139 vec![0b0_10111_01, 0b0111_0010, 0b0000_1101,]
140 );
141 }
142
143 #[test]
144 fn bf8() {
145 let mut os = OutputBitStream::new(BranchFactor::Eight, 1);
146
147 os.write_node(0b01110010);
148 os.write_node(0b00001101);
149
150 assert_eq!(os.into_bytes(), vec![0b0_00001_10, 0b01110010, 0b00001101,]);
151 }
152
153 #[test]
154 fn bf32() {
155 let mut os = OutputBitStream::new(BranchFactor::ThirtyTwo, 31);
156
157 os.write_node(0b10000000_00000000_00001101_01110010);
158
159 assert_eq!(
160 os.into_bytes(),
161 vec![0b0_11111_11, 0b01110010, 0b00001101, 0b00000000, 0b10000000]
162 );
163 }
164
165 #[test]
166 fn truncating() {
167 let mut os = OutputBitStream::new(BranchFactor::Four, 23);
168
169 os.write_node(0b11110010);
170
171 assert_eq!(os.into_bytes(), vec![0b0_10111_01, 0b0000_0010]);
172 }
173}