5 use super::CryptConfig
;
6 use crate::tools
::borrow
::Tied
;
8 pub struct ChecksumReader
<R
> {
10 hasher
: crc32fast
::Hasher
,
11 signer
: Option
<Tied
<Arc
<CryptConfig
>, openssl
::sign
::Signer
<'
static>>>,
14 impl <R
: Read
> ChecksumReader
<R
> {
16 pub fn new(reader
: R
, config
: Option
<Arc
<CryptConfig
>>) -> Self {
17 let hasher
= crc32fast
::Hasher
::new();
18 let signer
= match config
{
20 let tied_signer
= Tied
::new(config
, |config
| {
21 Box
::new(unsafe { (*config).data_signer() }
)
28 Self { reader, hasher, signer }
31 pub fn finish(mut self) -> Result
<(R
, u32, Option
<[u8; 32]>), Error
> {
32 let crc
= self.hasher
.finalize();
34 if let Some(ref mut signer
) = self.signer
{
35 let mut tag
= [0u8; 32];
36 signer
.sign(&mut tag
)?
;
37 Ok((self.reader
, crc
, Some(tag
)))
39 Ok((self.reader
, crc
, None
))
44 impl <R
: Read
> Read
for ChecksumReader
<R
> {
46 fn read(&mut self, buf
: &mut [u8]) -> Result
<usize, std
::io
::Error
> {
47 let count
= self.reader
.read(buf
)?
;
49 self.hasher
.update(&buf
[..count
]);
50 if let Some(ref mut signer
) = self.signer
{
51 signer
.update(&buf
[..count
])
54 std
::io
::ErrorKind
::Other
,
55 format
!("hmac update failed - {}", err
))