1use std::io;
4use std::io::prelude::*;
5
6use crc32fast::Hasher;
7
8#[derive(Debug)]
12pub struct Crc {
13 amt: u32,
14 hasher: Hasher,
15}
16
17#[derive(Debug)]
21pub struct CrcReader<R> {
22 inner: R,
23 crc: Crc,
24}
25
26impl Default for Crc {
27 fn default() -> Self {
28 Self::new()
29 }
30}
31
32impl Crc {
33 pub fn new() -> Crc {
35 Crc {
36 amt: 0,
37 hasher: Hasher::new(),
38 }
39 }
40
41 pub fn sum(&self) -> u32 {
43 self.hasher.clone().finalize()
44 }
45
46 pub fn amount(&self) -> u32 {
49 self.amt
50 }
51
52 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 pub fn reset(&mut self) {
60 self.amt = 0;
61 self.hasher.reset();
62 }
63
64 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
71impl<R: Read> CrcReader<R> {
72 pub fn new(r: R) -> CrcReader<R> {
74 CrcReader {
75 inner: r,
76 crc: Crc::new(),
77 }
78 }
79}
80
81impl<R> CrcReader<R> {
82 pub fn crc(&self) -> &Crc {
84 &self.crc
85 }
86
87 pub fn into_inner(self) -> R {
89 self.inner
90 }
91
92 pub fn get_ref(&self) -> &R {
94 &self.inner
95 }
96
97 pub fn get_mut(&mut self) -> &mut R {
99 &mut self.inner
100 }
101
102 pub fn reset(&mut self) {
104 self.crc.reset();
105 }
106}
107
108impl<R: Read> Read for CrcReader<R> {
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
116impl<R: BufRead> BufRead for CrcReader<R> {
117 fn fill_buf(&mut self) -> io::Result<&[u8]> {
118 self.inner.fill_buf()
119 }
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#[derive(Debug)]
132pub struct CrcWriter<W> {
133 inner: W,
134 crc: Crc,
135}
136
137impl<W> CrcWriter<W> {
138 pub fn crc(&self) -> &Crc {
140 &self.crc
141 }
142
143 pub fn into_inner(self) -> W {
145 self.inner
146 }
147
148 pub fn get_ref(&self) -> &W {
150 &self.inner
151 }
152
153 pub fn get_mut(&mut self) -> &mut W {
155 &mut self.inner
156 }
157
158 pub fn reset(&mut self) {
160 self.crc.reset();
161 }
162}
163
164impl<W: Write> CrcWriter<W> {
165 pub fn new(w: W) -> CrcWriter<W> {
167 CrcWriter {
168 inner: w,
169 crc: Crc::new(),
170 }
171 }
172}
173
174impl<W: Write> Write for CrcWriter<W> {
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
181 fn flush(&mut self) -> io::Result<()> {
182 self.inner.flush()
183 }
184}