6 use super::CryptConfig
;
7 use crate::tools
::borrow
::Tied
;
9 pub struct ChecksumWriter
<W
> {
11 hasher
: crc32fast
::Hasher
,
12 signer
: Option
<Tied
<Arc
<CryptConfig
>, openssl
::sign
::Signer
<'
static>>>,
15 impl <W
: Write
> ChecksumWriter
<W
> {
17 pub fn new(writer
: W
, config
: Option
<Arc
<CryptConfig
>>) -> Self {
18 let hasher
= crc32fast
::Hasher
::new();
19 let signer
= match config
{
21 let tied_signer
= Tied
::new(config
, |config
| {
22 Box
::new(unsafe { (*config).data_signer() }
)
28 Self { writer, hasher, signer }
31 pub fn finish(mut self) -> Result
<(W
, 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.writer
, crc
, Some(tag
)))
39 Ok((self.writer
, crc
, None
))
44 impl <W
: Write
> Write
for ChecksumWriter
<W
> {
46 fn write(&mut self, buf
: &[u8]) -> Result
<usize, std
::io
::Error
> {
47 self.hasher
.update(buf
);
48 if let Some(ref mut signer
) = self.signer
{
52 std
::io
::ErrorKind
::Other
,
53 format
!("hmac update failed - {}", err
))
56 self.writer
.write(buf
)
59 fn flush(&mut self) -> Result
<(), std
::io
::Error
> {