use crate::read::ReadError;
use crate::write::WriteError;
use std::fs::File;
use std::os::raw::c_void;
use std::os::unix::io::{AsRawFd, RawFd};
pub type SSizeT = isize;
pub type SizeT = usize;
pub type OffT = isize;
extern "C" {
fn pread(fd: RawFd, buf: *mut c_void, count: SizeT, offset: OffT) -> SSizeT;
fn pwrite(fd: RawFd, buf: *mut c_void, count: SizeT, offset: OffT) -> SSizeT;
}
pub fn read_bytes_at(buffer: &mut Vec<u8>, file: &File, mut offset: u64) -> Result<(), ReadError> {
let mut data_read = 0;
let fd = file.as_raw_fd();
while data_read < buffer.len() {
let sz = buffer.len() - data_read as usize;
data_read += unsafe {
let ret = pread(
fd,
buffer.as_mut_ptr().offset(data_read as isize) as *mut c_void,
sz as SizeT,
offset as OffT,
);
if ret < 0 {
return Err(ReadError::Other(format!(
"{:?}",
std::io::Error::last_os_error()
)));
} else {
ret as usize
}
};
offset += data_read as u64;
}
Ok(())
}
pub fn write_bytes_at(buffer: &Vec<u8>, file: &File, mut offset: u64) -> Result<(), WriteError> {
let fd = file.as_raw_fd();
let mut written = 0;
while written < buffer.len() {
let sz = buffer.len() - written as usize;
written += unsafe {
let ret = pwrite(
fd,
buffer.as_ptr().offset(written as isize) as *mut c_void,
sz as SizeT,
offset as OffT,
);
if ret < 0 {
return Err(WriteError::Other(format!(
"{:?}",
std::io::Error::last_os_error()
)));
} else {
ret as usize
}
};
offset += written as u64;
}
Ok(())
}