/rust/registry/src/index.crates.io-6f17d22bba15001f/zune-inflate-0.2.54/src/utils.rs
Line | Count | Source (jump to first uncovered line) |
1 | | use core::cell::Cell; |
2 | | |
3 | | /// make_decode_table_entry() creates a decode table entry for the given symbol |
4 | | /// by combining the static part 'decode_results[sym]' with the dynamic part |
5 | | /// 'len', which is the remaining codeword length (the codeword length for main |
6 | | /// table entries, or the codeword length minus TABLEBITS for subtable entries). |
7 | | /// |
8 | | /// In all cases, we add 'len' to each of the two low-order bytes to create the |
9 | | /// appropriately-formatted decode table entry. See the definitions of the |
10 | | /// *_decode_results[] arrays below, where the entry format is described. |
11 | 0 | pub(crate) fn make_decode_table_entry(decode_results: &[u32], sym: usize, len: u32) -> u32 |
12 | 0 | { |
13 | 0 | decode_results[sym] + (len << 8) + len |
14 | 0 | } |
15 | | |
16 | | /// A safe version of src.copy_within that helps me because I tend to always |
17 | | /// confuse the arguments |
18 | 0 | pub fn fixed_copy_within<const SIZE: usize>(dest: &mut [u8], src_offset: usize, dest_offset: usize) |
19 | 0 | { |
20 | 0 | // for debug builds ensure we don't go out of bounds |
21 | 0 | debug_assert!( |
22 | 0 | dest_offset + SIZE <= dest.len(), |
23 | 0 | "[dst]: End position {} out of range for slice of length {}", |
24 | 0 | dest_offset + SIZE, |
25 | 0 | dest.len() |
26 | | ); |
27 | | |
28 | 0 | dest.copy_within(src_offset..src_offset + SIZE, dest_offset); |
29 | 0 | } |
30 | | |
31 | | #[inline(always)] |
32 | 0 | pub fn copy_rep_matches(dest: &mut [u8], offset: usize, dest_offset: usize, length: usize) |
33 | 0 | { |
34 | 0 | // This is a slightly complicated rep match copier that has |
35 | 0 | // no bounds check. |
36 | 0 |
|
37 | 0 | // The only invariant we need to uphold is dest[dest_offset] should |
38 | 0 | // copy from dest[offset] |
39 | 0 | // i.e in the first iteration, the first entry in the window will point |
40 | 0 | // to dest[offset] and the |
41 | 0 | // last entry will point to dest[dest_offset] |
42 | 0 | // it's easy to prove dest[offset] since we take our slice |
43 | 0 | // from offset. |
44 | 0 | // but proving dest[dest_offset] is trickier |
45 | 0 | // If we were at offset, to get to dest_offset, we could |
46 | 0 | // 1. Get difference between dest_offset and offset |
47 | 0 | // 2. Add that difference to offset. |
48 | 0 | // |
49 | 0 |
|
50 | 0 | let diff = dest_offset - offset + 1; |
51 | | |
52 | | // note |
53 | 0 | for window in Cell::from_mut(&mut dest[offset..dest_offset + length + 2]) |
54 | 0 | .as_slice_of_cells() |
55 | 0 | .windows(diff) |
56 | 0 | { |
57 | 0 | window.last().unwrap().set(window[0].get()); |
58 | 0 | } |
59 | 0 | } |
60 | | |
61 | | /// Return the minimum of two usizes in a const context |
62 | | #[rustfmt::skip] |
63 | 0 | pub const fn const_min_usize(a: usize, b: usize) -> usize |
64 | 0 | { |
65 | 0 | if a < b { a } else { b } |
66 | 0 | } |
67 | | |
68 | | /// Calculate the adler hash of a piece of data. |
69 | | #[inline(never)] |
70 | | #[cfg(feature = "zlib")] |
71 | 0 | pub fn calc_adler_hash(data: &[u8]) -> u32 |
72 | 0 | { |
73 | | use simd_adler32::Adler32; |
74 | 0 | let mut hasher = Adler32::new(); |
75 | 0 |
|
76 | 0 | hasher.write(data); |
77 | 0 |
|
78 | 0 | hasher.finish() |
79 | 0 | } |