zstd-complete 0.3.0

A pure Rust Zstandard compressor and decompressor with bounded streaming I/O
Documentation
use super::HuffmanTable;

impl HuffmanTable {
    pub(crate) fn can_encode_counts(&self, counts: &[usize]) -> bool {
        if counts.len() > self.codes.len() {
            return false;
        }

        counts
            .iter()
            .copied()
            .zip(self.codes.iter().copied())
            .all(|(count, (_, num_bits))| count == 0 || num_bits != 0)
    }

    pub(crate) fn encoded_len(&self, data: &[u8], with_table: bool, four_streams: bool) -> usize {
        let table_len = if with_table {
            self.table_description_len()
        } else {
            0
        };
        let data_len = if four_streams {
            let split_size = data.len().div_ceil(4);
            6 + self.stream_encoded_len(&data[..split_size])
                + self.stream_encoded_len(&data[split_size..split_size * 2])
                + self.stream_encoded_len(&data[split_size * 2..split_size * 3])
                + self.stream_encoded_len(&data[split_size * 3..])
        } else {
            self.stream_encoded_len(data)
        };
        table_len + data_len
    }

    pub(crate) fn encoded_len_from_counts(&self, counts: &[usize], with_table: bool) -> usize {
        let table_len = if with_table {
            self.table_description_len()
        } else {
            0
        };
        table_len + self.stream_encoded_len_from_counts(counts)
    }

    pub(crate) fn encoded_len_from_stream_counts(
        &self,
        stream_counts: &[[usize; 256]; 4],
        with_table: bool,
    ) -> usize {
        let table_len = if with_table {
            self.table_description_len()
        } else {
            0
        };
        table_len
            + 6
            + stream_counts
                .iter()
                .map(|counts| self.stream_encoded_len_from_counts(counts))
                .sum::<usize>()
    }

    pub(crate) fn estimated_compressed_size_from_counts(&self, counts: &[usize]) -> usize {
        let bit_len = counts
            .iter()
            .copied()
            .zip(self.codes.iter().copied())
            .map(|(count, (_, num_bits))| count * usize::from(num_bits))
            .sum::<usize>();
        bit_len >> 3
    }

    pub(crate) fn table_description_len(&self) -> usize {
        self.table_description.len()
    }

    fn stream_encoded_len(&self, data: &[u8]) -> usize {
        let mut bit_len = 0usize;
        for symbol in data {
            bit_len += self.codes[*symbol as usize].1 as usize;
        }
        bit_len / 8 + 1
    }

    fn stream_encoded_len_from_counts(&self, counts: &[usize]) -> usize {
        let bit_len = counts
            .iter()
            .copied()
            .zip(self.codes.iter().copied())
            .map(|(count, (_, num_bits))| count * usize::from(num_bits))
            .sum::<usize>();
        bit_len / 8 + 1
    }
}