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(feature = "xz")]
26pub mod xz;
27#[cfg(feature = "lzma")]
28pub mod xz2;
29#[cfg(feature = "zlib")]
30pub mod zlib;
31#[cfg(feature = "zstd")]
32pub mod zstd;
33
34use compression_core::util::{PartialBuffer, WriteBuffer};
35
36#[cfg(feature = "brotli")]
37pub use self::brotli::{BrotliDecoder, BrotliEncoder};
38#[cfg(feature = "bzip2")]
39pub use self::bzip2::{BzDecoder, BzEncoder};
40#[cfg(feature = "deflate")]
41pub use self::deflate::{DeflateDecoder, DeflateEncoder};
42#[cfg(feature = "deflate64")]
43pub use self::deflate64::Deflate64Decoder;
44#[cfg(feature = "flate2")]
45pub use self::flate::{FlateDecoder, FlateEncoder};
46#[cfg(feature = "gzip")]
47pub use self::gzip::{GzipDecoder, GzipEncoder};
48#[cfg(feature = "lz4")]
49pub use self::lz4::{Lz4Decoder, Lz4Encoder};
50#[cfg(feature = "lzma")]
51pub use self::lzma::{LzmaDecoder, LzmaEncoder};
52#[cfg(feature = "xz")]
53pub use self::xz::{XzDecoder, XzEncoder};
54#[cfg(feature = "lzma")]
55pub use self::xz2::{Xz2Decoder, Xz2Encoder, Xz2FileFormat};
56#[cfg(feature = "zlib")]
57pub use self::zlib::{ZlibDecoder, ZlibEncoder};
58#[cfg(feature = "zstd")]
59pub use self::zstd::{ZstdDecoder, ZstdEncoder};
60
61fn forward_output<R>(
62 output: &mut PartialBuffer<impl AsRef<[u8]> + AsMut<[u8]>>,
63 f: impl FnOnce(&mut WriteBuffer<'_>) -> R,
64) -> R {
65 let written_len = output.written_len();
66
67 let output_buffer = output.get_mut();
68 let mut write_buffer = WriteBuffer::new_initialized(output_buffer.as_mut());
69 write_buffer.advance(written_len);
70
71 let result = f(&mut write_buffer);
72 let new_written_len = write_buffer.written_len();
73 output.advance(new_written_len - written_len);
74 result
75}
76
77fn forward_input_output<R>(
78 input: &mut PartialBuffer<impl AsRef<[u8]>>,
79 output: &mut PartialBuffer<impl AsRef<[u8]> + AsMut<[u8]>>,
80 f: impl FnOnce(&mut PartialBuffer<&[u8]>, &mut WriteBuffer<'_>) -> R,
81) -> R {
82 let written_len = input.written_len();
83
84 let input_buffer = input.get_mut();
85 let mut partial_buffer = PartialBuffer::new(input_buffer.as_ref());
86 partial_buffer.advance(written_len);
87
88 let result = forward_output(output, |output| f(&mut partial_buffer, output));
89 let new_written_len = partial_buffer.written_len();
90 input.advance(new_written_len - written_len);
91 result
92}
93
94pub trait Encode {
95 fn encode(
96 &mut self,
97 input: &mut PartialBuffer<impl AsRef<[u8]>>,
98 output: &mut PartialBuffer<impl AsRef<[u8]> + AsMut<[u8]>>,
99 ) -> Result<()>;
100
101 fn flush(&mut self, output: &mut PartialBuffer<impl AsRef<[u8]> + AsMut<[u8]>>)
103 -> Result<bool>;
104
105 fn finish(
107 &mut self,
108 output: &mut PartialBuffer<impl AsRef<[u8]> + AsMut<[u8]>>,
109 ) -> Result<bool>;
110}
111impl<T: EncodeV2 + ?Sized> Encode for T {
112 fn encode(
113 &mut self,
114 input: &mut PartialBuffer<impl AsRef<[u8]>>,
115 output: &mut PartialBuffer<impl AsRef<[u8]> + AsMut<[u8]>>,
116 ) -> Result<()> {
117 forward_input_output(input, output, |input, output| {
118 EncodeV2::encode(self, input, output)
119 })
120 }
121
122 fn flush(
123 &mut self,
124 output: &mut PartialBuffer<impl AsRef<[u8]> + AsMut<[u8]>>,
125 ) -> Result<bool> {
126 forward_output(output, |output| EncodeV2::flush(self, output))
127 }
128
129 fn finish(
130 &mut self,
131 output: &mut PartialBuffer<impl AsRef<[u8]> + AsMut<[u8]>>,
132 ) -> Result<bool> {
133 forward_output(output, |output| EncodeV2::finish(self, output))
134 }
135}
136
137pub trait EncodeV2 {
143 fn encode(
144 &mut self,
145 input: &mut PartialBuffer<&[u8]>,
146 output: &mut WriteBuffer<'_>,
147 ) -> Result<()>;
148
149 fn flush(&mut self, output: &mut WriteBuffer<'_>) -> Result<bool>;
151
152 fn finish(&mut self, output: &mut WriteBuffer<'_>) -> Result<bool>;
154}
155
156pub trait Decode {
157 fn reinit(&mut self) -> Result<()>;
159
160 fn decode(
162 &mut self,
163 input: &mut PartialBuffer<impl AsRef<[u8]>>,
164 output: &mut PartialBuffer<impl AsRef<[u8]> + AsMut<[u8]>>,
165 ) -> Result<bool>;
166
167 fn flush(&mut self, output: &mut PartialBuffer<impl AsRef<[u8]> + AsMut<[u8]>>)
169 -> Result<bool>;
170
171 fn finish(
173 &mut self,
174 output: &mut PartialBuffer<impl AsRef<[u8]> + AsMut<[u8]>>,
175 ) -> Result<bool>;
176}
177
178impl<T: DecodeV2 + ?Sized> Decode for T {
179 fn reinit(&mut self) -> Result<()> {
180 DecodeV2::reinit(self)
181 }
182
183 fn decode(
184 &mut self,
185 input: &mut PartialBuffer<impl AsRef<[u8]>>,
186 output: &mut PartialBuffer<impl AsRef<[u8]> + AsMut<[u8]>>,
187 ) -> Result<bool> {
188 forward_input_output(input, output, |input, output| {
189 DecodeV2::decode(self, input, output)
190 })
191 }
192
193 fn flush(
194 &mut self,
195 output: &mut PartialBuffer<impl AsRef<[u8]> + AsMut<[u8]>>,
196 ) -> Result<bool> {
197 forward_output(output, |output| DecodeV2::flush(self, output))
198 }
199
200 fn finish(
201 &mut self,
202 output: &mut PartialBuffer<impl AsRef<[u8]> + AsMut<[u8]>>,
203 ) -> Result<bool> {
204 forward_output(output, |output| DecodeV2::finish(self, output))
205 }
206}
207
208pub trait DecodeV2 {
214 fn reinit(&mut self) -> Result<()>;
216
217 fn decode(
219 &mut self,
220 input: &mut PartialBuffer<&[u8]>,
221 output: &mut WriteBuffer<'_>,
222 ) -> Result<bool>;
223
224 fn flush(&mut self, output: &mut WriteBuffer<'_>) -> Result<bool>;
226
227 fn finish(&mut self, output: &mut WriteBuffer<'_>) -> Result<bool>;
229}
230
231pub trait DecodedSize {
232 fn decoded_size(input: &[u8]) -> Result<u64>;
234}