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