Coverage Report

Created: 2025-06-02 07:01

/rust/registry/src/index.crates.io-6f17d22bba15001f/flate2-1.0.30/src/crc.rs
Line
Count
Source (jump to first uncovered line)
1
//! Simple CRC bindings backed by miniz.c
2
3
use std::io;
4
use std::io::prelude::*;
5
6
use crc32fast::Hasher;
7
8
/// The CRC calculated by a [`CrcReader`].
9
///
10
/// [`CrcReader`]: struct.CrcReader.html
11
#[derive(Debug)]
12
pub struct Crc {
13
    amt: u32,
14
    hasher: Hasher,
15
}
16
17
/// A wrapper around a [`Read`] that calculates the CRC.
18
///
19
/// [`Read`]: https://doc.rust-lang.org/std/io/trait.Read.html
20
#[derive(Debug)]
21
pub struct CrcReader<R> {
22
    inner: R,
23
    crc: Crc,
24
}
25
26
impl Default for Crc {
27
0
    fn default() -> Self {
28
0
        Self::new()
29
0
    }
30
}
31
32
impl Crc {
33
    /// Create a new CRC.
34
0
    pub fn new() -> Crc {
35
0
        Crc {
36
0
            amt: 0,
37
0
            hasher: Hasher::new(),
38
0
        }
39
0
    }
40
41
    /// Returns the current crc32 checksum.
42
0
    pub fn sum(&self) -> u32 {
43
0
        self.hasher.clone().finalize()
44
0
    }
45
46
    /// The number of bytes that have been used to calculate the CRC.
47
    /// This value is only accurate if the amount is lower than 2<sup>32</sup>.
48
0
    pub fn amount(&self) -> u32 {
49
0
        self.amt
50
0
    }
51
52
    /// Update the CRC with the bytes in `data`.
53
0
    pub fn update(&mut self, data: &[u8]) {
54
0
        self.amt = self.amt.wrapping_add(data.len() as u32);
55
0
        self.hasher.update(data);
56
0
    }
57
58
    /// Reset the CRC.
59
0
    pub fn reset(&mut self) {
60
0
        self.amt = 0;
61
0
        self.hasher.reset();
62
0
    }
63
64
    /// Combine the CRC with the CRC for the subsequent block of bytes.
65
0
    pub fn combine(&mut self, additional_crc: &Crc) {
66
0
        self.amt = self.amt.wrapping_add(additional_crc.amt);
67
0
        self.hasher.combine(&additional_crc.hasher);
68
0
    }
69
}
70
71
impl<R: Read> CrcReader<R> {
72
    /// Create a new `CrcReader`.
73
0
    pub fn new(r: R) -> CrcReader<R> {
74
0
        CrcReader {
75
0
            inner: r,
76
0
            crc: Crc::new(),
77
0
        }
78
0
    }
79
}
80
81
impl<R> CrcReader<R> {
82
    /// Get the Crc for this `CrcReader`.
83
0
    pub fn crc(&self) -> &Crc {
84
0
        &self.crc
85
0
    }
86
87
    /// Get the reader that is wrapped by this `CrcReader`.
88
0
    pub fn into_inner(self) -> R {
89
0
        self.inner
90
0
    }
91
92
    /// Get the reader that is wrapped by this `CrcReader` by reference.
93
0
    pub fn get_ref(&self) -> &R {
94
0
        &self.inner
95
0
    }
96
97
    /// Get a mutable reference to the reader that is wrapped by this `CrcReader`.
98
0
    pub fn get_mut(&mut self) -> &mut R {
99
0
        &mut self.inner
100
0
    }
101
102
    /// Reset the Crc in this `CrcReader`.
103
0
    pub fn reset(&mut self) {
104
0
        self.crc.reset();
105
0
    }
106
}
107
108
impl<R: Read> Read for CrcReader<R> {
109
0
    fn read(&mut self, into: &mut [u8]) -> io::Result<usize> {
110
0
        let amt = self.inner.read(into)?;
111
0
        self.crc.update(&into[..amt]);
112
0
        Ok(amt)
113
0
    }
114
}
115
116
impl<R: BufRead> BufRead for CrcReader<R> {
117
0
    fn fill_buf(&mut self) -> io::Result<&[u8]> {
118
0
        self.inner.fill_buf()
119
0
    }
120
0
    fn consume(&mut self, amt: usize) {
121
0
        if let Ok(data) = self.inner.fill_buf() {
122
0
            self.crc.update(&data[..amt]);
123
0
        }
124
0
        self.inner.consume(amt);
125
0
    }
126
}
127
128
/// A wrapper around a [`Write`] that calculates the CRC.
129
///
130
/// [`Write`]: https://doc.rust-lang.org/std/io/trait.Write.html
131
#[derive(Debug)]
132
pub struct CrcWriter<W> {
133
    inner: W,
134
    crc: Crc,
135
}
136
137
impl<W> CrcWriter<W> {
138
    /// Get the Crc for this `CrcWriter`.
139
0
    pub fn crc(&self) -> &Crc {
140
0
        &self.crc
141
0
    }
142
143
    /// Get the writer that is wrapped by this `CrcWriter`.
144
0
    pub fn into_inner(self) -> W {
145
0
        self.inner
146
0
    }
147
148
    /// Get the writer that is wrapped by this `CrcWriter` by reference.
149
0
    pub fn get_ref(&self) -> &W {
150
0
        &self.inner
151
0
    }
152
153
    /// Get a mutable reference to the writer that is wrapped by this `CrcWriter`.
154
0
    pub fn get_mut(&mut self) -> &mut W {
155
0
        &mut self.inner
156
0
    }
157
158
    /// Reset the Crc in this `CrcWriter`.
159
0
    pub fn reset(&mut self) {
160
0
        self.crc.reset();
161
0
    }
162
}
163
164
impl<W: Write> CrcWriter<W> {
165
    /// Create a new `CrcWriter`.
166
0
    pub fn new(w: W) -> CrcWriter<W> {
167
0
        CrcWriter {
168
0
            inner: w,
169
0
            crc: Crc::new(),
170
0
        }
171
0
    }
172
}
173
174
impl<W: Write> Write for CrcWriter<W> {
175
0
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
176
0
        let amt = self.inner.write(buf)?;
177
0
        self.crc.update(&buf[..amt]);
178
0
        Ok(amt)
179
0
    }
180
181
0
    fn flush(&mut self) -> io::Result<()> {
182
0
        self.inner.flush()
183
0
    }
184
}