summaryrefslogtreecommitdiffstats
path: root/third_party/rust/flate2/src/ffi/rust.rs
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/rust/flate2/src/ffi/rust.rs')
-rw-r--r--third_party/rust/flate2/src/ffi/rust.rs183
1 files changed, 183 insertions, 0 deletions
diff --git a/third_party/rust/flate2/src/ffi/rust.rs b/third_party/rust/flate2/src/ffi/rust.rs
new file mode 100644
index 0000000000..eadd6ec187
--- /dev/null
+++ b/third_party/rust/flate2/src/ffi/rust.rs
@@ -0,0 +1,183 @@
+//! Implementation for miniz_oxide rust backend.
+
+use std::convert::TryInto;
+use std::fmt;
+
+use miniz_oxide::deflate::core::CompressorOxide;
+use miniz_oxide::inflate::stream::InflateState;
+pub use miniz_oxide::*;
+
+pub const MZ_NO_FLUSH: isize = MZFlush::None as isize;
+pub const MZ_PARTIAL_FLUSH: isize = MZFlush::Partial as isize;
+pub const MZ_SYNC_FLUSH: isize = MZFlush::Sync as isize;
+pub const MZ_FULL_FLUSH: isize = MZFlush::Full as isize;
+pub const MZ_FINISH: isize = MZFlush::Finish as isize;
+
+use super::*;
+use crate::mem;
+
+// miniz_oxide doesn't provide any error messages (yet?)
+#[derive(Default)]
+pub struct ErrorMessage;
+
+impl ErrorMessage {
+ pub fn get(&self) -> Option<&str> {
+ None
+ }
+}
+
+fn format_from_bool(zlib_header: bool) -> DataFormat {
+ if zlib_header {
+ DataFormat::Zlib
+ } else {
+ DataFormat::Raw
+ }
+}
+
+pub struct Inflate {
+ inner: Box<InflateState>,
+ total_in: u64,
+ total_out: u64,
+}
+
+impl fmt::Debug for Inflate {
+ fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
+ write!(
+ f,
+ "miniz_oxide inflate internal state. total_in: {}, total_out: {}",
+ self.total_in, self.total_out,
+ )
+ }
+}
+
+impl InflateBackend for Inflate {
+ fn make(zlib_header: bool, _window_bits: u8) -> Self {
+ let format = format_from_bool(zlib_header);
+
+ Inflate {
+ inner: InflateState::new_boxed(format),
+ total_in: 0,
+ total_out: 0,
+ }
+ }
+
+ fn decompress(
+ &mut self,
+ input: &[u8],
+ output: &mut [u8],
+ flush: FlushDecompress,
+ ) -> Result<Status, DecompressError> {
+ let flush = MZFlush::new(flush as i32).unwrap();
+
+ let res = inflate::stream::inflate(&mut self.inner, input, output, flush);
+ self.total_in += res.bytes_consumed as u64;
+ self.total_out += res.bytes_written as u64;
+
+ match res.status {
+ Ok(status) => match status {
+ MZStatus::Ok => Ok(Status::Ok),
+ MZStatus::StreamEnd => Ok(Status::StreamEnd),
+ MZStatus::NeedDict => {
+ mem::decompress_need_dict(self.inner.decompressor().adler32().unwrap_or(0))
+ }
+ },
+ Err(status) => match status {
+ MZError::Buf => Ok(Status::BufError),
+ _ => mem::decompress_failed(ErrorMessage),
+ },
+ }
+ }
+
+ fn reset(&mut self, zlib_header: bool) {
+ self.inner.reset(format_from_bool(zlib_header));
+ self.total_in = 0;
+ self.total_out = 0;
+ }
+}
+
+impl Backend for Inflate {
+ #[inline]
+ fn total_in(&self) -> u64 {
+ self.total_in
+ }
+
+ #[inline]
+ fn total_out(&self) -> u64 {
+ self.total_out
+ }
+}
+
+pub struct Deflate {
+ inner: Box<CompressorOxide>,
+ total_in: u64,
+ total_out: u64,
+}
+
+impl fmt::Debug for Deflate {
+ fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
+ write!(
+ f,
+ "miniz_oxide deflate internal state. total_in: {}, total_out: {}",
+ self.total_in, self.total_out,
+ )
+ }
+}
+
+impl DeflateBackend for Deflate {
+ fn make(level: Compression, zlib_header: bool, _window_bits: u8) -> Self {
+ // Check in case the integer value changes at some point.
+ debug_assert!(level.level() <= 10);
+
+ let mut inner: Box<CompressorOxide> = Box::default();
+ let format = format_from_bool(zlib_header);
+ inner.set_format_and_level(format, level.level().try_into().unwrap_or(1));
+
+ Deflate {
+ inner,
+ total_in: 0,
+ total_out: 0,
+ }
+ }
+
+ fn compress(
+ &mut self,
+ input: &[u8],
+ output: &mut [u8],
+ flush: FlushCompress,
+ ) -> Result<Status, CompressError> {
+ let flush = MZFlush::new(flush as i32).unwrap();
+ let res = deflate::stream::deflate(&mut self.inner, input, output, flush);
+ self.total_in += res.bytes_consumed as u64;
+ self.total_out += res.bytes_written as u64;
+
+ match res.status {
+ Ok(status) => match status {
+ MZStatus::Ok => Ok(Status::Ok),
+ MZStatus::StreamEnd => Ok(Status::StreamEnd),
+ MZStatus::NeedDict => mem::compress_failed(ErrorMessage),
+ },
+ Err(status) => match status {
+ MZError::Buf => Ok(Status::BufError),
+ _ => mem::compress_failed(ErrorMessage),
+ },
+ }
+ }
+
+ fn reset(&mut self) {
+ self.total_in = 0;
+ self.total_out = 0;
+ self.inner.reset();
+ }
+}
+
+impl Backend for Deflate {
+ #[inline]
+ fn total_in(&self) -> u64 {
+ self.total_in
+ }
+
+ #[inline]
+ fn total_out(&self) -> u64 {
+ self.total_out
+ }
+}