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 Crc {
27 pub fn new() -> Crc {
29 Crc {
30 amt: 0,
31 hasher: Hasher::new(),
32 }
33 }
34
35 pub fn sum(&self) -> u32 {
37 self.hasher.clone().finalize()
38 }
39
40 pub fn amount(&self) -> u32 {
43 self.amt
44 }
45
46 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 pub fn reset(&mut self) {
54 self.amt = 0;
55 self.hasher.reset();
56 }
57
58 pub fn combine(&mut self, additional_crc: &Crc) {
60 self.amt += additional_crc.amt;
61 self.hasher.combine(&additional_crc.hasher);
62 }
63}
64
65impl<R: Read> CrcReader<R> {
66 pub fn new(r: R) -> CrcReader<R> {
68 CrcReader {
69 inner: r,
70 crc: Crc::new(),
71 }
72 }
73}
74
75impl<R> CrcReader<R> {
76 pub fn crc(&self) -> &Crc {
78 &self.crc
79 }
80
81 pub fn into_inner(self) -> R {
83 self.inner
84 }
85
86 pub fn get_ref(&self) -> &R {
88 &self.inner
89 }
90
91 pub fn get_mut(&mut self) -> &mut R {
93 &mut self.inner
94 }
95
96 pub fn reset(&mut self) {
98 self.crc.reset();
99 }
100}
101
102impl<R: Read> Read for CrcReader<R> {
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
110impl<R: BufRead> BufRead for CrcReader<R> {
111 fn fill_buf(&mut self) -> io::Result<&[u8]> {
112 self.inner.fill_buf()
113 }
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#[derive(Debug)]
126pub struct CrcWriter<W> {
127 inner: W,
128 crc: Crc,
129}
130
131impl<W> CrcWriter<W> {
132 pub fn crc(&self) -> &Crc {
134 &self.crc
135 }
136
137 pub fn into_inner(self) -> W {
139 self.inner
140 }
141
142 pub fn get_ref(&self) -> &W {
144 &self.inner
145 }
146
147 pub fn get_mut(&mut self) -> &mut W {
149 &mut self.inner
150 }
151
152 pub fn reset(&mut self) {
154 self.crc.reset();
155 }
156}
157
158impl<W: Write> CrcWriter<W> {
159 pub fn new(w: W) -> CrcWriter<W> {
161 CrcWriter {
162 inner: w,
163 crc: Crc::new(),
164 }
165 }
166}
167
168impl<W: Write> Write for CrcWriter<W> {
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
175 fn flush(&mut self) -> io::Result<()> {
176 self.inner.flush()
177 }
178}