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 {
default() -> Self27     fn default() -> Self {
28         Self::new()
29     }
30 }
31 
32 impl Crc {
33     /// Create a new CRC.
new() -> Crc34     pub fn new() -> Crc {
35         Crc {
36             amt: 0,
37             hasher: Hasher::new(),
38         }
39     }
40 
41     /// Returns the current crc32 checksum.
sum(&self) -> u3242     pub fn sum(&self) -> u32 {
43         self.hasher.clone().finalize()
44     }
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>.
amount(&self) -> u3248     pub fn amount(&self) -> u32 {
49         self.amt
50     }
51 
52     /// Update the CRC with the bytes in `data`.
update(&mut self, data: &[u8])53     pub fn update(&mut self, data: &[u8]) {
54         self.amt = self.amt.wrapping_add(data.len() as u32);
55         self.hasher.update(data);
56     }
57 
58     /// Reset the CRC.
reset(&mut self)59     pub fn reset(&mut self) {
60         self.amt = 0;
61         self.hasher.reset();
62     }
63 
64     /// Combine the CRC with the CRC for the subsequent block of bytes.
combine(&mut self, additional_crc: &Crc)65     pub fn combine(&mut self, additional_crc: &Crc) {
66         self.amt = self.amt.wrapping_add(additional_crc.amt);
67         self.hasher.combine(&additional_crc.hasher);
68     }
69 }
70 
71 impl<R: Read> CrcReader<R> {
72     /// Create a new `CrcReader`.
new(r: R) -> CrcReader<R>73     pub fn new(r: R) -> CrcReader<R> {
74         CrcReader {
75             inner: r,
76             crc: Crc::new(),
77         }
78     }
79 }
80 
81 impl<R> CrcReader<R> {
82     /// Get the Crc for this `CrcReader`.
crc(&self) -> &Crc83     pub fn crc(&self) -> &Crc {
84         &self.crc
85     }
86 
87     /// Get the reader that is wrapped by this `CrcReader`.
into_inner(self) -> R88     pub fn into_inner(self) -> R {
89         self.inner
90     }
91 
92     /// Get the reader that is wrapped by this `CrcReader` by reference.
get_ref(&self) -> &R93     pub fn get_ref(&self) -> &R {
94         &self.inner
95     }
96 
97     /// Get a mutable reference to the reader that is wrapped by this `CrcReader`.
get_mut(&mut self) -> &mut R98     pub fn get_mut(&mut self) -> &mut R {
99         &mut self.inner
100     }
101 
102     /// Reset the Crc in this `CrcReader`.
reset(&mut self)103     pub fn reset(&mut self) {
104         self.crc.reset();
105     }
106 }
107 
108 impl<R: Read> Read for CrcReader<R> {
read(&mut self, into: &mut [u8]) -> io::Result<usize>109     fn read(&mut self, into: &mut [u8]) -> io::Result<usize> {
110         let amt = self.inner.read(into)?;
111         self.crc.update(&into[..amt]);
112         Ok(amt)
113     }
114 }
115 
116 impl<R: BufRead> BufRead for CrcReader<R> {
fill_buf(&mut self) -> io::Result<&[u8]>117     fn fill_buf(&mut self) -> io::Result<&[u8]> {
118         self.inner.fill_buf()
119     }
consume(&mut self, amt: usize)120     fn consume(&mut self, amt: usize) {
121         if let Ok(data) = self.inner.fill_buf() {
122             self.crc.update(&data[..amt]);
123         }
124         self.inner.consume(amt);
125     }
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`.
crc(&self) -> &Crc139     pub fn crc(&self) -> &Crc {
140         &self.crc
141     }
142 
143     /// Get the writer that is wrapped by this `CrcWriter`.
into_inner(self) -> W144     pub fn into_inner(self) -> W {
145         self.inner
146     }
147 
148     /// Get the writer that is wrapped by this `CrcWriter` by reference.
get_ref(&self) -> &W149     pub fn get_ref(&self) -> &W {
150         &self.inner
151     }
152 
153     /// Get a mutable reference to the writer that is wrapped by this `CrcWriter`.
get_mut(&mut self) -> &mut W154     pub fn get_mut(&mut self) -> &mut W {
155         &mut self.inner
156     }
157 
158     /// Reset the Crc in this `CrcWriter`.
reset(&mut self)159     pub fn reset(&mut self) {
160         self.crc.reset();
161     }
162 }
163 
164 impl<W: Write> CrcWriter<W> {
165     /// Create a new `CrcWriter`.
new(w: W) -> CrcWriter<W>166     pub fn new(w: W) -> CrcWriter<W> {
167         CrcWriter {
168             inner: w,
169             crc: Crc::new(),
170         }
171     }
172 }
173 
174 impl<W: Write> Write for CrcWriter<W> {
write(&mut self, buf: &[u8]) -> io::Result<usize>175     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
176         let amt = self.inner.write(buf)?;
177         self.crc.update(&buf[..amt]);
178         Ok(amt)
179     }
180 
flush(&mut self) -> io::Result<()>181     fn flush(&mut self) -> io::Result<()> {
182         self.inner.flush()
183     }
184 }
185