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
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
use crate::prelude::*;
#[derive(Debug,Copy,Clone)]
pub struct DigestRead<D: Digest, R: Read> {
d: D,
r: R,
}
impl<D: Digest, R: Read> DigestRead<D, R> {
pub fn new(r: R) -> Self { DigestRead { r, d: D::new() } }
pub fn into_inner(self) -> (D, R) { (self.d, self.r) }
pub fn finish(self) -> digest::Output<D> {
self.d.finalize()
}
}
impl<D: Digest, R: Read> Read for DigestRead<D, R> {
#[throws(io::Error)]
fn read(&mut self, buf: &mut [u8]) -> usize {
let count = self.r.read(buf)?;
self.d.update(&buf[0..count]);
count
}
}
#[test]
#[cfg(not(miri))]
fn test_digest_read() {
let ibuffer = b"abc";
let exp = Sha512_256::digest(&ibuffer[..]);
let inner = &ibuffer[..];
let mut dr = DigestRead::<Sha512_256,_>::new(inner);
let mut obuffer = [0;4];
assert_eq!( dr.read(&mut obuffer).unwrap(), 3 );
assert_eq!( &obuffer, b"abc\0" );
let got = dr.finish();
assert_eq!( got, exp );
}
#[derive(Debug,Copy,Clone)]
pub struct DigestWrite<D: Digest, W: Write> {
d: D,
w: W,
}
impl<D: Digest, W: Write> DigestWrite<D, W> {
pub fn new(w: W) -> Self { DigestWrite { w, d: D::new() } }
pub fn into_inner(self) -> (D, W) { (self.d, self.w) }
pub fn finish(self) -> (digest::Output<D>, W) {
(self.d.finalize(), self.w)
}
}
impl<D: Digest> DigestWrite<D, io::Sink> {
pub fn sink() -> Self { DigestWrite::new(io::sink()) }
#[throws(io::Error)]
pub fn of<R>(r: &mut R) -> digest::Output<D> where R: Read {
let mut dw = DigestWrite::<D,_>::sink();
io::copy(r, &mut dw)?;
dw.finish().0
}
}
impl<D: Digest, W: Write> Write for DigestWrite<D, W> {
#[throws(io::Error)]
fn write(&mut self, buf: &[u8]) -> usize {
let count = self.w.write(buf)?;
self.d.update(&buf[0..count]);
count
}
#[throws(io::Error)]
fn flush(&mut self) { self.w.flush()? }
}