@@ -174,91 +174,70 @@ impl<'inp, 'out> InOutBufReserved<'inp, 'out, u8> {
174174 P : Padding ,
175175 BS : ArraySize ,
176176 {
177- let bs = BS :: USIZE ;
178- let blocks_len = self . in_len / bs;
179-
180177 use block_padding:: PaddedData ;
181178 let ( blocks, tail_block) = match P :: pad_detached ( self . get_in ( ) ) {
182179 PaddedData :: Pad { blocks, tail_block } => ( blocks, Some ( tail_block) ) ,
183180 PaddedData :: NoPad { blocks } => ( blocks, None ) ,
184181 PaddedData :: Error => return Err ( PadError ) ,
185182 } ;
186183
187- assert_eq ! ( blocks. len( ) , blocks_len) ;
188-
189- let out_len = self . out_len ;
190- let ( in_ptr, out_ptr) = self . into_raw ( ) ;
191-
192- let blocks = unsafe {
193- InOutBuf :: from_raw (
194- in_ptr. cast :: < Array < u8 , BS > > ( ) ,
195- out_ptr. cast :: < Array < u8 , BS > > ( ) ,
196- blocks_len,
197- )
198- } ;
199-
200- let Some ( tail_block) = tail_block else {
201- let tail_inout = None ;
202- return Ok ( PaddedInOutBuf { blocks, tail_inout } ) ;
203- } ;
204-
205- let blocks_byte_len = blocks_len * bs;
206- let reserve_len = out_len - blocks_byte_len;
207- if reserve_len < tail_block. len ( ) {
208- return Err ( PadError ) ;
209- }
210- // SAFETY: we checked that the out buffer has enough bytes in reserve
211- let tail_out: & mut Array < u8 , BS > = unsafe {
212- let tail_out_ptr = out_ptr. add ( blocks_byte_len) ;
213- & mut * ( tail_out_ptr. cast ( ) )
214- } ;
184+ assert_eq ! ( blocks. len( ) , self . in_len / BS :: USIZE ) ;
215185
216- let tail_inout = Some ( ( tail_block, tail_out) ) ;
217-
218- Ok ( PaddedInOutBuf { blocks, tail_inout } )
186+ Ok ( PaddedInOutBuf {
187+ in_ptr : blocks. as_ptr ( ) ,
188+ out_ptr : self . out_ptr . cast ( ) ,
189+ blocks_len : blocks. len ( ) ,
190+ tail_block,
191+ _pd : PhantomData ,
192+ } )
219193 }
220194}
221195
222196/// Variant of [`InOutBuf`] with optional padded tail block.
223197#[ cfg( feature = "block-padding" ) ]
224- #[ allow( clippy:: type_complexity) ]
225198pub struct PaddedInOutBuf < ' inp , ' out , BS : ArraySize > {
226- blocks : InOutBuf < ' inp , ' out , Array < u8 , BS > > ,
227- tail_inout : Option < ( Array < u8 , BS > , & ' out mut Array < u8 , BS > ) > ,
199+ /// Pointer to the input blocks.
200+ in_ptr : * const Array < u8 , BS > ,
201+ /// Pointer to the output blocks (including tail block if present).
202+ out_ptr : * mut Array < u8 , BS > ,
203+ /// Number of full blocks (i.e. excluding the tail block if present).
204+ blocks_len : usize ,
205+ /// Padded input tail.
206+ tail_block : Option < Array < u8 , BS > > ,
207+ _pd : PhantomData < ( & ' inp u8 , & ' out mut u8 ) > ,
228208}
229209
230210#[ cfg( feature = "block-padding" ) ]
231211impl < ' out , BS : ArraySize > PaddedInOutBuf < ' _ , ' out , BS > {
232212 /// Get full blocks.
233213 #[ inline( always) ]
234214 pub fn get_blocks ( & mut self ) -> InOutBuf < ' _ , ' _ , Array < u8 , BS > > {
235- self . blocks . reborrow ( )
215+ unsafe { InOutBuf :: from_raw ( self . in_ptr , self . out_ptr , self . blocks_len ) }
236216 }
237217
238218 /// Get padded tail block.
239219 ///
240220 /// Most padding implementations always return `Some`.
241221 #[ inline( always) ]
242222 pub fn get_tail_block ( & mut self ) -> Option < InOut < ' _ , ' _ , Array < u8 , BS > > > {
243- self . tail_inout . as_mut ( ) . map ( |( in_block, out_block) | {
244- let in_block = & * in_block;
245- let out_block = & mut * * out_block;
246- InOut :: from ( ( in_block, out_block) )
223+ // SAFETY: if `tail` is `Some`, then `out_ptr` points to a buffer with length equal
224+ // to at least `blocks_len + 1` blocks, so it satisfies the safety conditions
225+ // required by `InOut::from_raw`.
226+ self . tail_block . as_ref ( ) . map ( |in_block| unsafe {
227+ let tail_out_ptr = self . out_ptr . add ( self . blocks_len ) ;
228+ InOut :: from_raw ( in_block, tail_out_ptr)
247229 } )
248230 }
249231
250232 /// Convert buffer into output slice.
251233 #[ inline( always) ]
252234 pub fn into_out ( self ) -> & ' out [ u8 ] {
253- let total_blocks = if self . tail_inout . is_some ( ) {
254- self . blocks . len ( ) + 1
255- } else {
256- self . blocks . len ( )
257- } ;
258- let res_len = BS :: USIZE * total_blocks;
259- let ( _, out_ptr) = self . blocks . into_raw ( ) ;
260- // SAFETY: `res_len` is always valid for the output buffer since
261- // it's checked during type construction
262- unsafe { slice:: from_raw_parts ( out_ptr as * const u8 , res_len) }
235+ let mut bytes_len = BS :: USIZE * self . blocks_len ;
236+ // If tail is present, add its length to the resulting buffer length.
237+ if self . tail_block . is_some ( ) {
238+ bytes_len += BS :: USIZE ;
239+ }
240+ // SAFETY: `out_ptr` points to a valid memory with size of `bytes_len`
241+ unsafe { slice:: from_raw_parts ( self . out_ptr . cast ( ) , bytes_len) }
263242 }
264243}
0 commit comments