@@ -271,28 +271,55 @@ impl<A: Allocator> BufferedWriterSpec for Vec<u8, A> {
271
271
}
272
272
}
273
273
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
+
274
278
loop {
275
279
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 ;
282
281
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 ( ) ;
287
291
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
+ }
294
305
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
+ }
296
323
}
297
324
}
298
325
0 commit comments