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