compression_codecs/zstd/
decoder.rs

1use crate::zstd::params::DParameter;
2use crate::Decode;
3use compression_core::unshared::Unshared;
4use compression_core::util::PartialBuffer;
5use libzstd::stream::raw::{Decoder, Operation};
6use std::io;
7use std::io::Result;
8
9#[derive(Debug)]
10pub struct ZstdDecoder {
11    decoder: Unshared<Decoder<'static>>,
12}
13
14impl Default for ZstdDecoder {
15    fn default() -> Self {
16        Self {
17            decoder: Unshared::new(Decoder::new().unwrap()),
18        }
19    }
20}
21
22impl ZstdDecoder {
23    pub fn new() -> Self {
24        Self::default()
25    }
26
27    pub fn new_with_params(params: &[DParameter]) -> Self {
28        let mut decoder = Decoder::new().unwrap();
29        for param in params {
30            decoder.set_parameter(param.as_zstd()).unwrap();
31        }
32        Self {
33            decoder: Unshared::new(decoder),
34        }
35    }
36
37    pub fn new_with_dict(dictionary: &[u8]) -> io::Result<Self> {
38        let decoder = Decoder::with_dictionary(dictionary)?;
39        Ok(Self {
40            decoder: Unshared::new(decoder),
41        })
42    }
43}
44
45impl Decode for ZstdDecoder {
46    fn reinit(&mut self) -> Result<()> {
47        self.decoder.get_mut().reinit()?;
48        Ok(())
49    }
50
51    fn decode(
52        &mut self,
53        input: &mut PartialBuffer<impl AsRef<[u8]>>,
54        output: &mut PartialBuffer<impl AsRef<[u8]> + AsMut<[u8]>>,
55    ) -> Result<bool> {
56        let status = self
57            .decoder
58            .get_mut()
59            .run_on_buffers(input.unwritten(), output.unwritten_mut())?;
60        input.advance(status.bytes_read);
61        output.advance(status.bytes_written);
62        Ok(status.remaining == 0)
63    }
64
65    fn flush(
66        &mut self,
67        output: &mut PartialBuffer<impl AsRef<[u8]> + AsMut<[u8]>>,
68    ) -> Result<bool> {
69        let mut out_buf = zstd_safe::OutBuffer::around(output.unwritten_mut());
70        let bytes_left = self.decoder.get_mut().flush(&mut out_buf)?;
71        let len = out_buf.as_slice().len();
72        output.advance(len);
73        Ok(bytes_left == 0)
74    }
75
76    fn finish(
77        &mut self,
78        output: &mut PartialBuffer<impl AsRef<[u8]> + AsMut<[u8]>>,
79    ) -> Result<bool> {
80        let mut out_buf = zstd_safe::OutBuffer::around(output.unwritten_mut());
81        let bytes_left = self.decoder.get_mut().finish(&mut out_buf, true)?;
82        let len = out_buf.as_slice().len();
83        output.advance(len);
84        Ok(bytes_left == 0)
85    }
86}