Skip to content

Commit ff725f3

Browse files
committed
fix change clobbered by rebase
1 parent 0d8fd23 commit ff725f3

File tree

1 file changed

+23
-7
lines changed

1 file changed

+23
-7
lines changed

library/std/src/io/mod.rs

+23-7
Original file line numberDiff line numberDiff line change
@@ -358,11 +358,9 @@ where
358358
// of data to return. Simply tacking on an extra DEFAULT_BUF_SIZE space every
359359
// time is 4,500 times (!) slower than a default reservation size of 32 if the
360360
// reader has a very small amount of data to return.
361-
//
362-
// Because we're extending the buffer with uninitialized data for trusted
363-
// readers, we need to make sure to truncate that if any of this panics.
364361
pub(crate) fn default_read_to_end<R: Read + ?Sized>(r: &mut R, buf: &mut Vec<u8>) -> Result<usize> {
365-
let initial_len = buf.len(); // need to know so we can return how many bytes we read
362+
let start_len = buf.len();
363+
let start_cap = buf.capacity();
366364

367365
let mut initialized = 0; // Extra initalized bytes from previous loop iteration
368366
loop {
@@ -384,7 +382,7 @@ pub(crate) fn default_read_to_end<R: Read + ?Sized>(r: &mut R, buf: &mut Vec<u8>
384382
}
385383

386384
if read_buf.filled_len() == 0 {
387-
break;
385+
return Ok(buf.len() - start_len)
388386
}
389387

390388
// store how much was initialized but not filled
@@ -395,9 +393,27 @@ pub(crate) fn default_read_to_end<R: Read + ?Sized>(r: &mut R, buf: &mut Vec<u8>
395393
unsafe {
396394
buf.set_len(new_len);
397395
}
398-
}
399396

400-
Ok(buf.len() - initial_len)
397+
if buf.len() == buf.capacity() && buf.capacity() == start_cap {
398+
// The buffer might be an exact fit. Let's read into a probe buffer
399+
// and see if it returns `Ok(0)`. If so, we've avoided an
400+
// unnecessary doubling of the capacity. But if not, append the
401+
// probe buffer to the primary buffer and let its capacity grow.
402+
let mut probe = [0u8; 32];
403+
404+
loop {
405+
match r.read(&mut probe) {
406+
Ok(0) => return Ok(buf.len() - start_len),
407+
Ok(n) => {
408+
buf.extend_from_slice(&probe[..n]);
409+
break;
410+
}
411+
Err(ref e) if e.kind() == ErrorKind::Interrupted => continue,
412+
Err(e) => return Err(e),
413+
}
414+
}
415+
}
416+
}
401417
}
402418

403419
pub(crate) fn default_read_to_string<R: Read + ?Sized>(

0 commit comments

Comments
 (0)