Coverage Report

Created: 2025-07-01 07:43

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