1 // Copyright 2020-2021 Ian Jackson and contributors to Otter
2 // SPDX-License-Identifier: AGPL-3.0-or-later
3 // There is NO WARRANTY.
7 #[derive(Debug,Copy,Clone)]
8 pub struct DigestRead<D: Digest, R: Read> {
13 impl<D: Digest, R: Read> DigestRead<D, R> {
14 pub fn new(r: R) -> Self { DigestRead { r, d: D::new() } }
15 pub fn into_inner(self) -> (D, R) { (self.d, self.r) }
16 pub fn finish(self) -> digest::Output<D> {
21 impl<D: Digest, R: Read> Read for DigestRead<D, R> {
23 fn read(&mut self, buf: &mut [u8]) -> usize {
24 let count = self.r.read(buf)?;
25 self.d.update(&buf[0..count]);
32 fn test_digest_read() {
34 let exp = Sha512_256::digest(&ibuffer[..]);
35 let inner = &ibuffer[..];
36 let mut dr = DigestRead::<Sha512_256,_>::new(inner);
37 let mut obuffer = [0;4];
38 assert_eq!( dr.read(&mut obuffer).unwrap(), 3 );
39 assert_eq!( &obuffer, b"abc\0" );
40 let got = dr.finish();
41 assert_eq!( got, exp );
44 #[derive(Debug,Copy,Clone)]
45 pub struct DigestWrite<D: Digest, W: Write> {
50 impl<D: Digest, W: Write> DigestWrite<D, W> {
51 pub fn new(w: W) -> Self { DigestWrite { w, d: D::new() } }
52 pub fn into_inner(self) -> (D, W) { (self.d, self.w) }
53 pub fn finish(self) -> (digest::Output<D>, W) {
54 (self.d.finalize(), self.w)
57 impl<D: Digest> DigestWrite<D, io::Sink> {
58 pub fn sink() -> Self { DigestWrite::new(io::sink()) }
61 pub fn of<R>(r: &mut R) -> digest::Output<D> where R: Read {
62 let mut dw = DigestWrite::<D,_>::sink();
63 io::copy(r, &mut dw)?;
68 impl<D: Digest, W: Write> Write for DigestWrite<D, W> {
70 fn write(&mut self, buf: &[u8]) -> usize {
71 let count = self.w.write(buf)?;
72 self.d.update(&buf[0..count]);
76 fn flush(&mut self) { self.w.flush()? }