@@ -271,28 +271,55 @@ impl<A: Allocator> BufferedWriterSpec for Vec<u8, A> {
271271 }
272272 }
273273
274+ // don't immediately offer the vec's whole spare capacity, otherwise
275+ // we might have to fully initialize it if the reader doesn't have a custom read_buf() impl
276+ let mut max_read_size = DEFAULT_BUF_SIZE ;
277+
274278 loop {
275279 self . reserve ( DEFAULT_BUF_SIZE ) ;
276- let mut buf: BorrowedBuf < ' _ > = self . spare_capacity_mut ( ) . into ( ) ;
277- match reader. read_buf ( buf. unfilled ( ) ) {
278- Ok ( ( ) ) => { }
279- Err ( e) if e. is_interrupted ( ) => continue ,
280- Err ( e) => return Err ( e) ,
281- } ;
280+ let mut initialized_spare_capacity = 0 ;
282281
283- let read = buf. filled ( ) . len ( ) ;
284- if read == 0 {
285- break ;
286- }
282+ loop {
283+ let buf = self . spare_capacity_mut ( ) ;
284+ let read_size = min ( max_read_size, buf. len ( ) ) ;
285+ let mut buf = BorrowedBuf :: from ( & mut buf[ ..read_size] ) ;
286+ // SAFETY: init is either 0 or the init_len from the previous iteration.
287+ unsafe { buf. set_init ( initialized_spare_capacity) ; }
288+ match reader. read_buf ( buf. unfilled ( ) ) {
289+ Ok ( ( ) ) => {
290+ let bytes_read = buf. len ( ) ;
287291
288- // SAFETY: BorrowedBuf guarantees all of its filled bytes are init
289- // and the number of read bytes can't exceed the spare capacity since
290- // that's what the buffer is borrowing from.
291- unsafe { self . set_len ( self . len ( ) + read) } ;
292- bytes += read as u64 ;
293- }
292+ // EOF
293+ if bytes_read == 0 {
294+ return Ok ( bytes) ;
295+ }
296+
297+ // the reader is returning short reads but it doesn't call ensure_init()
298+ if buf. init_len ( ) < buf. capacity ( ) {
299+ max_read_size = usize:: MAX ;
300+ }
301+ // the reader hasn't returned short reads so far
302+ if bytes_read == buf. capacity ( ) {
303+ max_read_size *= 2 ;
304+ }
294305
295- Ok ( bytes)
306+ initialized_spare_capacity = buf. init_len ( ) - bytes_read;
307+ bytes += bytes_read as u64 ;
308+ // SAFETY: BorrowedBuf guarantees all of its filled bytes are init
309+ // and the number of read bytes can't exceed the spare capacity since
310+ // that's what the buffer is borrowing from.
311+ unsafe { self . set_len ( self . len ( ) + bytes_read) } ;
312+
313+ // spare capacity full, reserve more
314+ if self . len ( ) == self . capacity ( ) {
315+ break ;
316+ }
317+ }
318+ Err ( e) if e. is_interrupted ( ) => continue ,
319+ Err ( e) => return Err ( e) ,
320+ }
321+ }
322+ }
296323 }
297324}
298325
0 commit comments