Coverage Report

Created: 2025-11-11 06:48

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/fdeflate-0.3.7/src/compress.rs
Line
Count
Source
1
use simd_adler32::Adler32;
2
use std::io::{self, Seek, SeekFrom, Write};
3
4
use crate::tables::{
5
    BITMASKS, HUFFMAN_CODES, HUFFMAN_LENGTHS, LENGTH_TO_LEN_EXTRA, LENGTH_TO_SYMBOL,
6
};
7
8
/// Compressor that produces fdeflate compressed streams.
9
pub struct Compressor<W: Write> {
10
    checksum: Adler32,
11
    buffer: u64,
12
    nbits: u8,
13
    writer: W,
14
}
15
impl<W: Write> Compressor<W> {
16
22.0M
    fn write_bits(&mut self, bits: u64, nbits: u8) -> io::Result<()> {
17
22.0M
        debug_assert!(nbits <= 64);
18
19
22.0M
        self.buffer |= bits << self.nbits;
20
22.0M
        self.nbits += nbits;
21
22
22.0M
        if self.nbits >= 64 {
23
3.99M
            self.writer.write_all(&self.buffer.to_le_bytes())?;
24
3.99M
            self.nbits -= 64;
25
3.99M
            self.buffer = bits.checked_shr((nbits - self.nbits) as u32).unwrap_or(0);
26
18.0M
        }
27
22.0M
        debug_assert!(self.nbits < 64);
28
22.0M
        Ok(())
29
22.0M
    }
<fdeflate::compress::Compressor<std::io::cursor::Cursor<alloc::vec::Vec<u8>>>>::write_bits
Line
Count
Source
16
22.0M
    fn write_bits(&mut self, bits: u64, nbits: u8) -> io::Result<()> {
17
22.0M
        debug_assert!(nbits <= 64);
18
19
22.0M
        self.buffer |= bits << self.nbits;
20
22.0M
        self.nbits += nbits;
21
22
22.0M
        if self.nbits >= 64 {
23
3.99M
            self.writer.write_all(&self.buffer.to_le_bytes())?;
24
3.99M
            self.nbits -= 64;
25
3.99M
            self.buffer = bits.checked_shr((nbits - self.nbits) as u32).unwrap_or(0);
26
18.0M
        }
27
22.0M
        debug_assert!(self.nbits < 64);
28
22.0M
        Ok(())
29
22.0M
    }
Unexecuted instantiation: <fdeflate::compress::Compressor<alloc::vec::Vec<u8>>>::write_bits
30
31
883
    fn flush(&mut self) -> io::Result<()> {
32
883
        if self.nbits % 8 != 0 {
33
757
            self.write_bits(0, 8 - self.nbits % 8)?;
34
126
        }
35
883
        if self.nbits > 0 {
36
775
            self.writer
37
775
                .write_all(&self.buffer.to_le_bytes()[..self.nbits as usize / 8])
38
775
                .unwrap();
39
775
            self.buffer = 0;
40
775
            self.nbits = 0;
41
775
        }
42
883
        Ok(())
43
883
    }
<fdeflate::compress::Compressor<std::io::cursor::Cursor<alloc::vec::Vec<u8>>>>::flush
Line
Count
Source
31
883
    fn flush(&mut self) -> io::Result<()> {
32
883
        if self.nbits % 8 != 0 {
33
757
            self.write_bits(0, 8 - self.nbits % 8)?;
34
126
        }
35
883
        if self.nbits > 0 {
36
775
            self.writer
37
775
                .write_all(&self.buffer.to_le_bytes()[..self.nbits as usize / 8])
38
775
                .unwrap();
39
775
            self.buffer = 0;
40
775
            self.nbits = 0;
41
775
        }
42
883
        Ok(())
43
883
    }
Unexecuted instantiation: <fdeflate::compress::Compressor<alloc::vec::Vec<u8>>>::flush
44
45
362k
    fn write_run(&mut self, mut run: u32) -> io::Result<()> {
46
362k
        self.write_bits(HUFFMAN_CODES[0] as u64, HUFFMAN_LENGTHS[0])?;
47
362k
        run -= 1;
48
49
365k
        while run >= 258 {
50
2.86k
            self.write_bits(HUFFMAN_CODES[285] as u64, HUFFMAN_LENGTHS[285] + 1)?;
51
2.86k
            run -= 258;
52
        }
53
54
362k
        if run > 4 {
55
185k
            let sym = LENGTH_TO_SYMBOL[run as usize - 3] as usize;
56
185k
            self.write_bits(HUFFMAN_CODES[sym] as u64, HUFFMAN_LENGTHS[sym])?;
57
58
185k
            let len_extra = LENGTH_TO_LEN_EXTRA[run as usize - 3];
59
185k
            let extra = ((run - 3) & BITMASKS[len_extra as usize]) as u64;
60
185k
            self.write_bits(extra, len_extra + 1)?;
61
        } else {
62
177k
            debug_assert_eq!(HUFFMAN_CODES[0], 0);
63
177k
            self.write_bits(0, run as u8 * HUFFMAN_LENGTHS[0])?;
64
        }
65
66
362k
        Ok(())
67
362k
    }
<fdeflate::compress::Compressor<std::io::cursor::Cursor<alloc::vec::Vec<u8>>>>::write_run
Line
Count
Source
45
362k
    fn write_run(&mut self, mut run: u32) -> io::Result<()> {
46
362k
        self.write_bits(HUFFMAN_CODES[0] as u64, HUFFMAN_LENGTHS[0])?;
47
362k
        run -= 1;
48
49
365k
        while run >= 258 {
50
2.86k
            self.write_bits(HUFFMAN_CODES[285] as u64, HUFFMAN_LENGTHS[285] + 1)?;
51
2.86k
            run -= 258;
52
        }
53
54
362k
        if run > 4 {
55
185k
            let sym = LENGTH_TO_SYMBOL[run as usize - 3] as usize;
56
185k
            self.write_bits(HUFFMAN_CODES[sym] as u64, HUFFMAN_LENGTHS[sym])?;
57
58
185k
            let len_extra = LENGTH_TO_LEN_EXTRA[run as usize - 3];
59
185k
            let extra = ((run - 3) & BITMASKS[len_extra as usize]) as u64;
60
185k
            self.write_bits(extra, len_extra + 1)?;
61
        } else {
62
177k
            debug_assert_eq!(HUFFMAN_CODES[0], 0);
63
177k
            self.write_bits(0, run as u8 * HUFFMAN_LENGTHS[0])?;
64
        }
65
66
362k
        Ok(())
67
362k
    }
Unexecuted instantiation: <fdeflate::compress::Compressor<alloc::vec::Vec<u8>>>::write_run
68
69
    /// Create a new Compressor.
70
883
    pub fn new(writer: W) -> io::Result<Self> {
71
883
        let mut compressor = Self {
72
883
            checksum: Adler32::new(),
73
883
            buffer: 0,
74
883
            nbits: 0,
75
883
            writer,
76
883
        };
77
883
        compressor.write_headers()?;
78
883
        Ok(compressor)
79
883
    }
<fdeflate::compress::Compressor<std::io::cursor::Cursor<alloc::vec::Vec<u8>>>>::new
Line
Count
Source
70
883
    pub fn new(writer: W) -> io::Result<Self> {
71
883
        let mut compressor = Self {
72
883
            checksum: Adler32::new(),
73
883
            buffer: 0,
74
883
            nbits: 0,
75
883
            writer,
76
883
        };
77
883
        compressor.write_headers()?;
78
883
        Ok(compressor)
79
883
    }
Unexecuted instantiation: <fdeflate::compress::Compressor<alloc::vec::Vec<u8>>>::new
80
81
883
    fn write_headers(&mut self) -> io::Result<()> {
82
        const HEADER: [u8; 54] = [
83
            120, 1, 237, 192, 3, 160, 36, 89, 150, 198, 241, 255, 119, 238, 141, 200, 204, 167,
84
            114, 75, 99, 174, 109, 219, 182, 109, 219, 182, 109, 219, 182, 109, 105, 140, 158, 150,
85
            74, 175, 158, 50, 51, 34, 238, 249, 118, 183, 106, 122, 166, 135, 59, 107, 213, 15,
86
        ];
87
883
        self.writer.write_all(&HEADER[..53]).unwrap();
88
883
        self.write_bits(HEADER[53] as u64, 5)?;
89
90
883
        Ok(())
91
883
    }
<fdeflate::compress::Compressor<std::io::cursor::Cursor<alloc::vec::Vec<u8>>>>::write_headers
Line
Count
Source
81
883
    fn write_headers(&mut self) -> io::Result<()> {
82
        const HEADER: [u8; 54] = [
83
            120, 1, 237, 192, 3, 160, 36, 89, 150, 198, 241, 255, 119, 238, 141, 200, 204, 167,
84
            114, 75, 99, 174, 109, 219, 182, 109, 219, 182, 109, 219, 182, 109, 105, 140, 158, 150,
85
            74, 175, 158, 50, 51, 34, 238, 249, 118, 183, 106, 122, 166, 135, 59, 107, 213, 15,
86
        ];
87
883
        self.writer.write_all(&HEADER[..53]).unwrap();
88
883
        self.write_bits(HEADER[53] as u64, 5)?;
89
90
883
        Ok(())
91
883
    }
Unexecuted instantiation: <fdeflate::compress::Compressor<alloc::vec::Vec<u8>>>::write_headers
92
93
    /// Write data to the compressor.
94
8.79M
    pub fn write_data(&mut self, data: &[u8]) -> io::Result<()> {
95
8.79M
        self.checksum.write(data);
96
97
8.79M
        let mut run = 0;
98
8.79M
        let mut chunks = data.chunks_exact(8);
99
10.6M
        for chunk in &mut chunks {
100
1.89M
            let ichunk = u64::from_le_bytes(chunk.try_into().unwrap());
101
102
1.89M
            if ichunk == 0 {
103
179k
                run += 8;
104
179k
                continue;
105
1.71M
            } else if run > 0 {
106
153k
                let run_extra = ichunk.trailing_zeros() / 8;
107
153k
                self.write_run(run + run_extra)?;
108
153k
                run = 0;
109
110
153k
                if run_extra > 0 {
111
35.4k
                    run = ichunk.leading_zeros() / 8;
112
132k
                    for &b in &chunk[run_extra as usize..8 - run as usize] {
113
132k
                        self.write_bits(
114
132k
                            HUFFMAN_CODES[b as usize] as u64,
115
132k
                            HUFFMAN_LENGTHS[b as usize],
116
0
                        )?;
117
                    }
118
35.4k
                    continue;
119
117k
                }
120
1.56M
            }
121
122
1.67M
            let run_start = ichunk.leading_zeros() / 8;
123
1.67M
            if run_start > 0 {
124
1.35M
                for &b in &chunk[..8 - run_start as usize] {
125
1.35M
                    self.write_bits(
126
1.35M
                        HUFFMAN_CODES[b as usize] as u64,
127
1.35M
                        HUFFMAN_LENGTHS[b as usize],
128
0
                    )?;
129
                }
130
343k
                run = run_start;
131
343k
                continue;
132
1.33M
            }
133
134
1.33M
            let n0 = HUFFMAN_LENGTHS[chunk[0] as usize];
135
1.33M
            let n1 = HUFFMAN_LENGTHS[chunk[1] as usize];
136
1.33M
            let n2 = HUFFMAN_LENGTHS[chunk[2] as usize];
137
1.33M
            let n3 = HUFFMAN_LENGTHS[chunk[3] as usize];
138
1.33M
            let bits = HUFFMAN_CODES[chunk[0] as usize] as u64
139
1.33M
                | ((HUFFMAN_CODES[chunk[1] as usize] as u64) << n0)
140
1.33M
                | ((HUFFMAN_CODES[chunk[2] as usize] as u64) << (n0 + n1))
141
1.33M
                | ((HUFFMAN_CODES[chunk[3] as usize] as u64) << (n0 + n1 + n2));
142
1.33M
            self.write_bits(bits, n0 + n1 + n2 + n3)?;
143
144
1.33M
            let n4 = HUFFMAN_LENGTHS[chunk[4] as usize];
145
1.33M
            let n5 = HUFFMAN_LENGTHS[chunk[5] as usize];
146
1.33M
            let n6 = HUFFMAN_LENGTHS[chunk[6] as usize];
147
1.33M
            let n7 = HUFFMAN_LENGTHS[chunk[7] as usize];
148
1.33M
            let bits2 = HUFFMAN_CODES[chunk[4] as usize] as u64
149
1.33M
                | ((HUFFMAN_CODES[chunk[5] as usize] as u64) << n4)
150
1.33M
                | ((HUFFMAN_CODES[chunk[6] as usize] as u64) << (n4 + n5))
151
1.33M
                | ((HUFFMAN_CODES[chunk[7] as usize] as u64) << (n4 + n5 + n6));
152
1.33M
            self.write_bits(bits2, n4 + n5 + n6 + n7)?;
153
        }
154
155
8.79M
        if run > 0 {
156
209k
            self.write_run(run)?;
157
8.58M
        }
158
159
17.0M
        for &b in chunks.remainder() {
160
17.0M
            self.write_bits(
161
17.0M
                HUFFMAN_CODES[b as usize] as u64,
162
17.0M
                HUFFMAN_LENGTHS[b as usize],
163
0
            )?;
164
        }
165
166
8.79M
        Ok(())
167
8.79M
    }
<fdeflate::compress::Compressor<std::io::cursor::Cursor<alloc::vec::Vec<u8>>>>::write_data
Line
Count
Source
94
8.79M
    pub fn write_data(&mut self, data: &[u8]) -> io::Result<()> {
95
8.79M
        self.checksum.write(data);
96
97
8.79M
        let mut run = 0;
98
8.79M
        let mut chunks = data.chunks_exact(8);
99
10.6M
        for chunk in &mut chunks {
100
1.89M
            let ichunk = u64::from_le_bytes(chunk.try_into().unwrap());
101
102
1.89M
            if ichunk == 0 {
103
179k
                run += 8;
104
179k
                continue;
105
1.71M
            } else if run > 0 {
106
153k
                let run_extra = ichunk.trailing_zeros() / 8;
107
153k
                self.write_run(run + run_extra)?;
108
153k
                run = 0;
109
110
153k
                if run_extra > 0 {
111
35.4k
                    run = ichunk.leading_zeros() / 8;
112
132k
                    for &b in &chunk[run_extra as usize..8 - run as usize] {
113
132k
                        self.write_bits(
114
132k
                            HUFFMAN_CODES[b as usize] as u64,
115
132k
                            HUFFMAN_LENGTHS[b as usize],
116
0
                        )?;
117
                    }
118
35.4k
                    continue;
119
117k
                }
120
1.56M
            }
121
122
1.67M
            let run_start = ichunk.leading_zeros() / 8;
123
1.67M
            if run_start > 0 {
124
1.35M
                for &b in &chunk[..8 - run_start as usize] {
125
1.35M
                    self.write_bits(
126
1.35M
                        HUFFMAN_CODES[b as usize] as u64,
127
1.35M
                        HUFFMAN_LENGTHS[b as usize],
128
0
                    )?;
129
                }
130
343k
                run = run_start;
131
343k
                continue;
132
1.33M
            }
133
134
1.33M
            let n0 = HUFFMAN_LENGTHS[chunk[0] as usize];
135
1.33M
            let n1 = HUFFMAN_LENGTHS[chunk[1] as usize];
136
1.33M
            let n2 = HUFFMAN_LENGTHS[chunk[2] as usize];
137
1.33M
            let n3 = HUFFMAN_LENGTHS[chunk[3] as usize];
138
1.33M
            let bits = HUFFMAN_CODES[chunk[0] as usize] as u64
139
1.33M
                | ((HUFFMAN_CODES[chunk[1] as usize] as u64) << n0)
140
1.33M
                | ((HUFFMAN_CODES[chunk[2] as usize] as u64) << (n0 + n1))
141
1.33M
                | ((HUFFMAN_CODES[chunk[3] as usize] as u64) << (n0 + n1 + n2));
142
1.33M
            self.write_bits(bits, n0 + n1 + n2 + n3)?;
143
144
1.33M
            let n4 = HUFFMAN_LENGTHS[chunk[4] as usize];
145
1.33M
            let n5 = HUFFMAN_LENGTHS[chunk[5] as usize];
146
1.33M
            let n6 = HUFFMAN_LENGTHS[chunk[6] as usize];
147
1.33M
            let n7 = HUFFMAN_LENGTHS[chunk[7] as usize];
148
1.33M
            let bits2 = HUFFMAN_CODES[chunk[4] as usize] as u64
149
1.33M
                | ((HUFFMAN_CODES[chunk[5] as usize] as u64) << n4)
150
1.33M
                | ((HUFFMAN_CODES[chunk[6] as usize] as u64) << (n4 + n5))
151
1.33M
                | ((HUFFMAN_CODES[chunk[7] as usize] as u64) << (n4 + n5 + n6));
152
1.33M
            self.write_bits(bits2, n4 + n5 + n6 + n7)?;
153
        }
154
155
8.79M
        if run > 0 {
156
209k
            self.write_run(run)?;
157
8.58M
        }
158
159
17.0M
        for &b in chunks.remainder() {
160
17.0M
            self.write_bits(
161
17.0M
                HUFFMAN_CODES[b as usize] as u64,
162
17.0M
                HUFFMAN_LENGTHS[b as usize],
163
0
            )?;
164
        }
165
166
8.79M
        Ok(())
167
8.79M
    }
Unexecuted instantiation: <fdeflate::compress::Compressor<alloc::vec::Vec<u8>>>::write_data
168
169
    /// Write the remainder of the stream and return the inner writer.
170
883
    pub fn finish(mut self) -> io::Result<W> {
171
        // Write end of block
172
883
        self.write_bits(HUFFMAN_CODES[256] as u64, HUFFMAN_LENGTHS[256])?;
173
883
        self.flush()?;
174
175
        // Write Adler32 checksum
176
883
        let checksum: u32 = self.checksum.finish();
177
883
        self.writer
178
883
            .write_all(checksum.to_be_bytes().as_ref())
179
883
            .unwrap();
180
883
        Ok(self.writer)
181
883
    }
<fdeflate::compress::Compressor<std::io::cursor::Cursor<alloc::vec::Vec<u8>>>>::finish
Line
Count
Source
170
883
    pub fn finish(mut self) -> io::Result<W> {
171
        // Write end of block
172
883
        self.write_bits(HUFFMAN_CODES[256] as u64, HUFFMAN_LENGTHS[256])?;
173
883
        self.flush()?;
174
175
        // Write Adler32 checksum
176
883
        let checksum: u32 = self.checksum.finish();
177
883
        self.writer
178
883
            .write_all(checksum.to_be_bytes().as_ref())
179
883
            .unwrap();
180
883
        Ok(self.writer)
181
883
    }
Unexecuted instantiation: <fdeflate::compress::Compressor<alloc::vec::Vec<u8>>>::finish
182
}
183
184
/// Compressor that only writes the stored blocks.
185
///
186
/// This is useful for writing files that are not compressed, but still need to be wrapped in a
187
/// zlib stream.
188
pub struct StoredOnlyCompressor<W> {
189
    writer: W,
190
    checksum: Adler32,
191
    block_bytes: u16,
192
}
193
impl<W: Write + Seek> StoredOnlyCompressor<W> {
194
    /// Creates a new `StoredOnlyCompressor` that writes to the given writer.
195
701
    pub fn new(mut writer: W) -> io::Result<Self> {
196
701
        writer.write_all(&[0x78, 0x01])?; // zlib header
197
701
        writer.write_all(&[0; 5])?; // placeholder stored block header
198
199
701
        Ok(Self {
200
701
            writer,
201
701
            checksum: Adler32::new(),
202
701
            block_bytes: 0,
203
701
        })
204
701
    }
<fdeflate::compress::StoredOnlyCompressor<std::io::cursor::Cursor<alloc::vec::Vec<u8>>>>::new
Line
Count
Source
195
701
    pub fn new(mut writer: W) -> io::Result<Self> {
196
701
        writer.write_all(&[0x78, 0x01])?; // zlib header
197
701
        writer.write_all(&[0; 5])?; // placeholder stored block header
198
199
701
        Ok(Self {
200
701
            writer,
201
701
            checksum: Adler32::new(),
202
701
            block_bytes: 0,
203
701
        })
204
701
    }
Unexecuted instantiation: <fdeflate::compress::StoredOnlyCompressor<_>>::new
205
206
1.10k
    fn set_block_header(&mut self, size: u16, last: bool) -> io::Result<()> {
207
1.10k
        self.writer.seek(SeekFrom::Current(-(size as i64 + 5)))?;
208
1.10k
        self.writer.write_all(&[
209
1.10k
            last as u8,
210
1.10k
            (size & 0xFF) as u8,
211
1.10k
            ((size >> 8) & 0xFF) as u8,
212
1.10k
            (!size & 0xFF) as u8,
213
1.10k
            ((!size >> 8) & 0xFF) as u8,
214
1.10k
        ])?;
215
1.10k
        self.writer.seek(SeekFrom::Current(size as i64))?;
216
217
1.10k
        Ok(())
218
1.10k
    }
<fdeflate::compress::StoredOnlyCompressor<std::io::cursor::Cursor<alloc::vec::Vec<u8>>>>::set_block_header
Line
Count
Source
206
1.10k
    fn set_block_header(&mut self, size: u16, last: bool) -> io::Result<()> {
207
1.10k
        self.writer.seek(SeekFrom::Current(-(size as i64 + 5)))?;
208
1.10k
        self.writer.write_all(&[
209
1.10k
            last as u8,
210
1.10k
            (size & 0xFF) as u8,
211
1.10k
            ((size >> 8) & 0xFF) as u8,
212
1.10k
            (!size & 0xFF) as u8,
213
1.10k
            ((!size >> 8) & 0xFF) as u8,
214
1.10k
        ])?;
215
1.10k
        self.writer.seek(SeekFrom::Current(size as i64))?;
216
217
1.10k
        Ok(())
218
1.10k
    }
Unexecuted instantiation: <fdeflate::compress::StoredOnlyCompressor<_>>::set_block_header
219
220
    /// Writes the given data to the underlying writer.
221
18.7M
    pub fn write_data(&mut self, mut data: &[u8]) -> io::Result<()> {
222
18.7M
        self.checksum.write(data);
223
37.5M
        while !data.is_empty() {
224
18.7M
            if self.block_bytes == u16::MAX {
225
402
                self.set_block_header(u16::MAX, false)?;
226
402
                self.writer.write_all(&[0; 5])?; // placeholder stored block header
227
402
                self.block_bytes = 0;
228
18.7M
            }
229
230
18.7M
            let prefix_bytes = data.len().min((u16::MAX - self.block_bytes) as usize);
231
18.7M
            self.writer.write_all(&data[..prefix_bytes])?;
232
18.7M
            self.block_bytes += prefix_bytes as u16;
233
18.7M
            data = &data[prefix_bytes..];
234
        }
235
236
18.7M
        Ok(())
237
18.7M
    }
<fdeflate::compress::StoredOnlyCompressor<std::io::cursor::Cursor<alloc::vec::Vec<u8>>>>::write_data
Line
Count
Source
221
18.7M
    pub fn write_data(&mut self, mut data: &[u8]) -> io::Result<()> {
222
18.7M
        self.checksum.write(data);
223
37.5M
        while !data.is_empty() {
224
18.7M
            if self.block_bytes == u16::MAX {
225
402
                self.set_block_header(u16::MAX, false)?;
226
402
                self.writer.write_all(&[0; 5])?; // placeholder stored block header
227
402
                self.block_bytes = 0;
228
18.7M
            }
229
230
18.7M
            let prefix_bytes = data.len().min((u16::MAX - self.block_bytes) as usize);
231
18.7M
            self.writer.write_all(&data[..prefix_bytes])?;
232
18.7M
            self.block_bytes += prefix_bytes as u16;
233
18.7M
            data = &data[prefix_bytes..];
234
        }
235
236
18.7M
        Ok(())
237
18.7M
    }
Unexecuted instantiation: <fdeflate::compress::StoredOnlyCompressor<_>>::write_data
238
239
    /// Finish writing the final block and return the underlying writer.
240
701
    pub fn finish(mut self) -> io::Result<W> {
241
701
        self.set_block_header(self.block_bytes, true)?;
242
243
        // Write Adler32 checksum
244
701
        let checksum: u32 = self.checksum.finish();
245
701
        self.writer
246
701
            .write_all(checksum.to_be_bytes().as_ref())
247
701
            .unwrap();
248
249
701
        Ok(self.writer)
250
701
    }
<fdeflate::compress::StoredOnlyCompressor<std::io::cursor::Cursor<alloc::vec::Vec<u8>>>>::finish
Line
Count
Source
240
701
    pub fn finish(mut self) -> io::Result<W> {
241
701
        self.set_block_header(self.block_bytes, true)?;
242
243
        // Write Adler32 checksum
244
701
        let checksum: u32 = self.checksum.finish();
245
701
        self.writer
246
701
            .write_all(checksum.to_be_bytes().as_ref())
247
701
            .unwrap();
248
249
701
        Ok(self.writer)
250
701
    }
Unexecuted instantiation: <fdeflate::compress::StoredOnlyCompressor<_>>::finish
251
}
252
impl<W> StoredOnlyCompressor<W> {
253
    /// Return the number of bytes that will be written to the output stream
254
    /// for the given input size. Because this compressor only writes stored blocks,
255
    /// the output size is always slightly *larger* than the input size.
256
883
    pub fn compressed_size(raw_size: usize) -> usize {
257
883
        (raw_size.saturating_sub(1) / u16::MAX as usize) * (u16::MAX as usize + 5)
258
883
            + (raw_size % u16::MAX as usize + 5)
259
883
            + 6
260
883
    }
<fdeflate::compress::StoredOnlyCompressor<()>>::compressed_size
Line
Count
Source
256
883
    pub fn compressed_size(raw_size: usize) -> usize {
257
883
        (raw_size.saturating_sub(1) / u16::MAX as usize) * (u16::MAX as usize + 5)
258
883
            + (raw_size % u16::MAX as usize + 5)
259
883
            + 6
260
883
    }
Unexecuted instantiation: <fdeflate::compress::StoredOnlyCompressor<_>>::compressed_size
261
}
262
263
/// Compresses the given data.
264
0
pub fn compress_to_vec(input: &[u8]) -> Vec<u8> {
265
0
    let mut compressor = Compressor::new(Vec::with_capacity(input.len() / 4)).unwrap();
266
0
    compressor.write_data(input).unwrap();
267
0
    compressor.finish().unwrap()
268
0
}
269
270
#[cfg(test)]
271
mod tests {
272
    use super::*;
273
    use rand::Rng;
274
275
    fn roundtrip(data: &[u8]) {
276
        let compressed = compress_to_vec(data);
277
        let decompressed = miniz_oxide::inflate::decompress_to_vec_zlib(&compressed).unwrap();
278
        assert_eq!(&decompressed, data);
279
    }
280
281
    #[test]
282
    fn it_works() {
283
        roundtrip(b"Hello world!");
284
    }
285
286
    #[test]
287
    fn constant() {
288
        roundtrip(&vec![0; 2048]);
289
        roundtrip(&vec![5; 2048]);
290
        roundtrip(&vec![128; 2048]);
291
        roundtrip(&vec![254; 2048]);
292
    }
293
294
    #[test]
295
    fn random() {
296
        let mut rng = rand::thread_rng();
297
        let mut data = vec![0; 2048];
298
        for _ in 0..10 {
299
            for byte in &mut data {
300
                *byte = rng.gen();
301
            }
302
            roundtrip(&data);
303
        }
304
    }
305
}