From 107b7902e142575ea69ae911f0515838b139426d Mon Sep 17 00:00:00 2001 From: Avril Date: Thu, 12 Aug 2021 00:20:07 +0100 Subject: [PATCH] Source::read(),transform() impl. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixed compilation failure with `reuse-buffer` due to references to inner buffer in non-#cfg"d code. Fortune for chacha20stream's current commit: Future small blessing − 末小吉 --- src/stream.rs | 112 ++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 108 insertions(+), 4 deletions(-) diff --git a/src/stream.rs b/src/stream.rs index 13d7bd4..a5b327f 100644 --- a/src/stream.rs +++ b/src/stream.rs @@ -3,7 +3,7 @@ use super::*; use key::*; -use std::io::{self, Write}; +use std::io::{self, Write, Read}; use std::fmt; use openssl::{ symm::Crypter, @@ -66,9 +66,9 @@ pub struct Sink /// TODO: Document //#[derive(Debug)] -pub struct Source +pub struct Source { - crypter: Crypter, + crypter: Crypter, #[cfg(not(feature="reuse-buffer"))] buffer: BufferVec, // When `reuse-buffer` is enabled, this isn't needed. We re-use the output buffer for the initial read of untransformed data from `stream` and the actual transformation of the read bytes. stream: R @@ -82,10 +82,98 @@ impl fmt::Debug for Sink } } +impl fmt::Debug for Source +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result + { + #[cfg(feature="reuse-buffer")] + return write!(f, "Source({:?}, (unbounded buffer cap))", &self.stream); + #[cfg(not(feature="reuse-buffer"))] + return write!(f, "Source({:?}, ({} buffer cap))", &self.stream, self.buffer.capacity()); + } +} + +impl Source +where R: Read +{ + /// The crypter of this instance + #[inline] pub fn crypter(&self) -> &Crypter + { + &self.crypter + } + + /// The crypter of this instance + #[inline] pub fn crypter_mut(&mut self) -> &mut Crypter + { + &mut self.crypter + } + + /// The inner stream + #[inline] pub fn inner(&self) -> &R + { + &self.stream + } + + /// The inner stream + #[inline] pub fn inner_mut(&mut self) -> &mut R + { + &mut self.stream + } + + #[cfg(not(feature="reuse-buffer"))] + /// Grow the inner buffer to fix this size, if needed. + fn grow_to_fit(&mut self, sz: usize) + { + if sz > self.buffer.len() { + self.buffer.resize(sz, 0); + } + } + + #[cfg(not(feature="reuse-buffer"))] + /// Perform the cipher transform on this input to the inner buffer, returning the number of bytes updated. + fn transform(&mut self, bufsz: usize, output: &mut [u8]) -> Result + { + //self.grow_to_fix(output.len()); + //let bufsz = self.stream.read(&mut self.buffer[..bufsz])?; + let n = self.crypter.update(&self.buffer[..bufsz], &mut output[..])?; + let _f = self.crypter.finalize(&mut output[..n])?; + debug_assert_eq!(_f, 0); + + Ok(n) + /* + if buf.len() > self.buffer.len() { + self.buffer.resize(buf.len(), 0); + } + + let n = self.crypter.update(&buf[..], &mut self.buffer[..])?; + let _f = self.crypter.finalize(&mut self.buffer[..n])?; // I don't know if this is needed. + debug_assert_eq!(_f, 0); + + Ok(n)*/ + } + + #[cfg(not(feature="reuse-buffer"))] + /// Clear the internal buffer while keeping it allocated for further use. + /// + /// This does not affect operations at all, all it does is 0 out the left-over temporary buffer from the last operation(s). + #[inline] + pub fn prune(&mut self) + { + #[cfg(feature="explicit_clear")] + { + bytes::explicit_prune(&mut self.buffer[..]); + return; + } + #[cfg(not(feature="explicit_clear"))] + unsafe { + std::ptr::write_bytes(self.buffer.as_mut_ptr(), 0, self.buffer.len()); + } + } +} + impl Sink where W: Write { - /// The crypter of this instance #[inline] pub fn crypter(&self) -> &Crypter { @@ -179,6 +267,22 @@ where W: Write } + +impl Read for Source +where R: Read +{ + fn read(&mut self, buf: &mut [u8]) -> io::Result { + (#[cfg(feature="reuse-buffer")] { + todo!() + }, + #[cfg(not(feature="reuse-buffer"))] { + self.grow_to_fit(buf.len()); + let read = self.stream.read(&mut self.buffer[..buf.len()])?; + Ok(self.transform(read, &mut buf[..read])?) + },).0 + } +} + impl Write for Sink { #[inline] fn write(&mut self, buf: &[u8]) -> io::Result {