libsignal_service/
digeststream.rs

1use std::io::{self, Read, Seek, SeekFrom};
2
3use sha2::{Digest, Sha256};
4
5pub struct DigestingReader<'r, R> {
6    inner: &'r mut R,
7    digest: Sha256,
8}
9
10impl<R: Read + Seek> Read for DigestingReader<'_, R> {
11    fn read(&mut self, tgt: &mut [u8]) -> Result<usize, std::io::Error> {
12        let amount = self.inner.read(tgt)?;
13        self.digest.update(&tgt[..amount]);
14        Ok(amount)
15    }
16}
17
18impl<'r, R: Read + Seek> DigestingReader<'r, R> {
19    pub fn new(inner: &'r mut R) -> Self {
20        Self {
21            inner,
22            digest: Sha256::new(),
23        }
24    }
25
26    pub fn seek(&mut self, from: SeekFrom) -> io::Result<u64> {
27        self.inner.seek(from)
28    }
29
30    pub fn finalize(self) -> Vec<u8> {
31        // XXX representation is not ideal, but this leaks to the public interface and I don't
32        // really like exposing the GenericArray.
33        Vec::from(self.digest.finalize().as_slice())
34    }
35}