1- pub use flate2:: { Decompress , Status } ;
1+ use std:: ffi:: c_int;
2+
3+ /// A type to hold all state needed for decompressing a ZLIB encoded stream.
4+ pub struct Decompress ( libz_rs_sys:: z_stream ) ;
5+
6+ unsafe impl Sync for Decompress { }
7+ unsafe impl Send for Decompress { }
8+
9+ impl Default for Decompress {
10+ fn default ( ) -> Self {
11+ Self :: new ( )
12+ }
13+ }
14+
15+ impl Decompress {
16+ /// The amount of bytes consumed from the input so far.
17+ pub fn total_in ( & self ) -> u64 {
18+ self . 0 . total_in as _
19+ }
20+
21+ /// The amount of decompressed bytes that have been written to the output thus far.
22+ pub fn total_out ( & self ) -> u64 {
23+ self . 0 . total_out as _
24+ }
25+
26+ /// Create a new instance. Note that it allocates in various ways and thus should be re-used.
27+ pub fn new ( ) -> Self {
28+ let mut this = libz_rs_sys:: z_stream:: default ( ) ;
29+
30+ unsafe {
31+ libz_rs_sys:: inflateInit_ (
32+ & mut this,
33+ libz_rs_sys:: zlibVersion ( ) ,
34+ core:: mem:: size_of :: < libz_rs_sys:: z_stream > ( ) as core:: ffi:: c_int ,
35+ ) ;
36+ }
37+
38+ Self ( this)
39+ }
40+
41+ /// Reset the state to allow handling a new stream.
42+ pub fn reset ( & mut self ) {
43+ unsafe { libz_rs_sys:: inflateReset ( & mut self . 0 ) } ;
44+ }
45+
46+ /// Decompress `input` and write all decompressed bytes into `output`, with `flush` defining some details about this.
47+ pub fn decompress (
48+ & mut self ,
49+ input : & [ u8 ] ,
50+ output : & mut [ u8 ] ,
51+ flush : FlushDecompress ,
52+ ) -> Result < Status , DecompressError > {
53+ self . 0 . avail_in = input. len ( ) as _ ;
54+ self . 0 . avail_out = output. len ( ) as _ ;
55+
56+ self . 0 . next_in = input. as_ptr ( ) ;
57+ self . 0 . next_out = output. as_mut_ptr ( ) ;
58+
59+ match unsafe { libz_rs_sys:: inflate ( & mut self . 0 , flush as _ ) } {
60+ libz_rs_sys:: Z_OK => Ok ( Status :: Ok ) ,
61+ libz_rs_sys:: Z_BUF_ERROR => Ok ( Status :: BufError ) ,
62+ libz_rs_sys:: Z_STREAM_END => Ok ( Status :: StreamEnd ) ,
63+
64+ libz_rs_sys:: Z_STREAM_ERROR => Err ( DecompressError :: StreamError ) ,
65+ libz_rs_sys:: Z_DATA_ERROR => Err ( DecompressError :: DataError ) ,
66+ libz_rs_sys:: Z_MEM_ERROR => Err ( DecompressError :: InsufficientMemory ) ,
67+ err => Err ( DecompressError :: Unknown { err } ) ,
68+ }
69+ }
70+ }
71+
72+ impl Drop for Decompress {
73+ fn drop ( & mut self ) {
74+ unsafe { libz_rs_sys:: inflateEnd ( & mut self . 0 ) } ;
75+ }
76+ }
77+
78+ /// The error produced by [`Decompress::decompress()`].
79+ #[ derive( Debug , thiserror:: Error ) ]
80+ #[ allow( missing_docs) ]
81+ pub enum DecompressError {
82+ #[ error( "stream error" ) ]
83+ StreamError ,
84+ #[ error( "Not enough memory" ) ]
85+ InsufficientMemory ,
86+ #[ error( "Invalid input data" ) ]
87+ DataError ,
88+ #[ error( "An unknown error occurred: {err}" ) ]
89+ Unknown { err : c_int } ,
90+ }
91+
92+ /// The status returned by [`Decompress::decompress()`].
93+ #[ derive( Debug , Clone , Copy , PartialEq , Eq ) ]
94+ pub enum Status {
95+ /// The decompress operation went well. Not to be confused with `StreamEnd`, so one can continue
96+ /// the decompression.
97+ Ok ,
98+ /// An error occurred when decompression.
99+ BufError ,
100+ /// The stream was fully decompressed.
101+ StreamEnd ,
102+ }
103+
104+ /// Values which indicate the form of flushing to be used when
105+ /// decompressing in-memory data.
106+ #[ derive( Copy , Clone , PartialEq , Eq , Debug ) ]
107+ #[ non_exhaustive]
108+ #[ allow( clippy:: unnecessary_cast) ]
109+ pub enum FlushDecompress {
110+ /// A typical parameter for passing to compression/decompression functions,
111+ /// this indicates that the underlying stream to decide how much data to
112+ /// accumulate before producing output in order to maximize compression.
113+ None = libz_rs_sys:: Z_NO_FLUSH as isize ,
114+
115+ /// All pending output is flushed to the output buffer and the output is
116+ /// aligned on a byte boundary so that the decompressor can get all input
117+ /// data available so far.
118+ ///
119+ /// Flushing may degrade compression for some compression algorithms and so
120+ /// it should only be used when necessary. This will complete the current
121+ /// deflate block and follow it with an empty stored block.
122+ Sync = libz_rs_sys:: Z_SYNC_FLUSH as isize ,
123+
124+ /// Pending input is processed and pending output is flushed.
125+ ///
126+ /// The return value may indicate that the stream is not yet done and more
127+ /// data has yet to be processed.
128+ Finish = libz_rs_sys:: Z_FINISH as isize ,
129+ }
2130
3131/// non-streaming interfaces for decompression
4132pub mod inflate {
@@ -8,33 +136,26 @@ pub mod inflate {
8136 pub enum Error {
9137 #[ error( "Could not write all bytes when decompressing content" ) ]
10138 WriteInflated ( #[ from] std:: io:: Error ) ,
11- #[ error( "Could not decode zip stream, status was '{0:? }'" ) ]
12- Inflate ( #[ from] flate2 :: DecompressError ) ,
139+ #[ error( "Could not decode zip stream, status was '{0}'" ) ]
140+ Inflate ( #[ from] super :: DecompressError ) ,
13141 #[ error( "The zlib status indicated an error, status was '{0:?}'" ) ]
14- Status ( flate2 :: Status ) ,
142+ Status ( super :: Status ) ,
15143 }
16144}
17145
18146/// Decompress a few bytes of a zlib stream without allocation
147+ #[ derive( Default ) ]
19148pub struct Inflate {
20149 /// The actual decompressor doing all the work.
21150 pub state : Decompress ,
22151}
23152
24- impl Default for Inflate {
25- fn default ( ) -> Self {
26- Inflate {
27- state : Decompress :: new ( true ) ,
28- }
29- }
30- }
31-
32153impl Inflate {
33154 /// Run the decompressor exactly once. Cannot be run multiple times
34- pub fn once ( & mut self , input : & [ u8 ] , out : & mut [ u8 ] ) -> Result < ( flate2 :: Status , usize , usize ) , inflate:: Error > {
155+ pub fn once ( & mut self , input : & [ u8 ] , out : & mut [ u8 ] ) -> Result < ( Status , usize , usize ) , inflate:: Error > {
35156 let before_in = self . state . total_in ( ) ;
36157 let before_out = self . state . total_out ( ) ;
37- let status = self . state . decompress ( input, out, flate2 :: FlushDecompress :: None ) ?;
158+ let status = self . state . decompress ( input, out, FlushDecompress :: None ) ?;
38159 Ok ( (
39160 status,
40161 ( self . state . total_in ( ) - before_in) as usize ,
@@ -44,7 +165,7 @@ impl Inflate {
44165
45166 /// Ready this instance for decoding another data stream.
46167 pub fn reset ( & mut self ) {
47- self . state . reset ( true ) ;
168+ self . state . reset ( ) ;
48169 }
49170}
50171
0 commit comments