use std::fs::File;
use std::io::Error;
use std::io::Result;
use crate::descriptor::AsRawDescriptor;
use crate::FileAllocate;
use crate::FileReadWriteAtVolatile;
use crate::FileReadWriteVolatile;
use crate::VolatileSlice;
use crate::WriteZeroesAt;
impl FileReadWriteVolatile for File {
fn read_volatile(&mut self, slice: VolatileSlice) -> Result<usize> {
let mut bytes = 0;
let ret = unsafe {
winapi::um::fileapi::ReadFile(
self.as_raw_descriptor(),
slice.as_ptr() as *mut libc::c_void,
slice.size().try_into().unwrap(),
&mut bytes,
std::ptr::null_mut(),
)
};
if ret > 0 {
Ok(bytes as usize)
} else {
Err(Error::last_os_error())
}
}
fn read_vectored_volatile(&mut self, bufs: &[VolatileSlice]) -> Result<usize> {
if bufs.is_empty() {
return Ok(0);
}
let mut ret = 0usize;
for buf in bufs.iter() {
match self.read_volatile(*buf) {
Ok(bytes) => ret += bytes,
Err(_) => return Err(Error::last_os_error()),
}
}
Ok(ret)
}
fn write_volatile(&mut self, slice: VolatileSlice) -> Result<usize> {
let mut bytes = 0;
let ret = unsafe {
winapi::um::fileapi::WriteFile(
self.as_raw_descriptor(),
slice.as_ptr() as *mut libc::c_void,
slice.size().try_into().unwrap(),
&mut bytes,
std::ptr::null_mut(),
)
};
if ret > 0 {
Ok(bytes as usize)
} else {
Err(Error::last_os_error())
}
}
fn write_vectored_volatile(&mut self, bufs: &[VolatileSlice]) -> Result<usize> {
if bufs.is_empty() {
return Ok(0);
}
let mut ret = 0usize;
for buf in bufs.iter() {
match self.write_volatile(*buf) {
Ok(bytes) => ret += bytes,
Err(_) => return Err(Error::last_os_error()),
}
}
Ok(ret)
}
}
impl FileReadWriteAtVolatile for File {
fn read_at_volatile(&self, slice: VolatileSlice, offset: u64) -> Result<usize> {
let mut bytes = 0;
let ret = unsafe {
let mut overlapped: winapi::um::minwinbase::OVERLAPPED = std::mem::zeroed();
overlapped.u.s_mut().Offset = offset as u32;
overlapped.u.s_mut().OffsetHigh = (offset >> 32) as u32;
winapi::um::fileapi::ReadFile(
self.as_raw_descriptor(),
slice.as_ptr() as *mut libc::c_void,
slice.size().try_into().unwrap(),
&mut bytes,
&mut overlapped,
)
};
if ret > 0 {
Ok(bytes as usize)
} else {
Err(Error::last_os_error())
}
}
fn read_vectored_at_volatile(&self, bufs: &[VolatileSlice], offset: u64) -> Result<usize> {
if bufs.is_empty() {
return Ok(0);
}
let mut ret: usize = 0;
for buf in bufs.iter() {
match self.read_at_volatile(*buf, offset + ret as u64) {
Ok(bytes) => ret += bytes,
Err(_) => return Err(Error::last_os_error()),
}
}
Ok(ret)
}
fn write_at_volatile(&self, slice: VolatileSlice, offset: u64) -> Result<usize> {
let mut bytes = 0;
let ret = unsafe {
let mut overlapped: winapi::um::minwinbase::OVERLAPPED = std::mem::zeroed();
overlapped.u.s_mut().Offset = offset as u32;
overlapped.u.s_mut().OffsetHigh = (offset >> 32) as u32;
winapi::um::fileapi::WriteFile(
self.as_raw_descriptor(),
slice.as_ptr() as *mut libc::c_void,
slice.size().try_into().unwrap(),
&mut bytes,
&mut overlapped,
)
};
if ret > 0 {
Ok(bytes as usize)
} else {
Err(Error::last_os_error())
}
}
fn write_vectored_at_volatile(&self, bufs: &[VolatileSlice], offset: u64) -> Result<usize> {
if bufs.is_empty() {
return Ok(0);
}
let mut ret: usize = 0;
for buf in bufs.iter() {
match self.write_at_volatile(*buf, offset + ret as u64) {
Ok(bytes) => ret += bytes,
Err(_) => return Err(Error::last_os_error()),
}
}
Ok(ret)
}
}
impl FileAllocate for File {
fn allocate(&self, offset: u64, len: u64) -> Result<()> {
self.write_zeroes_all_at(offset, len as usize)
}
}