diff options
Diffstat (limited to 'vendor/zune-inflate/src/utils.rs')
-rw-r--r-- | vendor/zune-inflate/src/utils.rs | 79 |
1 files changed, 79 insertions, 0 deletions
diff --git a/vendor/zune-inflate/src/utils.rs b/vendor/zune-inflate/src/utils.rs new file mode 100644 index 0000000..56e20f9 --- /dev/null +++ b/vendor/zune-inflate/src/utils.rs @@ -0,0 +1,79 @@ +use core::cell::Cell; + +/// make_decode_table_entry() creates a decode table entry for the given symbol +/// by combining the static part 'decode_results[sym]' with the dynamic part +/// 'len', which is the remaining codeword length (the codeword length for main +/// table entries, or the codeword length minus TABLEBITS for subtable entries). +/// +/// In all cases, we add 'len' to each of the two low-order bytes to create the +/// appropriately-formatted decode table entry. See the definitions of the +/// *_decode_results[] arrays below, where the entry format is described. +pub(crate) fn make_decode_table_entry(decode_results: &[u32], sym: usize, len: u32) -> u32 +{ + decode_results[sym] + (len << 8) + len +} + +/// A safe version of src.copy_within that helps me because I tend to always +/// confuse the arguments +pub fn fixed_copy_within<const SIZE: usize>(dest: &mut [u8], src_offset: usize, dest_offset: usize) +{ + // for debug builds ensure we don't go out of bounds + debug_assert!( + dest_offset + SIZE <= dest.len(), + "[dst]: End position {} out of range for slice of length {}", + dest_offset + SIZE, + dest.len() + ); + + dest.copy_within(src_offset..src_offset + SIZE, dest_offset); +} + +#[inline(always)] +pub fn copy_rep_matches(dest: &mut [u8], offset: usize, dest_offset: usize, length: usize) +{ + // This is a slightly complicated rep match copier that has + // no bounds check. + + // The only invariant we need to uphold is dest[dest_offset] should + // copy from dest[offset] + // i.e in the first iteration, the first entry in the window will point + // to dest[offset] and the + // last entry will point to dest[dest_offset] + // it's easy to prove dest[offset] since we take our slice + // from offset. + // but proving dest[dest_offset] is trickier + // If we were at offset, to get to dest_offset, we could + // 1. Get difference between dest_offset and offset + // 2. Add that difference to offset. + // + + let diff = dest_offset - offset + 1; + + // note + for window in Cell::from_mut(&mut dest[offset..dest_offset + length + 2]) + .as_slice_of_cells() + .windows(diff) + { + window.last().unwrap().set(window[0].get()); + } +} + +/// Return the minimum of two usizes in a const context +#[rustfmt::skip] +pub const fn const_min_usize(a: usize, b: usize) -> usize +{ + if a < b { a } else { b } +} + +/// Calculate the adler hash of a piece of data. +#[inline(never)] +#[cfg(feature = "zlib")] +pub fn calc_adler_hash(data: &[u8]) -> u32 +{ + use simd_adler32::Adler32; + let mut hasher = Adler32::new(); + + hasher.write(data); + + hasher.finish() +} |