async_compression_issue_150_workaround/codec/xz2/
encoder.rs1use crate::codec::Xz2FileFormat;
2use crate::{codec::Encode, util::PartialBuffer};
3
4use std::fmt::{Debug, Formatter, Result as FmtResult};
5use std::io::Result;
6use xz2::stream::{Action, Check, LzmaOptions, Status, Stream};
7
8pub struct Xz2Encoder {
9 stream: Stream,
10}
11
12impl Debug for Xz2Encoder {
13 fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
14 write!(f, "Xz2Encoder")
15 }
16}
17
18impl Xz2Encoder {
19 pub fn new(format: Xz2FileFormat, level: u32) -> Self {
20 let stream = match format {
21 Xz2FileFormat::Xz => Stream::new_easy_encoder(level, Check::Crc64).unwrap(),
22 Xz2FileFormat::Lzma => {
23 Stream::new_lzma_encoder(&LzmaOptions::new_preset(level).unwrap()).unwrap()
24 }
25 };
26
27 Self { stream }
28 }
29}
30
31impl Encode for Xz2Encoder {
32 fn encode(
33 &mut self,
34 input: &mut PartialBuffer<impl AsRef<[u8]>>,
35 output: &mut PartialBuffer<impl AsRef<[u8]> + AsMut<[u8]>>,
36 ) -> Result<()> {
37 let previous_in = self.stream.total_in() as usize;
38 let previous_out = self.stream.total_out() as usize;
39
40 let status = self
41 .stream
42 .process(input.unwritten(), output.unwritten_mut(), Action::Run)?;
43
44 input.advance(self.stream.total_in() as usize - previous_in);
45 output.advance(self.stream.total_out() as usize - previous_out);
46
47 match status {
48 Status::Ok | Status::StreamEnd => Ok(()),
49 Status::GetCheck => panic!("Unexpected lzma integrity check"),
50 Status::MemNeeded => Err(std::io::Error::new(
51 std::io::ErrorKind::Other,
52 "out of memory",
53 )),
54 }
55 }
56
57 fn flush(
58 &mut self,
59 output: &mut PartialBuffer<impl AsRef<[u8]> + AsMut<[u8]>>,
60 ) -> Result<bool> {
61 let previous_out = self.stream.total_out() as usize;
62
63 let status = self
64 .stream
65 .process(&[], output.unwritten_mut(), Action::SyncFlush)?;
66
67 output.advance(self.stream.total_out() as usize - previous_out);
68
69 match status {
70 Status::Ok => Ok(false),
71 Status::StreamEnd => Ok(true),
72 Status::GetCheck => panic!("Unexpected lzma integrity check"),
73 Status::MemNeeded => Err(std::io::Error::new(
74 std::io::ErrorKind::Other,
75 "out of memory",
76 )),
77 }
78 }
79
80 fn finish(
81 &mut self,
82 output: &mut PartialBuffer<impl AsRef<[u8]> + AsMut<[u8]>>,
83 ) -> Result<bool> {
84 let previous_out = self.stream.total_out() as usize;
85
86 let status = self
87 .stream
88 .process(&[], output.unwritten_mut(), Action::Finish)?;
89
90 output.advance(self.stream.total_out() as usize - previous_out);
91
92 match status {
93 Status::Ok => Ok(false),
94 Status::StreamEnd => Ok(true),
95 Status::GetCheck => panic!("Unexpected lzma integrity check"),
96 Status::MemNeeded => Err(std::io::Error::new(
97 std::io::ErrorKind::Other,
98 "out of memory",
99 )),
100 }
101 }
102}