summaryrefslogtreecommitdiffstats
path: root/openpgp/src/serialize/stream/writer/writer_deflate.rs
diff options
context:
space:
mode:
Diffstat (limited to 'openpgp/src/serialize/stream/writer/writer_deflate.rs')
-rw-r--r--openpgp/src/serialize/stream/writer/writer_deflate.rs142
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
+ }
+}