osrscache/util/
huffman.rs

1/// Decompresses chat messages.
2/// 
3/// # Examples
4///
5/// ```
6/// # use osrscache::Cache;
7/// use osrscache::util::Huffman;
8///
9/// # fn main() -> Result<(), osrscache::Error> {
10/// # let cache = Cache::new("./data/osrs_cache")?;
11/// let huffman_tbl = cache.huffman_table()?;
12/// let huffman = Huffman::new(&huffman_tbl);
13///
14/// let compressed_msg = &[174, 128, 35, 32, 208, 96];
15/// let decompressed_len = 8; // client will include this in the chat packet.
16///
17/// let decompressed_msg = huffman.decompress(compressed_msg, decompressed_len);
18///
19/// if let Ok(msg) = String::from_utf8(decompressed_msg) {
20///     assert_eq!(msg, "rs-cache");
21/// }
22/// # Ok(())
23/// # }
24/// ```
25
26#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug, Default)]
27pub struct Huffman {
28    keys: Vec<i32>,
29}
30
31impl Huffman {
32    /// Initializes the Huffman struct with the given sizes.
33    ///
34    /// The sizes can be found in the cache.
35    /// Call the [`huffman_table()`](../struct.Cache.html#method.huffman_table) function to get the huffman table which
36    /// contains the sizes needed to initialize this struct.
37    pub fn new(sizes: &[u8]) -> Self {
38        let i_2 = sizes.len();
39        let mut masks: Vec<i32> = vec![0; i_2];
40        let mut ints_3: Vec<i32> = vec![0; 33];
41        let mut keys: Vec<i32> = vec![0; 8];
42        let mut i_4 = 0;
43
44        for i_5 in 0..i_2 {
45            let b_6 = sizes[i_5];
46            if b_6 != 0 {
47                let i_7 = 1 << (32 - b_6);
48                let i_8 = ints_3[b_6 as usize];
49                masks[i_5] = i_8;
50                let mut i_9 = 0;
51                let mut i_10 = 0;
52                let mut i_11 = 0;
53                let mut i_12_1 = 0;
54                if i_8 & i_7 != 0 {
55                    i_9 = ints_3[(b_6 - 1) as usize];
56                } else {
57                    i_9 = i_8 | i_7;
58
59                    i_10 = (b_6 - 1) as i32;
60                    while i_10 >= 1 {
61                        i_11 = ints_3[i_10 as usize];
62                        if i_11 != i_8 {
63                            break;
64                        }
65
66                        i_12_1 = 1 << (32 - i_10);
67                        if i_11 & i_12_1 != 0 {
68                            ints_3[i_10 as usize] = ints_3[(i_10 - 1) as usize];
69                            break;
70                        }
71
72                        ints_3[i_10 as usize] = i_11 | i_12_1;
73                        i_10 -= 1;
74                    }
75                }
76
77                ints_3[b_6 as usize] = i_9;
78
79                i_10 = (b_6 + 1) as i32;
80                while i_10 <= 32 {
81                    if ints_3[i_10 as usize] == i_8 {
82                        ints_3[i_10 as usize] = i_9;
83                    }
84                    i_10 += 1;
85                }
86
87                i_10 = 0;
88
89                i_11 = 0;
90                while i_11 < b_6 as i32 {
91                    i_12_1 = ((i32::min_value()) as u32 >> i_11) as i32;
92                    if i_8 & i_12_1 != 0 {
93                        if keys[i_10 as usize] == 0 {
94                            keys[i_10 as usize] = i_4;
95                        }
96
97                        i_10 = keys[i_10 as usize];
98                    } else {
99                        i_10 += 1;
100                    }
101
102                    if i_10 as usize >= keys.len() {
103                        let mut ints_13_vec = vec![0; keys.len() * 2];
104
105                        ints_13_vec[..keys.len()].clone_from_slice(&keys[..]);
106
107                        keys = ints_13_vec;
108                    }
109
110                    i_11 += 1;
111                }
112
113                keys[i_10 as usize] = (!i_5) as i32;
114                if i_10 >= i_4 {
115                    i_4 = i_10 + 1;
116                }
117            }
118        }
119
120        Self { keys }
121    }
122
123    /// Decompresses the given buffer.
124    ///
125    /// The buffer is normally an encoded chat message which will be decoded into
126    /// the original message. This helps limit chat packet sizes.
127    ///
128    /// # Panics
129    ///
130    /// Panics if the decompressed length == 0
131    pub fn decompress(&self, compressed: &[u8], decompressed_len: usize) -> Vec<u8> {
132        let mut decompressed = vec![0; decompressed_len];
133
134        let i_2 = 0;
135        let mut i_4 = 0;
136        if decompressed_len == 0 {
137            panic!("Huffman decompressed message length can't be 0.");
138        }
139        let mut i_7 = 0;
140        let mut i_8 = i_2;
141
142        loop {
143            if i_4 >= decompressed_len {
144                break;
145            }
146
147            let b_9 = compressed[i_8 as usize];
148            if b_9 > 127 {
149                i_7 = self.keys[i_7 as usize];
150            } else {
151                i_7 += 1;
152            }
153
154            let mut i_10 = 0;
155            i_10_keys(&mut i_10, &self.keys, &mut i_7, &mut i_4, &mut decompressed);
156
157            if b_9 & 0x40 != 0 {
158                i_7 = self.keys[i_7 as usize];
159            } else {
160                i_7 += 1;
161            }
162
163            i_10_keys(&mut i_10, &self.keys, &mut i_7, &mut i_4, &mut decompressed);
164
165            if b_9 & 0x20 != 0 {
166                i_7 = self.keys[i_7 as usize];
167            } else {
168                i_7 += 1;
169            }
170
171            i_10_keys(&mut i_10, &self.keys, &mut i_7, &mut i_4, &mut decompressed);
172
173            if b_9 & 0x10 != 0 {
174                i_7 = self.keys[i_7 as usize];
175            } else {
176                i_7 += 1;
177            }
178
179            i_10_keys(&mut i_10, &self.keys, &mut i_7, &mut i_4, &mut decompressed);
180
181            if b_9 & 0x8 != 0 {
182                i_7 = self.keys[i_7 as usize];
183            } else {
184                i_7 += 1;
185            }
186
187            i_10_keys(&mut i_10, &self.keys, &mut i_7, &mut i_4, &mut decompressed);
188
189            if b_9 & 0x4 != 0 {
190                i_7 = self.keys[i_7 as usize];
191            } else {
192                i_7 += 1;
193            }
194
195            i_10_keys(&mut i_10, &self.keys, &mut i_7, &mut i_4, &mut decompressed);
196
197            if b_9 & 0x2 != 0 {
198                i_7 = self.keys[i_7 as usize];
199            } else {
200                i_7 += 1;
201            }
202
203            i_10_keys(&mut i_10, &self.keys, &mut i_7, &mut i_4, &mut decompressed);
204
205            if b_9 & 0x1 != 0 {
206                i_7 = self.keys[i_7 as usize];
207            } else {
208                i_7 += 1;
209            }
210
211            i_10_keys(&mut i_10, &self.keys, &mut i_7, &mut i_4, &mut decompressed);
212
213            i_8 += 1;
214        }
215
216        decompressed
217    }
218}
219
220fn i_10_keys(
221    i_10: &mut i32,
222    keys: &[i32],
223    i_7: &mut i32,
224    i_4: &mut usize,
225    decompressed: &mut [u8],
226) {
227    *i_10 = keys[*i_7 as usize];
228    if *i_10 < 0 {
229        decompressed[*i_4] = (!*i_10) as u8;
230        *i_4 += 1;
231        *i_7 = 0;
232    }
233}