11use crate :: zlib:: Status ;
2- use std :: ffi :: c_int ;
2+ use zlib_rs :: DeflateError ;
33
44const BUF_SIZE : usize = 4096 * 8 ;
55
2626}
2727
2828/// Hold all state needed for compressing data.
29- pub struct Compress ( zlib_rs:: c_api:: z_stream ) ;
30-
31- // SAFETY: The z_stream contains raw pointers but they are only used through safe zlib-rs APIs
32- // and the state is fully owned by this struct, making it safe to send across threads.
33- unsafe impl Send for Compress { }
34- unsafe impl Sync for Compress { }
29+ pub struct Compress ( zlib_rs:: Deflate ) ;
3530
3631impl Default for Compress {
3732 fn default ( ) -> Self {
@@ -42,72 +37,41 @@ impl Default for Compress {
4237impl Compress {
4338 /// The number of bytes that were read from the input.
4439 pub fn total_in ( & self ) -> u64 {
45- self . 0 . total_in as _
40+ self . 0 . total_in ( )
4641 }
4742
4843 /// The number of compressed bytes that were written to the output.
4944 pub fn total_out ( & self ) -> u64 {
50- self . 0 . total_out as _
45+ self . 0 . total_out ( )
5146 }
5247
5348 /// Create a new instance - this allocates so should be done with care.
5449 pub fn new ( ) -> Self {
55- let mut stream = zlib_rs:: c_api:: z_stream:: default ( ) ;
56- let config = zlib_rs:: deflate:: DeflateConfig {
57- level : 1 , // Z_BEST_SPEED
58- ..Default :: default ( )
59- } ;
60- zlib_rs:: deflate:: init ( & mut stream, config) ;
61- Self ( stream)
50+ let inner = zlib_rs:: Deflate :: new ( zlib_rs:: c_api:: Z_BEST_SPEED , true , zlib_rs:: MAX_WBITS as u8 ) ;
51+ Self ( inner)
6252 }
6353
6454 /// Prepare the instance for a new stream.
6555 pub fn reset ( & mut self ) {
66- // SAFETY: Converting from z_stream to DeflateStream is safe here as we maintain ownership
67- if let Some ( stream) = unsafe { zlib_rs:: deflate:: DeflateStream :: from_stream_mut ( & mut self . 0 ) } {
68- zlib_rs:: deflate:: reset ( stream) ;
69- }
56+ self . 0 . reset ( ) ;
7057 }
7158
7259 /// Compress `input` and write compressed bytes to `output`, with `flush` controlling additional characteristics.
7360 pub fn compress ( & mut self , input : & [ u8 ] , output : & mut [ u8 ] , flush : FlushCompress ) -> Result < Status , CompressError > {
74- self . 0 . avail_in = input. len ( ) as _ ;
75- self . 0 . avail_out = output. len ( ) as _ ;
76-
77- self . 0 . next_in = input. as_ptr ( ) ;
78- self . 0 . next_out = output. as_mut_ptr ( ) ;
79-
80- // SAFETY: We're converting from the C-compatible z_stream to the typed DeflateStream.
81- // This is safe because we initialized the stream with `deflate::init` and maintain ownership.
82- let stream = unsafe { zlib_rs:: deflate:: DeflateStream :: from_stream_mut ( & mut self . 0 ) }
83- . ok_or ( CompressError :: StreamError ) ?;
84-
85- let deflate_flush = match flush {
61+ let flush = match flush {
8662 FlushCompress :: None => zlib_rs:: DeflateFlush :: NoFlush ,
8763 FlushCompress :: Partial => zlib_rs:: DeflateFlush :: PartialFlush ,
8864 FlushCompress :: Sync => zlib_rs:: DeflateFlush :: SyncFlush ,
8965 FlushCompress :: Full => zlib_rs:: DeflateFlush :: FullFlush ,
9066 FlushCompress :: Finish => zlib_rs:: DeflateFlush :: Finish ,
9167 } ;
92-
68+ let status = self . 0 . compress ( input , output , flush ) ? ;
9369 // Note: zlib_rs::deflate::deflate is a safe function (unlike inflate which is unsafe)
9470 // because deflate doesn't have the same safety concerns as inflate regarding output buffer handling
95- match zlib_rs:: deflate:: deflate ( stream, deflate_flush) {
96- zlib_rs:: ReturnCode :: Ok => Ok ( Status :: Ok ) ,
97- zlib_rs:: ReturnCode :: BufError => Ok ( Status :: BufError ) ,
98- zlib_rs:: ReturnCode :: StreamEnd => Ok ( Status :: StreamEnd ) ,
99- zlib_rs:: ReturnCode :: StreamError => Err ( CompressError :: StreamError ) ,
100- zlib_rs:: ReturnCode :: MemError => Err ( CompressError :: InsufficientMemory ) ,
101- err => Err ( CompressError :: Unknown { err : err as c_int } ) ,
102- }
103- }
104- }
105-
106- impl Drop for Compress {
107- fn drop ( & mut self ) {
108- // SAFETY: Converting from z_stream to DeflateStream is safe here as we maintain ownership
109- if let Some ( stream) = unsafe { zlib_rs:: deflate:: DeflateStream :: from_stream_mut ( & mut self . 0 ) } {
110- let _ = zlib_rs:: deflate:: end ( stream) ;
71+ match status {
72+ zlib_rs:: Status :: Ok => Ok ( Status :: Ok ) ,
73+ zlib_rs:: Status :: BufError => Ok ( Status :: BufError ) ,
74+ zlib_rs:: Status :: StreamEnd => Ok ( Status :: StreamEnd ) ,
11175 }
11276 }
11377}
@@ -119,10 +83,20 @@ impl Drop for Compress {
11983pub enum CompressError {
12084 #[ error( "stream error" ) ]
12185 StreamError ,
86+ #[ error( "The input is not a valid deflate stream." ) ]
87+ DataError ,
12288 #[ error( "Not enough memory" ) ]
12389 InsufficientMemory ,
124- #[ error( "An unknown error occurred: {err}" ) ]
125- Unknown { err : c_int } ,
90+ }
91+
92+ impl From < zlib_rs:: DeflateError > for CompressError {
93+ fn from ( value : zlib_rs:: DeflateError ) -> Self {
94+ match value {
95+ DeflateError :: StreamError => CompressError :: StreamError ,
96+ DeflateError :: DataError => CompressError :: DataError ,
97+ DeflateError :: MemError => CompressError :: InsufficientMemory ,
98+ }
99+ }
126100}
127101
128102/// Values which indicate the form of flushing to be used when compressing
0 commit comments