bpack/unpack/table.rs
1use std::collections::HashMap;
2
3pub struct Table {
4 // the length of the smallest code
5 smallest: u8,
6
7 // table itself
8 map: HashMap<u16, (u8, u8)>,
9
10 masks: Vec<u8>,
11
12 need_to_read: u8,
13
14 rest: u16,
15 bits_occupies: u8,
16}
17
18impl Table {
19 pub fn new() -> Self {
20 let masks = vec![
21 0b0000_0000, // placeholder
22 0b1000_0000, // 1
23 0b1100_0000, // 2
24 0b1110_0000, // 3
25 0b1111_0000, // 4
26 0b1111_1000, // 5
27 0b1111_1100, // 6
28 0b1111_1110, // 7
29 0b1111_1111, // 8
30 ];
31
32 // let rev_masks = vec![
33 // 0b1111_1111,
34 // 0b0111_1111,
35 // 0b0011_1111,
36 // 0b0001_1111,
37 // 0b0000_1111,
38 // 0b0000_0111,
39 // 0b0000_0011,
40 // 0b0000_0001,
41 // ];
42
43 Table {
44 smallest: u8::MAX,
45 map: HashMap::with_capacity(95),
46 masks,
47 need_to_read: u8::MAX,
48 rest: 0u16,
49 bits_occupies: 0,
50 }
51 }
52
53 pub fn set(&mut self, code: u8, bits: u16, counter: i8) {
54 if (counter as u8) < self.smallest {
55 self.smallest = counter as u8;
56 self.need_to_read = self.smallest;
57 }
58
59 // println!("bits -> {:b}, code -> {}", bits, code);
60 // assert_eq!(self.map.contains_key(&bits), false);
61 self.map.insert(bits, (code + 32, counter as u8));
62 }
63
64
65 pub fn handle(&mut self, byte: u8, v: &mut Vec<u8>, v_idx: &mut usize, o_size: usize) {
66 if *v_idx < o_size {
67 if self.bits_occupies == 0 {
68 for i in self.smallest..9 {
69 let c = ((byte & self.masks[i as usize]) as u16) << 8;
70 if let Some((code, length)) = self.map.get(&c) {
71 // verify length of the bits of the code
72 // with bits we took from current byte
73 if i != *length {
74 continue;
75 }
76 // println!("code found -> {}", code);
77 if *v_idx < o_size {
78 v[*v_idx] = *code;
79 *v_idx += 1;
80 }
81
82 // at this point we know that rest is empty
83 // we need to take rest of the bits
84 // and make them first bits of the rest
85 let bits_left = 8 - i;
86 if bits_left >= self.smallest {
87 panic!("bits_left >= self.smallest");
88 }
89 if bits_left == 0 {
90 // nothing is left
91 self.bits_occupies = 0;
92 self.rest = 0u16;
93 } else {
94 // somethin is left
95 // so take rest bits and make them first bits
96 // of the rest
97 // assert!(bits_left > 0);
98 self.rest = (((byte & (0xff >> i)) << i) as u16) << 8;
99 self.bits_occupies = bits_left;
100 self.need_to_read = self.smallest - bits_left;
101 }
102 return;
103 }
104 }
105 // at this point we have not found anything
106 // so bits_occupies is 0
107 // means that rest is empty
108 // take all bits of the byte
109 // and make them rest
110 self.rest = (byte as u16) << 8;
111 self.bits_occupies = 8;
112 self.need_to_read = 1;
113 println!("0 bits occupied and we got here");
114 } else {
115 // we have somthing in the rest in this case
116 for i in self.need_to_read..9 {
117 // we have something in the rest and it
118 // occupies some bits
119 // say 0b(000) 0_0000_0000_0000 it takes 3 bits
120 let mut c = ((byte & self.masks[i as usize]) as u16) << 8;
121 c >>= self.bits_occupies;
122 c |= self.rest;
123 if let Some((code, length)) = self.map.get(&c) {
124 // verify length
125 // we had 3 bits and we also took some bits
126 // from current byte
127 // so 3 + some bits should be the same length
128 // as a key we are looking for
129 if (self.bits_occupies + i) != *length {
130 continue;
131 }
132 // println!("code found -> {}", code);
133 if *v_idx < o_size {
134 v[*v_idx] = *code;
135 *v_idx += 1;
136 }
137 // at this point we found a code
138 // how many bits left?
139 let bits_left = 8 - i;
140 if bits_left >= self.smallest {
141 // panic!("bits_left >= self.smallest");
142 // we got to the point when more bits left
143 // then the smallest possible
144 // if we found a key at idx = 1
145 // so bits left = 7
146 // 0b(0) 000_0000
147 // if we found a key at idx = 2
148 // bits left = 6
149 // 0b(00) 00_0000
150 // 0b0000_00 (00) <- we don't need them
151 // 0b0000_000 (0) <- this also garbage
152 // updated byte, without bits we already took
153 let b = (byte & (0xff >> i)) << i;
154 for j in self.smallest..bits_left + 1 {
155 let c = ((b & self.masks[j as usize]) as u16) << 8;
156 if let Some((code, length)) = self.map.get(&c) {
157 if j != *length {
158 continue;
159 }
160 // println!("code found -> {}", code);
161 if *v_idx < o_size {
162 v[*v_idx] = *code;
163 *v_idx += 1;
164 }
165 let b_l = bits_left - j;
166 if b_l >= self.smallest {
167 panic!("bits_left >= self.smallest");
168 }
169 if b_l == 0 {
170 // nothing is left
171 self.bits_occupies = 0;
172 self.rest = 0u16;
173 self.need_to_read = self.smallest;
174 } else {
175 // somthin is left
176 // if previously we found at i=1
177 // 0b(0) 000_0000
178 // 7 bits left
179 // we shifted them
180 // so we added a 0 to the end
181 // 0b(0000_000) 0
182 self.rest = (((b & (0xff >> j)) << j) as u16) << 8;
183 self.bits_occupies = b_l;
184 self.need_to_read = self.smallest - b_l;
185 }
186 return;
187 }
188 }
189 // at this point we have not found anything
190 // need to set everything
191 self.rest = (b as u16) << 8;
192 self.bits_occupies = bits_left;
193 self.need_to_read = 1;
194 return;
195 }
196 if bits_left == 0 {
197 // nothing is left
198 self.bits_occupies = 0;
199 self.rest = 0u16;
200 self.need_to_read = self.smallest;
201 } else {
202 // assert!(bits_left > 0);
203 self.rest = (((byte & (0xff >> i)) << i) as u16) << 8;
204 self.bits_occupies = bits_left;
205 self.need_to_read = self.smallest - bits_left;
206 }
207 return;
208 }
209 }
210 // at this point we have not found anything
211 // so bits_occupies is not 0
212 // means that rest is not empty
213 // take all bits and add them to the rest
214 // update bits_occupies += 8
215
216 self.rest |= ((byte as u16) << 8) >> self.bits_occupies;
217 self.bits_occupies += 8;
218 self.need_to_read = 1;
219 }
220 }
221 }
222
223}