@@ -26,10 +26,12 @@ where
2626}
2727
2828/// Hold all state needed for compressing data.
29- pub struct Compress ( libz_rs_sys :: z_stream ) ;
29+ pub struct Compress ( zlib_rs :: c_api :: z_stream ) ;
3030
31- unsafe impl Sync for Compress { }
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.
3233unsafe impl Send for Compress { }
34+ unsafe impl Sync for Compress { }
3335
3436impl Default for Compress {
3537 fn default ( ) -> Self {
@@ -50,23 +52,21 @@ impl Compress {
5052
5153 /// Create a new instance - this allocates so should be done with care.
5254 pub fn new ( ) -> Self {
53- let mut this = libz_rs_sys:: z_stream:: default ( ) ;
54-
55- unsafe {
56- libz_rs_sys:: deflateInit_ (
57- & mut this,
58- libz_rs_sys:: Z_BEST_SPEED ,
59- libz_rs_sys:: zlibVersion ( ) ,
60- core:: mem:: size_of :: < libz_rs_sys:: z_stream > ( ) as core:: ffi:: c_int ,
61- ) ;
62- }
63-
64- Self ( this)
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)
6562 }
6663
6764 /// Prepare the instance for a new stream.
6865 pub fn reset ( & mut self ) {
69- unsafe { libz_rs_sys:: deflateReset ( & mut self . 0 ) } ;
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+ }
7070 }
7171
7272 /// Compress `input` and write compressed bytes to `output`, with `flush` controlling additional characteristics.
@@ -77,21 +77,38 @@ impl Compress {
7777 self . 0 . next_in = input. as_ptr ( ) ;
7878 self . 0 . next_out = output. as_mut_ptr ( ) ;
7979
80- match unsafe { libz_rs_sys:: deflate ( & mut self . 0 , flush as _ ) } {
81- libz_rs_sys:: Z_OK => Ok ( Status :: Ok ) ,
82- libz_rs_sys:: Z_BUF_ERROR => Ok ( Status :: BufError ) ,
83- libz_rs_sys:: Z_STREAM_END => Ok ( Status :: StreamEnd ) ,
84-
85- libz_rs_sys:: Z_STREAM_ERROR => Err ( CompressError :: StreamError ) ,
86- libz_rs_sys:: Z_MEM_ERROR => Err ( CompressError :: InsufficientMemory ) ,
87- err => Err ( CompressError :: Unknown { err } ) ,
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 {
86+ FlushCompress :: None => zlib_rs:: DeflateFlush :: NoFlush ,
87+ FlushCompress :: Partial => zlib_rs:: DeflateFlush :: PartialFlush ,
88+ FlushCompress :: Sync => zlib_rs:: DeflateFlush :: SyncFlush ,
89+ FlushCompress :: Full => zlib_rs:: DeflateFlush :: FullFlush ,
90+ FlushCompress :: Finish => zlib_rs:: DeflateFlush :: Finish ,
91+ } ;
92+
93+ // Note: zlib_rs::deflate::deflate is a safe function (unlike inflate which is unsafe)
94+ // 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 } ) ,
88102 }
89103 }
90104}
91105
92106impl Drop for Compress {
93107 fn drop ( & mut self ) {
94- unsafe { libz_rs_sys:: deflateEnd ( & mut self . 0 ) } ;
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) ;
111+ }
95112 }
96113}
97114
@@ -117,7 +134,7 @@ pub enum FlushCompress {
117134 /// A typical parameter for passing to compression/decompression functions,
118135 /// this indicates that the underlying stream to decide how much data to
119136 /// accumulate before producing output in order to maximize compression.
120- None = libz_rs_sys :: Z_NO_FLUSH as isize ,
137+ None = 0 ,
121138
122139 /// All pending output is flushed to the output buffer, but the output is
123140 /// not aligned to a byte boundary.
@@ -127,7 +144,7 @@ pub enum FlushCompress {
127144 /// with an empty fixed codes block that is 10 bits long, and it assures
128145 /// that enough bytes are output in order for the decompressor to finish the
129146 /// block before the empty fixed code block.
130- Partial = libz_rs_sys :: Z_PARTIAL_FLUSH as isize ,
147+ Partial = 1 ,
131148
132149 /// All pending output is flushed to the output buffer and the output is
133150 /// aligned on a byte boundary so that the decompressor can get all input
@@ -136,20 +153,20 @@ pub enum FlushCompress {
136153 /// Flushing may degrade compression for some compression algorithms and so
137154 /// it should only be used when necessary. This will complete the current
138155 /// deflate block and follow it with an empty stored block.
139- Sync = libz_rs_sys :: Z_SYNC_FLUSH as isize ,
156+ Sync = 2 ,
140157
141158 /// All output is flushed as with `Flush::Sync` and the compression state is
142159 /// reset so decompression can restart from this point if previous
143160 /// compressed data has been damaged or if random access is desired.
144161 ///
145162 /// Using this option too often can seriously degrade compression.
146- Full = libz_rs_sys :: Z_FULL_FLUSH as isize ,
163+ Full = 3 ,
147164
148165 /// Pending input is processed and pending output is flushed.
149166 ///
150167 /// The return value may indicate that the stream is not yet done and more
151168 /// data has yet to be processed.
152- Finish = libz_rs_sys :: Z_FINISH as isize ,
169+ Finish = 4 ,
153170}
154171
155172mod impls {
0 commit comments