more efficent File::read_buf impl for windows and unix
This commit is contained in:
parent
146b396f21
commit
5a97090b04
@ -13,7 +13,7 @@ mod tests;
|
||||
|
||||
use crate::ffi::OsString;
|
||||
use crate::fmt;
|
||||
use crate::io::{self, IoSlice, IoSliceMut, Read, Seek, SeekFrom, Write};
|
||||
use crate::io::{self, IoSlice, IoSliceMut, Read, ReadBuf, Seek, SeekFrom, Write};
|
||||
use crate::path::{Path, PathBuf};
|
||||
use crate::sys::fs as fs_imp;
|
||||
use crate::sys_common::{AsInner, AsInnerMut, FromInner, IntoInner};
|
||||
@ -624,6 +624,10 @@ impl Read for File {
|
||||
self.inner.read_vectored(bufs)
|
||||
}
|
||||
|
||||
fn read_buf(&mut self, buf: &mut ReadBuf<'_>) -> io::Result<()> {
|
||||
self.inner.read_buf(buf)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn is_read_vectored(&self) -> bool {
|
||||
self.inner.is_read_vectored()
|
||||
|
@ -448,6 +448,15 @@ pub(crate) fn default_read_exact<R: Read + ?Sized>(this: &mut R, mut buf: &mut [
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn default_read_buf<F>(read: F, buf: &mut ReadBuf<'_>) -> Result<()>
|
||||
where
|
||||
F: FnOnce(&mut [u8]) -> Result<usize>,
|
||||
{
|
||||
let n = read(buf.initialize_unfilled())?;
|
||||
buf.add_filled(n);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// The `Read` trait allows for reading bytes from a source.
|
||||
///
|
||||
/// Implementors of the `Read` trait are called 'readers'.
|
||||
@ -787,9 +796,7 @@ pub trait Read {
|
||||
/// The default implementation delegates to `read`.
|
||||
#[unstable(feature = "read_buf", issue = "78485")]
|
||||
fn read_buf(&mut self, buf: &mut ReadBuf<'_>) -> Result<()> {
|
||||
let n = self.read(buf.initialize_unfilled())?;
|
||||
buf.add_filled(n);
|
||||
Ok(())
|
||||
default_read_buf(|b| self.read(b), buf)
|
||||
}
|
||||
|
||||
/// Read the exact number of bytes required to fill `buf`.
|
||||
|
@ -1,6 +1,6 @@
|
||||
#![unstable(reason = "not public", issue = "none", feature = "fd")]
|
||||
|
||||
use crate::io::{self, Read};
|
||||
use crate::io::{self, Read, ReadBuf};
|
||||
use crate::mem;
|
||||
use crate::sys::cvt;
|
||||
use crate::sys::hermit::abi;
|
||||
|
@ -2,7 +2,7 @@ use crate::ffi::{CStr, CString, OsString};
|
||||
use crate::fmt;
|
||||
use crate::hash::{Hash, Hasher};
|
||||
use crate::io::{self, Error, ErrorKind};
|
||||
use crate::io::{IoSlice, IoSliceMut, SeekFrom};
|
||||
use crate::io::{IoSlice, IoSliceMut, ReadBuf, SeekFrom};
|
||||
use crate::os::unix::ffi::OsStrExt;
|
||||
use crate::path::{Path, PathBuf};
|
||||
use crate::sys::cvt;
|
||||
@ -312,6 +312,10 @@ impl File {
|
||||
false
|
||||
}
|
||||
|
||||
pub fn read_buf(&self, buf: &mut ReadBuf<'_>) -> io::Result<()> {
|
||||
crate::io::default_read_buf(|buf| self.read(buf), buf)
|
||||
}
|
||||
|
||||
pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
|
||||
self.0.write(buf)
|
||||
}
|
||||
|
@ -4,7 +4,7 @@
|
||||
mod tests;
|
||||
|
||||
use crate::cmp;
|
||||
use crate::io::{self, IoSlice, IoSliceMut, Read};
|
||||
use crate::io::{self, IoSlice, IoSliceMut, Read, ReadBuf};
|
||||
use crate::os::unix::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd};
|
||||
use crate::sys::cvt;
|
||||
use crate::sys_common::{AsInner, FromInner, IntoInner};
|
||||
@ -127,6 +127,23 @@ impl FileDesc {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn read_buf(&self, buf: &mut ReadBuf<'_>) -> io::Result<()> {
|
||||
let ret = cvt(unsafe {
|
||||
libc::read(
|
||||
self.as_raw_fd(),
|
||||
buf.unfilled_mut().as_mut_ptr() as *mut c_void,
|
||||
cmp::min(buf.remaining(), READ_LIMIT),
|
||||
)
|
||||
})?;
|
||||
|
||||
// Safety: `ret` bytes were written to the initialized portion of the buffer
|
||||
unsafe {
|
||||
buf.assume_init(ret as usize);
|
||||
}
|
||||
buf.add_filled(ret as usize);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
|
||||
let ret = cvt(unsafe {
|
||||
libc::write(
|
||||
|
@ -2,7 +2,7 @@ use crate::os::unix::prelude::*;
|
||||
|
||||
use crate::ffi::{CStr, CString, OsStr, OsString};
|
||||
use crate::fmt;
|
||||
use crate::io::{self, Error, IoSlice, IoSliceMut, SeekFrom};
|
||||
use crate::io::{self, Error, IoSlice, IoSliceMut, ReadBuf, SeekFrom};
|
||||
use crate::mem;
|
||||
use crate::os::unix::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd};
|
||||
use crate::path::{Path, PathBuf};
|
||||
@ -864,6 +864,10 @@ impl File {
|
||||
self.0.read_at(buf, offset)
|
||||
}
|
||||
|
||||
pub fn read_buf(&self, buf: &mut ReadBuf<'_>) -> io::Result<()> {
|
||||
self.0.read_buf(buf)
|
||||
}
|
||||
|
||||
pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
|
||||
self.0.write(buf)
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
use crate::ffi::OsString;
|
||||
use crate::fmt;
|
||||
use crate::hash::{Hash, Hasher};
|
||||
use crate::io::{self, IoSlice, IoSliceMut, SeekFrom};
|
||||
use crate::io::{self, IoSlice, IoSliceMut, ReadBuf, SeekFrom};
|
||||
use crate::path::{Path, PathBuf};
|
||||
use crate::sys::time::SystemTime;
|
||||
use crate::sys::unsupported;
|
||||
@ -206,6 +206,10 @@ impl File {
|
||||
self.0
|
||||
}
|
||||
|
||||
pub fn read_buf(&self, buf: &mut ReadBuf<'_>) -> io::Result<()> {
|
||||
self.0
|
||||
}
|
||||
|
||||
pub fn write(&self, _buf: &[u8]) -> io::Result<usize> {
|
||||
self.0
|
||||
}
|
||||
|
@ -3,7 +3,7 @@
|
||||
use super::fd::WasiFd;
|
||||
use crate::ffi::{CStr, CString, OsStr, OsString};
|
||||
use crate::fmt;
|
||||
use crate::io::{self, IoSlice, IoSliceMut, SeekFrom};
|
||||
use crate::io::{self, IoSlice, IoSliceMut, ReadBuf, SeekFrom};
|
||||
use crate::iter;
|
||||
use crate::mem::{self, ManuallyDrop};
|
||||
use crate::os::raw::c_int;
|
||||
@ -411,6 +411,10 @@ impl File {
|
||||
true
|
||||
}
|
||||
|
||||
pub fn read_buf(&self, buf: &mut ReadBuf<'_>) -> io::Result<()> {
|
||||
crate::io::default_read_buf(|buf| self.read(buf), buf)
|
||||
}
|
||||
|
||||
pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
|
||||
self.write_vectored(&[IoSlice::new(buf)])
|
||||
}
|
||||
|
@ -2,7 +2,7 @@ use crate::os::windows::prelude::*;
|
||||
|
||||
use crate::ffi::OsString;
|
||||
use crate::fmt;
|
||||
use crate::io::{self, Error, IoSlice, IoSliceMut, SeekFrom};
|
||||
use crate::io::{self, Error, IoSlice, IoSliceMut, ReadBuf, SeekFrom};
|
||||
use crate::mem;
|
||||
use crate::os::windows::io::{AsHandle, BorrowedHandle};
|
||||
use crate::path::{Path, PathBuf};
|
||||
@ -420,6 +420,10 @@ impl File {
|
||||
self.handle.read_at(buf, offset)
|
||||
}
|
||||
|
||||
pub fn read_buf(&self, buf: &mut ReadBuf<'_>) -> io::Result<()> {
|
||||
self.handle.read_buf(buf)
|
||||
}
|
||||
|
||||
pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
|
||||
self.handle.write(buf)
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
#![unstable(issue = "none", feature = "windows_handle")]
|
||||
|
||||
use crate::cmp;
|
||||
use crate::io::{self, ErrorKind, IoSlice, IoSliceMut, Read};
|
||||
use crate::io::{self, ErrorKind, IoSlice, IoSliceMut, Read, ReadBuf};
|
||||
use crate::mem;
|
||||
use crate::os::windows::io::{
|
||||
AsHandle, AsRawHandle, BorrowedHandle, FromRawHandle, IntoRawHandle, OwnedHandle, RawHandle,
|
||||
@ -130,6 +130,39 @@ impl Handle {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn read_buf(&self, buf: &mut ReadBuf<'_>) -> io::Result<()> {
|
||||
let mut read = 0;
|
||||
let len = cmp::min(buf.remaining(), <c::DWORD>::MAX as usize) as c::DWORD;
|
||||
let res = cvt(unsafe {
|
||||
c::ReadFile(
|
||||
self.as_raw_handle(),
|
||||
buf.unfilled_mut().as_mut_ptr() as c::LPVOID,
|
||||
len,
|
||||
&mut read,
|
||||
ptr::null_mut(),
|
||||
)
|
||||
});
|
||||
|
||||
match res {
|
||||
Ok(_) => {
|
||||
// Safety: `read` bytes were written to the initialized portion of the buffer
|
||||
unsafe {
|
||||
buf.assume_init(read as usize);
|
||||
}
|
||||
buf.add_filled(read as usize);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
// The special treatment of BrokenPipe is to deal with Windows
|
||||
// pipe semantics, which yields this error when *reading* from
|
||||
// a pipe after the other end has closed; we interpret that as
|
||||
// EOF on the pipe.
|
||||
Err(ref e) if e.kind() == ErrorKind::BrokenPipe => Ok(()),
|
||||
|
||||
Err(e) => Err(e),
|
||||
}
|
||||
}
|
||||
|
||||
pub unsafe fn read_overlapped(
|
||||
&self,
|
||||
buf: &mut [u8],
|
||||
|
Loading…
x
Reference in New Issue
Block a user