Skip to main content

async_compression_issue_150_workaround/codec/zstd/
encoder.rs

1use crate::{codec::Encode, unshared::Unshared, util::PartialBuffer};
2use libzstd::stream::raw::{Encoder, Operation};
3use std::io::Result;
4
5#[derive(Debug)]
6pub struct ZstdEncoder {
7    encoder: Unshared<Encoder<'static>>,
8}
9
10impl ZstdEncoder {
11    pub(crate) fn new(level: i32) -> Self {
12        Self {
13            encoder: Unshared::new(Encoder::new(level).unwrap()),
14        }
15    }
16}
17
18impl Encode for ZstdEncoder {
19    fn encode(
20        &mut self,
21        input: &mut PartialBuffer<impl AsRef<[u8]>>,
22        output: &mut PartialBuffer<impl AsRef<[u8]> + AsMut<[u8]>>,
23    ) -> Result<()> {
24        let status = self
25            .encoder
26            .get_mut()
27            .run_on_buffers(input.unwritten(), output.unwritten_mut())?;
28        input.advance(status.bytes_read);
29        output.advance(status.bytes_written);
30        Ok(())
31    }
32
33    fn flush(
34        &mut self,
35        output: &mut PartialBuffer<impl AsRef<[u8]> + AsMut<[u8]>>,
36    ) -> Result<bool> {
37        let mut out_buf = zstd_safe::OutBuffer::around(output.unwritten_mut());
38        let bytes_left = self.encoder.get_mut().flush(&mut out_buf)?;
39        let len = out_buf.as_slice().len();
40        output.advance(len);
41        Ok(bytes_left == 0)
42    }
43
44    fn finish(
45        &mut self,
46        output: &mut PartialBuffer<impl AsRef<[u8]> + AsMut<[u8]>>,
47    ) -> Result<bool> {
48        let mut out_buf = zstd_safe::OutBuffer::around(output.unwritten_mut());
49        let bytes_left = self.encoder.get_mut().finish(&mut out_buf, true)?;
50        let len = out_buf.as_slice().len();
51        output.advance(len);
52        Ok(bytes_left == 0)
53    }
54}