compression_codecs/bzip2/
decoder.rs1use crate::Decode;
2use bzip2::{Decompress, Status};
3use compression_core::util::PartialBuffer;
4use std::{fmt, io};
5
6pub struct BzDecoder {
7 decompress: Decompress,
8}
9
10impl fmt::Debug for BzDecoder {
11 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
12 write!(
13 f,
14 "BzDecoder {{total_in: {}, total_out: {}}}",
15 self.decompress.total_in(),
16 self.decompress.total_out()
17 )
18 }
19}
20
21impl Default for BzDecoder {
22 fn default() -> Self {
23 Self {
24 decompress: Decompress::new(false),
25 }
26 }
27}
28
29impl BzDecoder {
30 pub fn new() -> Self {
31 Self::default()
32 }
33
34 fn decode(
35 &mut self,
36 input: &mut PartialBuffer<impl AsRef<[u8]>>,
37 output: &mut PartialBuffer<impl AsRef<[u8]> + AsMut<[u8]>>,
38 ) -> io::Result<Status> {
39 let prior_in = self.decompress.total_in();
40 let prior_out = self.decompress.total_out();
41
42 let status = self
43 .decompress
44 .decompress(input.unwritten(), output.unwritten_mut())
45 .map_err(io::Error::other)?;
46
47 input.advance((self.decompress.total_in() - prior_in) as usize);
48 output.advance((self.decompress.total_out() - prior_out) as usize);
49
50 Ok(status)
51 }
52}
53
54impl Decode for BzDecoder {
55 fn reinit(&mut self) -> io::Result<()> {
56 self.decompress = Decompress::new(false);
57 Ok(())
58 }
59
60 fn decode(
61 &mut self,
62 input: &mut PartialBuffer<impl AsRef<[u8]>>,
63 output: &mut PartialBuffer<impl AsRef<[u8]> + AsMut<[u8]>>,
64 ) -> io::Result<bool> {
65 match self.decode(input, output)? {
66 Status::Ok => Ok(false),
68
69 Status::FlushOk => unreachable!(),
71
72 Status::RunOk => unreachable!(),
74
75 Status::FinishOk => unreachable!(),
77
78 Status::StreamEnd => Ok(true),
80
81 Status::MemNeeded => Err(io::Error::other("out of memory")),
84 }
85 }
86
87 fn flush(
88 &mut self,
89 output: &mut PartialBuffer<impl AsRef<[u8]> + AsMut<[u8]>>,
90 ) -> io::Result<bool> {
91 self.decode(&mut PartialBuffer::new(&[][..]), output)?;
92
93 loop {
94 let old_len = output.written().len();
95 self.decode(&mut PartialBuffer::new(&[][..]), output)?;
96 if output.written().len() == old_len {
97 break;
98 }
99 }
100
101 Ok(!output.unwritten().is_empty())
102 }
103
104 fn finish(
105 &mut self,
106 _output: &mut PartialBuffer<impl AsRef<[u8]> + AsMut<[u8]>>,
107 ) -> io::Result<bool> {
108 Ok(true)
109 }
110}