1 | //! Buffer wrappers implementing default so we can allocate the buffers with `Box::default()` |
2 | //! to avoid stack copies. Box::new() doesn't at the moment, and using a vec means we would lose |
3 | //! static length info. |
4 | |
5 | use crate::deflate::core::{LZ_DICT_SIZE, MAX_MATCH_LEN}; |
6 | |
7 | /// Size of the buffer of lz77 encoded data. |
8 | pub const LZ_CODE_BUF_SIZE: usize = 64 * 1024; |
9 | /// Size of the output buffer. |
10 | pub const OUT_BUF_SIZE: usize = (LZ_CODE_BUF_SIZE * 13) / 10; |
11 | pub const LZ_DICT_FULL_SIZE: usize = LZ_DICT_SIZE + MAX_MATCH_LEN - 1 + 1; |
12 | |
13 | /// Size of hash values in the hash chains. |
14 | pub const LZ_HASH_BITS: i32 = 15; |
15 | /// How many bits to shift when updating the current hash value. |
16 | pub const LZ_HASH_SHIFT: i32 = (LZ_HASH_BITS + 2) / 3; |
17 | /// Size of the chained hash tables. |
18 | pub const LZ_HASH_SIZE: usize = 1 << LZ_HASH_BITS; |
19 | |
20 | #[inline ] |
21 | pub fn update_hash(current_hash: u16, byte: u8) -> u16 { |
22 | ((current_hash << LZ_HASH_SHIFT) ^ u16::from(byte)) & (LZ_HASH_SIZE as u16 - 1) |
23 | } |
24 | |
25 | pub struct HashBuffers { |
26 | pub dict: [u8; LZ_DICT_FULL_SIZE], |
27 | pub next: [u16; LZ_DICT_SIZE], |
28 | pub hash: [u16; LZ_DICT_SIZE], |
29 | } |
30 | |
31 | impl HashBuffers { |
32 | #[inline ] |
33 | pub fn reset(&mut self) { |
34 | *self = HashBuffers::default(); |
35 | } |
36 | } |
37 | |
38 | impl Default for HashBuffers { |
39 | fn default() -> HashBuffers { |
40 | HashBuffers { |
41 | dict: [0; LZ_DICT_FULL_SIZE], |
42 | next: [0; LZ_DICT_SIZE], |
43 | hash: [0; LZ_DICT_SIZE], |
44 | } |
45 | } |
46 | } |
47 | |
48 | pub struct LocalBuf { |
49 | pub b: [u8; OUT_BUF_SIZE], |
50 | } |
51 | |
52 | impl Default for LocalBuf { |
53 | fn default() -> LocalBuf { |
54 | LocalBuf { |
55 | b: [0; OUT_BUF_SIZE], |
56 | } |
57 | } |
58 | } |
59 | |