in sgx_tstd/src/io/copy.rs [100:144]
fn copy_to<R: Read + ?Sized>(reader: &mut R, writer: &mut Self) -> Result<u64> {
if writer.capacity() < DEFAULT_BUF_SIZE {
return stack_buffer_copy(reader, writer);
}
let mut len = 0;
let mut init = 0;
loop {
let buf = writer.buffer_mut();
let mut read_buf: BorrowedBuf<'_> = buf.spare_capacity_mut().into();
unsafe {
// SAFETY: init is either 0 or the init_len from the previous iteration.
read_buf.set_init(init);
}
if read_buf.capacity() >= DEFAULT_BUF_SIZE {
let mut cursor = read_buf.unfilled();
match reader.read_buf(cursor.reborrow()) {
Ok(()) => {
let bytes_read = cursor.written();
if bytes_read == 0 {
return Ok(len);
}
init = read_buf.init_len() - bytes_read;
len += bytes_read as u64;
// SAFETY: BorrowedBuf guarantees all of its filled bytes are init
unsafe { buf.set_len(buf.len() + bytes_read) };
// Read again if the buffer still has enough capacity, as BufWriter itself would do
// This will occur if the reader returns short reads
}
Err(ref e) if e.kind() == ErrorKind::Interrupted => {}
Err(e) => return Err(e),
}
} else {
writer.flush_buf()?;
init = 0;
}
}
}