use std::fs::File;
use std::io;
#[cfg(unix)]
pub(crate) fn read_exact_at(file: &File, buf: &mut [u8], offset: u64) -> io::Result<()> {
use std::os::unix::fs::FileExt;
file.read_exact_at(buf, offset)
}
#[cfg(unix)]
pub(crate) fn write_all_at(file: &File, buf: &[u8], offset: u64) -> io::Result<()> {
use std::os::unix::fs::FileExt;
file.write_all_at(buf, offset)
}
#[cfg(windows)]
pub(crate) fn read_exact_at(file: &File, mut buf: &mut [u8], mut offset: u64) -> io::Result<()> {
use std::os::windows::fs::FileExt;
while !buf.is_empty() {
match file.seek_read(buf, offset) {
Ok(0) => {
return Err(io::Error::new(
io::ErrorKind::UnexpectedEof,
"reached end of file before the buffer was filled",
));
}
Ok(n) => {
let advanced = buf;
buf = &mut advanced[n..];
offset += n as u64;
}
Err(ref e) if e.kind() == io::ErrorKind::Interrupted => {}
Err(e) => return Err(e),
}
}
Ok(())
}
#[cfg(windows)]
pub(crate) fn write_all_at(file: &File, mut buf: &[u8], mut offset: u64) -> io::Result<()> {
use std::os::windows::fs::FileExt;
while !buf.is_empty() {
match file.seek_write(buf, offset) {
Ok(0) => {
return Err(io::Error::new(
io::ErrorKind::WriteZero,
"wrote zero bytes before the buffer was drained",
));
}
Ok(n) => {
buf = &buf[n..];
offset += n as u64;
}
Err(ref e) if e.kind() == io::ErrorKind::Interrupted => {}
Err(e) => return Err(e),
}
}
Ok(())
}
#[cfg(not(any(unix, windows)))]
compile_error!(
"bison-db's file store needs positional file I/O, which std provides only on \
Unix and Windows targets; disable the `std` feature to use the in-memory \
document model alone"
);