#![cfg_attr(docsrs, feature(doc_cfg))]
use std::io::Result;
pub use compression_core as core;
#[cfg(feature = "brotli")]
pub mod brotli;
#[cfg(feature = "bzip2")]
pub mod bzip2;
#[cfg(feature = "deflate")]
pub mod deflate;
#[cfg(feature = "deflate64")]
pub mod deflate64;
#[cfg(feature = "flate2")]
pub mod flate;
#[cfg(feature = "gzip")]
pub mod gzip;
#[cfg(feature = "lz4")]
pub mod lz4;
#[cfg(feature = "lzma")]
pub mod lzma;
#[cfg(feature = "xz")]
pub mod xz;
#[cfg(feature = "lzma")]
pub mod xz2;
#[cfg(feature = "zlib")]
pub mod zlib;
#[cfg(feature = "zstd")]
pub mod zstd;
use compression_core::util::{PartialBuffer, WriteBuffer};
#[cfg(feature = "brotli")]
pub use self::brotli::{BrotliDecoder, BrotliEncoder};
#[cfg(feature = "bzip2")]
pub use self::bzip2::{BzDecoder, BzEncoder};
#[cfg(feature = "deflate")]
pub use self::deflate::{DeflateDecoder, DeflateEncoder};
#[cfg(feature = "deflate64")]
pub use self::deflate64::Deflate64Decoder;
#[cfg(feature = "flate2")]
pub use self::flate::{FlateDecoder, FlateEncoder};
#[cfg(feature = "gzip")]
pub use self::gzip::{GzipDecoder, GzipEncoder};
#[cfg(feature = "lz4")]
pub use self::lz4::{Lz4Decoder, Lz4Encoder};
#[cfg(feature = "lzma")]
pub use self::lzma::{LzmaDecoder, LzmaEncoder};
#[cfg(feature = "xz")]
pub use self::xz::{XzDecoder, XzEncoder};
#[cfg(feature = "lzma")]
pub use self::xz2::{Xz2Decoder, Xz2Encoder, Xz2FileFormat};
#[cfg(feature = "zlib")]
pub use self::zlib::{ZlibDecoder, ZlibEncoder};
#[cfg(feature = "zstd")]
pub use self::zstd::{ZstdDecoder, ZstdEncoder};
fn forward_output<R>(
output: &mut PartialBuffer<impl AsRef<[u8]> + AsMut<[u8]>>,
f: impl FnOnce(&mut WriteBuffer<'_>) -> R,
) -> R {
let written_len = output.written_len();
let output_buffer = output.get_mut();
let mut write_buffer = WriteBuffer::new_initialized(output_buffer.as_mut());
write_buffer.advance(written_len);
let result = f(&mut write_buffer);
let new_written_len = write_buffer.written_len();
output.advance(new_written_len - written_len);
result
}
fn forward_input_output<R>(
input: &mut PartialBuffer<impl AsRef<[u8]>>,
output: &mut PartialBuffer<impl AsRef<[u8]> + AsMut<[u8]>>,
f: impl FnOnce(&mut PartialBuffer<&[u8]>, &mut WriteBuffer<'_>) -> R,
) -> R {
let written_len = input.written_len();
let input_buffer = input.get_mut();
let mut partial_buffer = PartialBuffer::new(input_buffer.as_ref());
partial_buffer.advance(written_len);
let result = forward_output(output, |output| f(&mut partial_buffer, output));
let new_written_len = partial_buffer.written_len();
input.advance(new_written_len - written_len);
result
}
pub trait Encode {
fn encode(
&mut self,
input: &mut PartialBuffer<impl AsRef<[u8]>>,
output: &mut PartialBuffer<impl AsRef<[u8]> + AsMut<[u8]>>,
) -> Result<()>;
fn flush(&mut self, output: &mut PartialBuffer<impl AsRef<[u8]> + AsMut<[u8]>>)
-> Result<bool>;
fn finish(
&mut self,
output: &mut PartialBuffer<impl AsRef<[u8]> + AsMut<[u8]>>,
) -> Result<bool>;
}
impl<T: EncodeV2 + ?Sized> Encode for T {
fn encode(
&mut self,
input: &mut PartialBuffer<impl AsRef<[u8]>>,
output: &mut PartialBuffer<impl AsRef<[u8]> + AsMut<[u8]>>,
) -> Result<()> {
forward_input_output(input, output, |input, output| {
EncodeV2::encode(self, input, output)
})
}
fn flush(
&mut self,
output: &mut PartialBuffer<impl AsRef<[u8]> + AsMut<[u8]>>,
) -> Result<bool> {
forward_output(output, |output| EncodeV2::flush(self, output))
}
fn finish(
&mut self,
output: &mut PartialBuffer<impl AsRef<[u8]> + AsMut<[u8]>>,
) -> Result<bool> {
forward_output(output, |output| EncodeV2::finish(self, output))
}
}
pub trait EncodeV2 {
fn encode(
&mut self,
input: &mut PartialBuffer<&[u8]>,
output: &mut WriteBuffer<'_>,
) -> Result<()>;
fn flush(&mut self, output: &mut WriteBuffer<'_>) -> Result<bool>;
fn finish(&mut self, output: &mut WriteBuffer<'_>) -> Result<bool>;
}
pub trait Decode {
fn reinit(&mut self) -> Result<()>;
fn decode(
&mut self,
input: &mut PartialBuffer<impl AsRef<[u8]>>,
output: &mut PartialBuffer<impl AsRef<[u8]> + AsMut<[u8]>>,
) -> Result<bool>;
fn flush(&mut self, output: &mut PartialBuffer<impl AsRef<[u8]> + AsMut<[u8]>>)
-> Result<bool>;
fn finish(
&mut self,
output: &mut PartialBuffer<impl AsRef<[u8]> + AsMut<[u8]>>,
) -> Result<bool>;
}
impl<T: DecodeV2 + ?Sized> Decode for T {
fn reinit(&mut self) -> Result<()> {
DecodeV2::reinit(self)
}
fn decode(
&mut self,
input: &mut PartialBuffer<impl AsRef<[u8]>>,
output: &mut PartialBuffer<impl AsRef<[u8]> + AsMut<[u8]>>,
) -> Result<bool> {
forward_input_output(input, output, |input, output| {
DecodeV2::decode(self, input, output)
})
}
fn flush(
&mut self,
output: &mut PartialBuffer<impl AsRef<[u8]> + AsMut<[u8]>>,
) -> Result<bool> {
forward_output(output, |output| DecodeV2::flush(self, output))
}
fn finish(
&mut self,
output: &mut PartialBuffer<impl AsRef<[u8]> + AsMut<[u8]>>,
) -> Result<bool> {
forward_output(output, |output| DecodeV2::finish(self, output))
}
}
pub trait DecodeV2 {
fn reinit(&mut self) -> Result<()>;
fn decode(
&mut self,
input: &mut PartialBuffer<&[u8]>,
output: &mut WriteBuffer<'_>,
) -> Result<bool>;
fn flush(&mut self, output: &mut WriteBuffer<'_>) -> Result<bool>;
fn finish(&mut self, output: &mut WriteBuffer<'_>) -> Result<bool>;
}
pub trait DecodedSize {
fn decoded_size(input: &[u8]) -> Result<u64>;
}