diff options
Diffstat (limited to 'openpgp/src/serialize/stream/writer/writer_deflate.rs')
-rw-r--r-- | openpgp/src/serialize/stream/writer/writer_deflate.rs | 142 |
1 files changed, 142 insertions, 0 deletions
diff --git a/openpgp/src/serialize/stream/writer/writer_deflate.rs b/openpgp/src/serialize/stream/writer/writer_deflate.rs new file mode 100644 index 00000000..387b3f2c --- /dev/null +++ b/openpgp/src/serialize/stream/writer/writer_deflate.rs @@ -0,0 +1,142 @@ +use flate2::write::{DeflateEncoder, ZlibEncoder}; +use std::fmt; +use std::io; + +use crate::Result; +use super::{Generic, Stack, BoxStack, Stackable, CompressionLevel}; + +/// ZIPing writer. +pub struct ZIP<'a, C: 'a> { + inner: Generic<DeflateEncoder<BoxStack<'a, C>>, C>, +} + +impl<'a, C: 'a> ZIP<'a, C> { + /// Makes a ZIP compressing writer. + pub fn new<L>(inner: Stack<'a, C>, cookie: C, level: L) -> Stack<'a, C> + where L: Into<Option<CompressionLevel>> + { + Stack::from(Box::new(ZIP { + inner: Generic::new_unboxed( + DeflateEncoder::new(inner.into(), + level.into().unwrap_or_default().into()), + cookie), + })) + } +} + +impl<'a, C: 'a> fmt::Debug for ZIP<'a, C> { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_struct("writer::ZIP") + .field("inner", &self.inner) + .finish() + } +} + +impl<'a, C: 'a> io::Write for ZIP<'a, C> { + fn write(&mut self, bytes: &[u8]) -> io::Result<usize> { + self.inner.write(bytes) + } + + fn flush(&mut self) -> io::Result<()> { + self.inner.flush() + } +} + +impl<'a, C: 'a> Stackable<'a, C> for ZIP<'a, C> { + fn into_inner(self: Box<Self>) -> Result<Option<BoxStack<'a, C>>> { + let inner = self.inner.inner.finish()?; + Ok(Some(inner)) + } + fn pop(&mut self) -> Result<Option<BoxStack<'a, C>>> { + unreachable!("Only implemented by Signer") + } + fn mount(&mut self, _new: BoxStack<'a, C>) { + unreachable!("Only implemented by Signer") + } + fn inner_mut(&mut self) -> Option<&mut dyn Stackable<'a, C>> { + Some(self.inner.inner.get_mut()) + } + fn inner_ref(&self) -> Option<&dyn Stackable<'a, C>> { + Some(self.inner.inner.get_ref()) + } + fn cookie_set(&mut self, cookie: C) -> C { + self.inner.cookie_set(cookie) + } + fn cookie_ref(&self) -> &C { + self.inner.cookie_ref() + } + fn cookie_mut(&mut self) -> &mut C { + self.inner.cookie_mut() + } + fn position(&self) -> u64 { + self.inner.position + } +} + +/// ZLIBing writer. +pub struct ZLIB<'a, C: 'a> { + inner: Generic<ZlibEncoder<BoxStack<'a, C>>, C>, +} + +impl<'a, C: 'a> ZLIB<'a, C> { + /// Makes a ZLIB compressing writer. + pub fn new<L>(inner: Stack<'a, C>, cookie: C, level: L) -> Stack<'a, C> + where L: Into<Option<CompressionLevel>> + { + Stack::from(Box::new(ZLIB { + inner: Generic::new_unboxed( + ZlibEncoder::new(inner.into(), + level.into().unwrap_or_default().into()), + cookie), + })) + } +} + +impl<'a, C:> fmt::Debug for ZLIB<'a, C> { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_struct("writer::ZLIB") + .field("inner", &self.inner) + .finish() + } +} + +impl<'a, C: 'a> io::Write for ZLIB<'a, C> { + fn write(&mut self, bytes: &[u8]) -> io::Result<usize> { + self.inner.write(bytes) + } + + fn flush(&mut self) -> io::Result<()> { + self.inner.flush() + } +} + +impl<'a, C: 'a> Stackable<'a, C> for ZLIB<'a, C> { + fn into_inner(self: Box<Self>) -> Result<Option<BoxStack<'a, C>>> { + let inner = self.inner.inner.finish()?; + Ok(Some(inner)) + } + fn pop(&mut self) -> Result<Option<BoxStack<'a, C>>> { + unreachable!("Only implemented by Signer") + } + fn mount(&mut self, _new: BoxStack<'a, C>) { + unreachable!("Only implemented by Signer") + } + fn inner_mut(&mut self) -> Option<&mut dyn Stackable<'a, C>> { + Some(self.inner.inner.get_mut()) + } + fn inner_ref(&self) -> Option<&dyn Stackable<'a, C>> { + Some(self.inner.inner.get_ref()) + } + fn cookie_set(&mut self, cookie: C) -> C { + self.inner.cookie_set(cookie) + } + fn cookie_ref(&self) -> &C { + self.inner.cookie_ref() + } + fn cookie_mut(&mut self) -> &mut C { + self.inner.cookie_mut() + } + fn position(&self) -> u64 { + self.inner.position + } +} |