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