use std::io::{self, BufRead, BufReader, Read};
use crate::dict::{DecoderDictionary, EncoderDictionary};
use crate::stream::{raw, zio};
use zstd_safe;
#[cfg(test)]
mod tests;
pub struct Decoder<'a, R> {
reader: zio::Reader<R, raw::Decoder<'a>>,
}
pub struct Encoder<'a, R> {
reader: zio::Reader<R, raw::Encoder<'a>>,
}
impl<R: Read> Decoder<'static, BufReader<R>> {
pub fn new(reader: R) -> io::Result<Self> {
let buffer_size = zstd_safe::DCtx::in_size();
Self::with_buffer(BufReader::with_capacity(buffer_size, reader))
}
}
impl<R: BufRead> Decoder<'static, R> {
pub fn with_buffer(reader: R) -> io::Result<Self> {
Self::with_dictionary(reader, &[])
}
pub fn with_dictionary(reader: R, dictionary: &[u8]) -> io::Result<Self> {
let decoder = raw::Decoder::with_dictionary(dictionary)?;
let reader = zio::Reader::new(reader, decoder);
Ok(Decoder { reader })
}
}
impl<'a, R: BufRead> Decoder<'a, R> {
pub fn with_context(
reader: R,
context: &'a mut zstd_safe::DCtx<'static>,
) -> Self {
Self {
reader: zio::Reader::new(
reader,
raw::Decoder::with_context(context),
),
}
}
#[must_use]
pub fn single_frame(mut self) -> Self {
self.reader.set_single_frame();
self
}
pub fn with_prepared_dictionary<'b>(
reader: R,
dictionary: &DecoderDictionary<'b>,
) -> io::Result<Self>
where
'b: 'a,
{
let decoder = raw::Decoder::with_prepared_dictionary(dictionary)?;
let reader = zio::Reader::new(reader, decoder);
Ok(Decoder { reader })
}
pub fn with_ref_prefix<'b>(
reader: R,
ref_prefix: &'b [u8],
) -> io::Result<Self>
where
'b: 'a,
{
let decoder = raw::Decoder::with_ref_prefix(ref_prefix)?;
let reader = zio::Reader::new(reader, decoder);
Ok(Decoder { reader })
}
pub fn recommended_output_size() -> usize {
zstd_safe::DCtx::out_size()
}
pub fn get_ref(&self) -> &R {
self.reader.reader()
}
pub fn get_mut(&mut self) -> &mut R {
self.reader.reader_mut()
}
pub fn finish(self) -> R {
self.reader.into_inner()
}
crate::decoder_common!(reader);
}
impl<R: BufRead> Read for Decoder<'_, R> {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
self.reader.read(buf)
}
}
impl<R: Read> Encoder<'static, BufReader<R>> {
pub fn new(reader: R, level: i32) -> io::Result<Self> {
let buffer_size = zstd_safe::CCtx::in_size();
Self::with_buffer(BufReader::with_capacity(buffer_size, reader), level)
}
}
impl<R: BufRead> Encoder<'static, R> {
pub fn with_buffer(reader: R, level: i32) -> io::Result<Self> {
Self::with_dictionary(reader, level, &[])
}
pub fn with_dictionary(
reader: R,
level: i32,
dictionary: &[u8],
) -> io::Result<Self> {
let encoder = raw::Encoder::with_dictionary(level, dictionary)?;
let reader = zio::Reader::new(reader, encoder);
Ok(Encoder { reader })
}
}
impl<'a, R: BufRead> Encoder<'a, R> {
pub fn with_prepared_dictionary<'b>(
reader: R,
dictionary: &EncoderDictionary<'b>,
) -> io::Result<Self>
where
'b: 'a,
{
let encoder = raw::Encoder::with_prepared_dictionary(dictionary)?;
let reader = zio::Reader::new(reader, encoder);
Ok(Encoder { reader })
}
pub fn recommended_output_size() -> usize {
zstd_safe::CCtx::out_size()
}
pub fn get_ref(&self) -> &R {
self.reader.reader()
}
pub fn get_mut(&mut self) -> &mut R {
self.reader.reader_mut()
}
pub fn flush(&mut self, out: &mut [u8]) -> io::Result<usize> {
self.reader.flush(out)
}
pub fn finish(self) -> R {
self.reader.into_inner()
}
crate::encoder_common!(reader);
}
impl<R: BufRead> Read for Encoder<'_, R> {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
self.reader.read(buf)
}
}
fn _assert_traits() {
use std::io::Cursor;
fn _assert_send<T: Send>(_: T) {}
_assert_send(Decoder::new(Cursor::new(Vec::new())));
_assert_send(Encoder::new(Cursor::new(Vec::new()), 1));
}