compression_codecs/
lib.rs1#![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 fn flush(&mut self, output: &mut PartialBuffer<impl AsRef<[u8]> + AsMut<[u8]>>)
107 -> Result<bool>;
108
109 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
141pub trait EncodeV2 {
147 fn encode(
148 &mut self,
149 input: &mut PartialBuffer<&[u8]>,
150 output: &mut WriteBuffer<'_>,
151 ) -> Result<()>;
152
153 fn flush(&mut self, output: &mut WriteBuffer<'_>) -> Result<bool>;
155
156 fn finish(&mut self, output: &mut WriteBuffer<'_>) -> Result<bool>;
158}
159
160pub trait Decode {
161 fn reinit(&mut self) -> Result<()>;
163
164 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 fn flush(&mut self, output: &mut PartialBuffer<impl AsRef<[u8]> + AsMut<[u8]>>)
173 -> Result<bool>;
174
175 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
212pub trait DecodeV2 {
218 fn reinit(&mut self) -> Result<()>;
220
221 fn decode(
223 &mut self,
224 input: &mut PartialBuffer<&[u8]>,
225 output: &mut WriteBuffer<'_>,
226 ) -> Result<bool>;
227
228 fn flush(&mut self, output: &mut WriteBuffer<'_>) -> Result<bool>;
230
231 fn finish(&mut self, output: &mut WriteBuffer<'_>) -> Result<bool>;
233}
234
235pub trait DecodedSize {
236 fn decoded_size(input: &[u8]) -> Result<u64>;
238}