@@ -4,7 +4,6 @@ use std::error;
44use std:: fmt;
55use std:: marker;
66use std:: mem;
7- use std:: slice;
87
98use core:: ffi:: { c_int, c_uint} ;
109
@@ -133,17 +132,11 @@ impl Compress {
133132 }
134133 }
135134
136- /// Compress a block of input into a block of output.
137- ///
138- /// If anything other than [`BZ_OK`] is seen, `Err` is returned.
139- ///
140- /// The action given must be one of [`Action::Run`], [`Action::Flush`] or [`Action::Finish`].
141- ///
142- /// [`BZ_OK`]: ffi::BZ_OK
143- pub fn compress (
135+ unsafe fn compress_inner (
144136 & mut self ,
145137 input : & [ u8 ] ,
146- output : & mut [ u8 ] ,
138+ output_ptr : * mut u8 ,
139+ output_len : usize ,
147140 action : Action ,
148141 ) -> Result < Status , Error > {
149142 // apparently 0-length compression requests which don't actually make
@@ -154,8 +147,8 @@ impl Compress {
154147 }
155148 self . inner . raw . next_in = input. as_ptr ( ) as * mut _ ;
156149 self . inner . raw . avail_in = input. len ( ) . min ( c_uint:: MAX as usize ) as c_uint ;
157- self . inner . raw . next_out = output . as_mut_ptr ( ) as * mut _ ;
158- self . inner . raw . avail_out = output . len ( ) . min ( c_uint:: MAX as usize ) as c_uint ;
150+ self . inner . raw . next_out = output_ptr as * mut _ ;
151+ self . inner . raw . avail_out = output_len . min ( c_uint:: MAX as usize ) as c_uint ;
159152 unsafe {
160153 match ffi:: BZ2_bzCompress ( & mut * self . inner . raw , action as c_int ) {
161154 ffi:: BZ_RUN_OK => Ok ( Status :: RunOk ) ,
@@ -168,6 +161,32 @@ impl Compress {
168161 }
169162 }
170163
164+ /// Compress a block of input into a block of output.
165+ ///
166+ /// If anything other than [`BZ_OK`] is seen, `Err` is returned.
167+ ///
168+ /// The action given must be one of [`Action::Run`], [`Action::Flush`] or [`Action::Finish`].
169+ ///
170+ /// [`BZ_OK`]: ffi::BZ_OK
171+ pub fn compress (
172+ & mut self ,
173+ input : & [ u8 ] ,
174+ output : & mut [ u8 ] ,
175+ action : Action ,
176+ ) -> Result < Status , Error > {
177+ unsafe { self . compress_inner ( input, output. as_mut_ptr ( ) , output. len ( ) , action) }
178+ }
179+
180+ /// Same as [`Self::compress`] but accepts an uninitialised `output` buffer.
181+ pub fn compress_uninit (
182+ & mut self ,
183+ input : & [ u8 ] ,
184+ output : & mut [ mem:: MaybeUninit < u8 > ] ,
185+ action : Action ,
186+ ) -> Result < Status , Error > {
187+ unsafe { self . compress_inner ( input, output. as_mut_ptr ( ) as * mut _ , output. len ( ) , action) }
188+ }
189+
171190 /// Compress a block of input into an output vector.
172191 ///
173192 /// This function will not grow `output`, but it will fill the space after
@@ -179,16 +198,11 @@ impl Compress {
179198 output : & mut Vec < u8 > ,
180199 action : Action ,
181200 ) -> Result < Status , Error > {
182- let cap = output. capacity ( ) ;
183201 let len = output. len ( ) ;
184202
185203 unsafe {
186204 let before = self . total_out ( ) ;
187- let ret = {
188- let ptr = output. as_mut_ptr ( ) . add ( len) ;
189- let out = slice:: from_raw_parts_mut ( ptr, cap - len) ;
190- self . compress ( input, out, action)
191- } ;
205+ let ret = self . compress_uninit ( input, output. spare_capacity_mut ( ) , action) ;
192206 output. set_len ( ( self . total_out ( ) - before) as usize + len) ;
193207
194208 ret
@@ -226,12 +240,16 @@ impl Decompress {
226240 }
227241 }
228242
229- /// Decompress a block of input into a block of output.
230- pub fn decompress ( & mut self , input : & [ u8 ] , output : & mut [ u8 ] ) -> Result < Status , Error > {
243+ unsafe fn decompress_inner (
244+ & mut self ,
245+ input : & [ u8 ] ,
246+ output_ptr : * mut u8 ,
247+ output_len : usize ,
248+ ) -> Result < Status , Error > {
231249 self . inner . raw . next_in = input. as_ptr ( ) as * mut _ ;
232250 self . inner . raw . avail_in = input. len ( ) . min ( c_uint:: MAX as usize ) as c_uint ;
233- self . inner . raw . next_out = output . as_mut_ptr ( ) as * mut _ ;
234- self . inner . raw . avail_out = output . len ( ) . min ( c_uint:: MAX as usize ) as c_uint ;
251+ self . inner . raw . next_out = output_ptr as * mut _ ;
252+ self . inner . raw . avail_out = output_len . min ( c_uint:: MAX as usize ) as c_uint ;
235253 unsafe {
236254 match ffi:: BZ2_bzDecompress ( & mut * self . inner . raw ) {
237255 ffi:: BZ_OK => Ok ( Status :: Ok ) ,
@@ -246,22 +264,31 @@ impl Decompress {
246264 }
247265 }
248266
267+ /// Decompress a block of input into a block of output.
268+ pub fn decompress ( & mut self , input : & [ u8 ] , output : & mut [ u8 ] ) -> Result < Status , Error > {
269+ unsafe { self . decompress_inner ( input, output. as_mut_ptr ( ) , output. len ( ) ) }
270+ }
271+
272+ /// Same as [`Self::decompress`] but accepts an uninitialized buffer.
273+ pub fn decompress_uninit (
274+ & mut self ,
275+ input : & [ u8 ] ,
276+ output : & mut [ mem:: MaybeUninit < u8 > ] ,
277+ ) -> Result < Status , Error > {
278+ unsafe { self . decompress_inner ( input, output. as_mut_ptr ( ) as * mut _ , output. len ( ) ) }
279+ }
280+
249281 /// Decompress a block of input into an output vector.
250282 ///
251283 /// This function will not grow `output`, but it will fill the space after
252284 /// its current length up to its capacity. The length of the vector will be
253285 /// adjusted appropriately.
254286 pub fn decompress_vec ( & mut self , input : & [ u8 ] , output : & mut Vec < u8 > ) -> Result < Status , Error > {
255- let cap = output. capacity ( ) ;
256287 let len = output. len ( ) ;
257288
258289 unsafe {
259290 let before = self . total_out ( ) ;
260- let ret = {
261- let ptr = output. as_mut_ptr ( ) . add ( len) ;
262- let out = slice:: from_raw_parts_mut ( ptr, cap - len) ;
263- self . decompress ( input, out)
264- } ;
291+ let ret = self . decompress_uninit ( input, output. spare_capacity_mut ( ) ) ;
265292 output. set_len ( ( self . total_out ( ) - before) as usize + len) ;
266293
267294 ret
0 commit comments