1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
use std::io;
use std::io::prelude::*;
use crc32fast::Hasher;
pub struct Crc32Reader<R>
{
inner: R,
hasher: Hasher,
check: u32,
}
impl<R> Crc32Reader<R>
{
pub fn new(inner: R, checksum: u32) -> Crc32Reader<R>
{
Crc32Reader
{
inner: inner,
hasher: Hasher::new(),
check: checksum,
}
}
fn check_matches(&self) -> bool
{
self.check == self.hasher.clone().finalize()
}
pub fn into_inner(self) -> R {
self.inner
}
}
impl<R: Read> Read for Crc32Reader<R>
{
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize>
{
let count = match self.inner.read(buf)
{
Ok(0) if !self.check_matches() => { return Err(io::Error::new(io::ErrorKind::Other, "Invalid checksum")) },
Ok(n) => n,
Err(e) => return Err(e),
};
self.hasher.update(&buf[0..count]);
Ok(count)
}
}