use crate::compression::{
CodecImplementation, CompressionCodec, CompressionCodecType, DecompressResult,
};
use crate::header::CodecType;
use crate::Error;
#[cfg(not(feature = "fast_zstd"))]
pub struct ZstdCodec {
decoder: ruzstd::decoding::FrameDecoder,
}
#[cfg(feature = "fast_zstd")]
pub struct ZstdCodec {
zstd_context: zstd_safe::DCtx<'static>,
}
#[cfg(not(feature = "fast_zstd"))]
impl CodecImplementation for ZstdCodec {
fn new(_hunk_size: u32) -> crate::Result<Self>
where
Self: Sized,
{
Ok(Self {
decoder: ruzstd::decoding::FrameDecoder::new(),
})
}
fn decompress(
&mut self,
mut input: &[u8],
output: &mut [u8],
) -> crate::Result<DecompressResult> {
let bytes_out = self
.decoder
.decode_all(&mut input, output)
.map_err(|e| Error::DecompressionError)?;
if bytes_out != output.len() {
return Err(Error::DecompressionError);
}
Ok(DecompressResult {
bytes_out,
bytes_read: self.decoder.bytes_read_from_source() as usize,
})
}
}
#[cfg(feature = "fast_zstd")]
impl CodecImplementation for ZstdCodec {
fn new(_hunk_size: u32) -> crate::Result<Self>
where
Self: Sized,
{
Ok(Self {
zstd_context: zstd_safe::DCtx::try_create().ok_or(crate::Error::CodecError)?,
})
}
fn decompress(&mut self, input: &[u8], output: &mut [u8]) -> crate::Result<DecompressResult> {
self.zstd_context
.reset(zstd_safe::ResetDirective::SessionAndParameters)
.map_err(|_| Error::DecompressionError)?;
let bytes_out = self
.zstd_context
.decompress(output, input)
.map_err(|_| Error::DecompressionError)?;
if bytes_out != output.len() {
return Err(Error::DecompressionError);
}
Ok(DecompressResult {
bytes_out: output.len(),
bytes_read: input.len(),
})
}
}
impl CompressionCodecType for ZstdCodec {
fn codec_type(&self) -> CodecType
where
Self: Sized,
{
CodecType::ZstdV5
}
}
impl CompressionCodec for ZstdCodec {}