Skip to main content

compression_codecs/
lib.rs

1//! Adaptors for various compression algorithms.
2
3#![cfg_attr(docsrs, feature(doc_cfg))]
4
5use std::io::Result;
6
7pub use compression_core as core;
8
9#[cfg(feature = "brotli")]
10pub mod brotli;
11#[cfg(feature = "bzip2")]
12pub mod bzip2;
13#[cfg(feature = "deflate")]
14pub mod deflate;
15#[cfg(feature = "deflate64")]
16pub mod deflate64;
17#[cfg(feature = "flate2")]
18pub mod flate;
19#[cfg(feature = "gzip")]
20pub mod gzip;
21#[cfg(feature = "lz4")]
22pub mod lz4;
23#[cfg(feature = "lzma")]
24pub mod lzma;
25#[cfg(all(feature = "brotli-mbrotli", async_compression_unstable))]
26pub mod mbrotli;
27#[cfg(feature = "xz")]
28pub mod xz;
29#[cfg(feature = "lzma")]
30pub mod xz2;
31#[cfg(feature = "zlib")]
32pub mod zlib;
33#[cfg(feature = "zstd")]
34pub mod zstd;
35
36use compression_core::util::{PartialBuffer, WriteBuffer};
37
38#[cfg(feature = "brotli")]
39pub use self::brotli::{BrotliDecoder, BrotliEncoder};
40#[cfg(feature = "bzip2")]
41pub use self::bzip2::{BzDecoder, BzEncoder};
42#[cfg(feature = "deflate")]
43pub use self::deflate::{DeflateDecoder, DeflateEncoder};
44#[cfg(feature = "deflate64")]
45pub use self::deflate64::Deflate64Decoder;
46#[cfg(feature = "flate2")]
47pub use self::flate::{FlateDecoder, FlateEncoder};
48#[cfg(feature = "gzip")]
49pub use self::gzip::{GzipDecoder, GzipEncoder};
50#[cfg(feature = "lz4")]
51pub use self::lz4::{Lz4Decoder, Lz4Encoder};
52#[cfg(feature = "lzma")]
53pub use self::lzma::{LzmaDecoder, LzmaEncoder};
54#[cfg(all(feature = "brotli-mbrotli", async_compression_unstable))]
55pub use self::mbrotli::{MbrotliDecoder, MbrotliEncoder};
56#[cfg(feature = "xz")]
57pub use self::xz::{XzDecoder, XzEncoder};
58#[cfg(feature = "lzma")]
59pub use self::xz2::{Xz2Decoder, Xz2Encoder, Xz2FileFormat};
60#[cfg(feature = "zlib")]
61pub use self::zlib::{ZlibDecoder, ZlibEncoder};
62#[cfg(feature = "zstd")]
63pub use self::zstd::{ZstdDecoder, ZstdEncoder};
64
65fn forward_output<R>(
66    output: &mut PartialBuffer<impl AsRef<[u8]> + AsMut<[u8]>>,
67    f: impl FnOnce(&mut WriteBuffer<'_>) -> R,
68) -> R {
69    let written_len = output.written_len();
70
71    let output_buffer = output.get_mut();
72    let mut write_buffer = WriteBuffer::new_initialized(output_buffer.as_mut());
73    write_buffer.advance(written_len);
74
75    let result = f(&mut write_buffer);
76    let new_written_len = write_buffer.written_len();
77    output.advance(new_written_len - written_len);
78    result
79}
80
81fn forward_input_output<R>(
82    input: &mut PartialBuffer<impl AsRef<[u8]>>,
83    output: &mut PartialBuffer<impl AsRef<[u8]> + AsMut<[u8]>>,
84    f: impl FnOnce(&mut PartialBuffer<&[u8]>, &mut WriteBuffer<'_>) -> R,
85) -> R {
86    let written_len = input.written_len();
87
88    let input_buffer = input.get_mut();
89    let mut partial_buffer = PartialBuffer::new(input_buffer.as_ref());
90    partial_buffer.advance(written_len);
91
92    let result = forward_output(output, |output| f(&mut partial_buffer, output));
93    let new_written_len = partial_buffer.written_len();
94    input.advance(new_written_len - written_len);
95    result
96}
97
98pub trait Encode {
99    fn encode(
100        &mut self,
101        input: &mut PartialBuffer<impl AsRef<[u8]>>,
102        output: &mut PartialBuffer<impl AsRef<[u8]> + AsMut<[u8]>>,
103    ) -> Result<()>;
104
105    /// Returns whether the internal buffers are flushed
106    fn flush(&mut self, output: &mut PartialBuffer<impl AsRef<[u8]> + AsMut<[u8]>>)
107        -> Result<bool>;
108
109    /// Returns whether the internal buffers are flushed and the end of the stream is written
110    fn finish(
111        &mut self,
112        output: &mut PartialBuffer<impl AsRef<[u8]> + AsMut<[u8]>>,
113    ) -> Result<bool>;
114}
115impl<T: EncodeV2 + ?Sized> Encode for T {
116    fn encode(
117        &mut self,
118        input: &mut PartialBuffer<impl AsRef<[u8]>>,
119        output: &mut PartialBuffer<impl AsRef<[u8]> + AsMut<[u8]>>,
120    ) -> Result<()> {
121        forward_input_output(input, output, |input, output| {
122            EncodeV2::encode(self, input, output)
123        })
124    }
125
126    fn flush(
127        &mut self,
128        output: &mut PartialBuffer<impl AsRef<[u8]> + AsMut<[u8]>>,
129    ) -> Result<bool> {
130        forward_output(output, |output| EncodeV2::flush(self, output))
131    }
132
133    fn finish(
134        &mut self,
135        output: &mut PartialBuffer<impl AsRef<[u8]> + AsMut<[u8]>>,
136    ) -> Result<bool> {
137        forward_output(output, |output| EncodeV2::finish(self, output))
138    }
139}
140
141/// version 2 of [`Encode`] that is trait object safe.
142///
143/// The different from [`Encode`] is that:
144///  - It doesn't have any generic in it, so it is trait object safe
145///  - It uses [`WriteBuffer`] for output, which will support uninitialized buffer.
146pub trait EncodeV2 {
147    fn encode(
148        &mut self,
149        input: &mut PartialBuffer<&[u8]>,
150        output: &mut WriteBuffer<'_>,
151    ) -> Result<()>;
152
153    /// Returns whether the internal buffers are flushed
154    fn flush(&mut self, output: &mut WriteBuffer<'_>) -> Result<bool>;
155
156    /// Returns whether the internal buffers are flushed and the end of the stream is written
157    fn finish(&mut self, output: &mut WriteBuffer<'_>) -> Result<bool>;
158}
159
160pub trait Decode {
161    /// Reinitializes this decoder ready to decode a new member/frame of data.
162    fn reinit(&mut self) -> Result<()>;
163
164    /// Returns whether the end of the stream has been read
165    fn decode(
166        &mut self,
167        input: &mut PartialBuffer<impl AsRef<[u8]>>,
168        output: &mut PartialBuffer<impl AsRef<[u8]> + AsMut<[u8]>>,
169    ) -> Result<bool>;
170
171    /// Returns whether the internal buffers are flushed
172    fn flush(&mut self, output: &mut PartialBuffer<impl AsRef<[u8]> + AsMut<[u8]>>)
173        -> Result<bool>;
174
175    /// Returns whether the internal buffers are flushed
176    fn finish(
177        &mut self,
178        output: &mut PartialBuffer<impl AsRef<[u8]> + AsMut<[u8]>>,
179    ) -> Result<bool>;
180}
181
182impl<T: DecodeV2 + ?Sized> Decode for T {
183    fn reinit(&mut self) -> Result<()> {
184        DecodeV2::reinit(self)
185    }
186
187    fn decode(
188        &mut self,
189        input: &mut PartialBuffer<impl AsRef<[u8]>>,
190        output: &mut PartialBuffer<impl AsRef<[u8]> + AsMut<[u8]>>,
191    ) -> Result<bool> {
192        forward_input_output(input, output, |input, output| {
193            DecodeV2::decode(self, input, output)
194        })
195    }
196
197    fn flush(
198        &mut self,
199        output: &mut PartialBuffer<impl AsRef<[u8]> + AsMut<[u8]>>,
200    ) -> Result<bool> {
201        forward_output(output, |output| DecodeV2::flush(self, output))
202    }
203
204    fn finish(
205        &mut self,
206        output: &mut PartialBuffer<impl AsRef<[u8]> + AsMut<[u8]>>,
207    ) -> Result<bool> {
208        forward_output(output, |output| DecodeV2::finish(self, output))
209    }
210}
211
212/// version 2 [`Decode`] that is trait object safe.
213///
214/// The different from [`Decode`] is that:
215///  - It doesn't have any generic in it, so it is trait object safe
216///  - It uses [`WriteBuffer`] for output, which will support uninitialized buffer.
217pub trait DecodeV2 {
218    /// Reinitializes this decoder ready to decode a new member/frame of data.
219    fn reinit(&mut self) -> Result<()>;
220
221    /// Returns whether the end of the stream has been read
222    fn decode(
223        &mut self,
224        input: &mut PartialBuffer<&[u8]>,
225        output: &mut WriteBuffer<'_>,
226    ) -> Result<bool>;
227
228    /// Returns whether the internal buffers are flushed
229    fn flush(&mut self, output: &mut WriteBuffer<'_>) -> Result<bool>;
230
231    /// Returns whether the internal buffers are flushed
232    fn finish(&mut self, output: &mut WriteBuffer<'_>) -> Result<bool>;
233}
234
235pub trait DecodedSize {
236    /// Returns the size of the input when uncompressed.
237    fn decoded_size(input: &[u8]) -> Result<u64>;
238}