mirror of
https://git.proxmox.com/git/proxmox
synced 2025-07-17 23:48:58 +00:00
trait ReadExt: add read_exact_or_eof and skip_to_end
This commit is contained in:
parent
a793453944
commit
c7be237b57
@ -222,6 +222,19 @@ pub trait ReadExt {
|
|||||||
/// This should only used for types with a defined storage representation, usually
|
/// This should only used for types with a defined storage representation, usually
|
||||||
/// `#[repr(C)]`, otherwise the results may be inconsistent.
|
/// `#[repr(C)]`, otherwise the results may be inconsistent.
|
||||||
unsafe fn read_host_value_boxed<T>(&mut self) -> io::Result<Box<T>>;
|
unsafe fn read_host_value_boxed<T>(&mut self) -> io::Result<Box<T>>;
|
||||||
|
|
||||||
|
/// Try to read the exact number of bytes required to fill buf.
|
||||||
|
///
|
||||||
|
/// This function reads as many bytes as necessary to completely
|
||||||
|
/// fill the specified buffer buf. If this function encounters an
|
||||||
|
/// "end of file" before getting any data, it returns Ok(false).
|
||||||
|
/// If there is some data, but not enough, it return an error of
|
||||||
|
/// the kind ErrorKind::UnexpectedEof. The contents of buf are
|
||||||
|
/// unspecified in this case.
|
||||||
|
fn read_exact_or_eof(&mut self, buf: &mut [u8]) -> io::Result<bool>;
|
||||||
|
|
||||||
|
/// Read until EOF
|
||||||
|
fn skip_to_end(&mut self) -> io::Result<usize>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<R: io::Read> ReadExt for R {
|
impl<R: io::Read> ReadExt for R {
|
||||||
@ -279,4 +292,40 @@ impl<R: io::Read> ReadExt for R {
|
|||||||
))?;
|
))?;
|
||||||
Ok(Box::from_raw(ptr))
|
Ok(Box::from_raw(ptr))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn read_exact_or_eof(&mut self, mut buf: &mut [u8]) -> io::Result<bool> {
|
||||||
|
let mut read_bytes = 0;
|
||||||
|
loop {
|
||||||
|
match self.read(&mut buf) {
|
||||||
|
Ok(0) => {
|
||||||
|
if read_bytes == 0 { return Ok(false); }
|
||||||
|
return Err(io::Error::new(
|
||||||
|
io::ErrorKind::UnexpectedEof,
|
||||||
|
"failed to fill whole buffer")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
Ok(n) => {
|
||||||
|
let tmp = buf;
|
||||||
|
buf = &mut tmp[n..];
|
||||||
|
read_bytes += n;
|
||||||
|
if buf.is_empty() { return Ok(true); }
|
||||||
|
}
|
||||||
|
Err(ref e) if e.kind() == std::io::ErrorKind::Interrupted => {}
|
||||||
|
Err(e) => return Err(e),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn skip_to_end(&mut self) -> io::Result<usize> {
|
||||||
|
let mut skipped_bytes = 0;
|
||||||
|
let mut buf = unsafe { vec::uninitialized(32*1024) };
|
||||||
|
loop {
|
||||||
|
match self.read(&mut buf) {
|
||||||
|
Ok(0) => return Ok(skipped_bytes),
|
||||||
|
Ok(n) => skipped_bytes += n,
|
||||||
|
Err(ref e) if e.kind() == std::io::ErrorKind::Interrupted => {}
|
||||||
|
Err(e) => return Err(e),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user