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