compression_codecs/flate/
decoder.rs1use crate::DecodeV2;
2use compression_core::util::{PartialBuffer, WriteBuffer};
3use flate2::{Decompress, FlushDecompress, Status};
4use std::io;
5
6#[derive(Debug)]
7pub struct FlateDecoder {
8 zlib_header: bool,
9 decompress: Decompress,
10}
11
12impl FlateDecoder {
13 pub(crate) fn new(zlib_header: bool) -> Self {
14 Self {
15 zlib_header,
16 decompress: Decompress::new(zlib_header),
17 }
18 }
19
20 fn decode(
21 &mut self,
22 input: &mut PartialBuffer<&[u8]>,
23 output: &mut WriteBuffer<'_>,
24 flush: FlushDecompress,
25 ) -> io::Result<Status> {
26 let prior_in = self.decompress.total_in();
27 let prior_out = self.decompress.total_out();
28
29 let result =
30 self.decompress
31 .decompress(input.unwritten(), output.initialize_unwritten(), flush);
32
33 input.advance((self.decompress.total_in() - prior_in) as usize);
34 output.advance((self.decompress.total_out() - prior_out) as usize);
35
36 Ok(result?)
37 }
38}
39
40impl DecodeV2 for FlateDecoder {
41 fn reinit(&mut self) -> io::Result<()> {
42 self.decompress.reset(self.zlib_header);
43 Ok(())
44 }
45
46 fn decode(
47 &mut self,
48 input: &mut PartialBuffer<&[u8]>,
49 output: &mut WriteBuffer<'_>,
50 ) -> io::Result<bool> {
51 match self.decode(input, output, FlushDecompress::None)? {
52 Status::Ok => Ok(false),
53 Status::StreamEnd => Ok(true),
54 Status::BufError => Err(io::Error::other("unexpected BufError")),
55 }
56 }
57
58 fn flush(&mut self, output: &mut WriteBuffer<'_>) -> io::Result<bool> {
59 self.decode(
60 &mut PartialBuffer::new(&[][..]),
61 output,
62 FlushDecompress::Sync,
63 )?;
64
65 loop {
66 let old_len = output.written_len();
67 self.decode(
68 &mut PartialBuffer::new(&[][..]),
69 output,
70 FlushDecompress::None,
71 )?;
72 if output.written_len() == old_len {
73 break;
74 }
75 }
76
77 Ok(!output.has_no_spare_space())
78 }
79
80 fn finish(&mut self, output: &mut WriteBuffer<'_>) -> io::Result<bool> {
81 match self.decode(
82 &mut PartialBuffer::new(&[][..]),
83 output,
84 FlushDecompress::Finish,
85 )? {
86 Status::Ok => Ok(false),
87 Status::StreamEnd => Ok(true),
88 Status::BufError => Err(io::Error::other("unexpected BufError")),
89 }
90 }
91}