use anyhow as ah;
use std::path::Path;
#[cfg(not(target_os = "windows"))]
mod linux;
#[cfg(target_os = "windows")]
mod windows;
pub const DEFAULT_SECTOR_SIZE: u32 = 512;
trait RawIoOsIntf {
fn get_sector_size(&self) -> Option<u32>;
fn drop_file_caches(&mut self, offset: u64, size: u64) -> ah::Result<()>;
fn close(&mut self) -> ah::Result<()>;
fn sync(&mut self) -> ah::Result<()>;
fn set_len(&mut self, size: u64) -> ah::Result<()>;
fn seek(&mut self, offset: u64) -> ah::Result<u64>;
fn read(&mut self, buffer: &mut [u8]) -> ah::Result<RawIoResult>;
fn write(&mut self, buffer: &[u8]) -> ah::Result<RawIoResult>;
}
pub enum RawIoResult {
Ok(usize),
Enospc,
}
pub struct RawIo {
os: Box<dyn RawIoOsIntf>,
}
impl RawIo {
pub fn new(path: &Path, create: bool, read: bool, write: bool) -> ah::Result<Self> {
#[cfg(not(target_os = "windows"))]
let os = Box::new(linux::RawIoLinux::new(path, create, read, write)?);
#[cfg(target_os = "windows")]
let os = Box::new(windows::RawIoWindows::new(path, create, read, write)?);
Ok(Self { os })
}
pub fn get_sector_size(&self) -> Option<u32> {
self.os.get_sector_size()
}
pub fn drop_file_caches(mut self, offset: u64, size: u64) -> ah::Result<()> {
self.os.drop_file_caches(offset, size)
}
pub fn close(&mut self) -> ah::Result<()> {
self.os.close()
}
pub fn sync(&mut self) -> ah::Result<()> {
self.os.sync()
}
#[cfg_attr(not(test), allow(dead_code))]
pub fn set_len(&mut self, size: u64) -> ah::Result<()> {
self.os.set_len(size)
}
pub fn seek(&mut self, offset: u64) -> ah::Result<u64> {
self.os.seek(offset)
}
pub fn read(&mut self, buffer: &mut [u8]) -> ah::Result<RawIoResult> {
self.os.read(buffer)
}
pub fn write(&mut self, buffer: &[u8]) -> ah::Result<RawIoResult> {
self.os.write(buffer)
}
}