1#[cfg(not(any(target_os = "linux", target_os = "android", target_os = "windows")))]
13std::compile_error!(
14 "Your operating system is not supported, yet. \
15 Please open an issue on GitHub: \
16 https://github.com/mbuesch/disktest/issues"
17);
18
19use anyhow as ah;
20use std::path::Path;
21
22#[cfg(any(target_os = "linux", target_os = "android"))]
23mod linux;
24
25#[cfg(target_os = "windows")]
26mod windows;
27
28pub const DEFAULT_SECTOR_SIZE: u32 = 512;
29
30trait RawIoOsIntf {
32 fn get_sector_size(&self) -> Option<u32>;
33 fn drop_file_caches(&mut self, offset: u64, size: u64) -> ah::Result<()>;
34 fn close(&mut self) -> ah::Result<()>;
35 fn sync(&mut self) -> ah::Result<()>;
36 fn set_len(&mut self, size: u64) -> ah::Result<()>;
37 fn seek(&mut self, offset: u64) -> ah::Result<u64>;
38 fn read(&mut self, buffer: &mut [u8]) -> ah::Result<RawIoResult>;
39 fn write(&mut self, buffer: &[u8]) -> ah::Result<RawIoResult>;
40}
41
42pub enum RawIoResult {
44 Ok(usize),
46 Enospc,
48}
49
50pub struct RawIo {
52 os: Box<dyn RawIoOsIntf>,
53}
54
55impl RawIo {
56 pub fn new(path: &Path, create: bool, read: bool, write: bool) -> ah::Result<Self> {
58 #[cfg(any(target_os = "linux", target_os = "android"))]
59 let os = Box::new(linux::RawIoLinux::new(path, create, read, write)?);
60
61 #[cfg(target_os = "windows")]
62 let os = Box::new(windows::RawIoWindows::new(path, create, read, write)?);
63
64 Ok(Self { os })
65 }
66
67 pub fn get_sector_size(&self) -> Option<u32> {
70 self.os.get_sector_size()
71 }
72
73 pub fn drop_file_caches(mut self, offset: u64, size: u64) -> ah::Result<()> {
76 self.os.drop_file_caches(offset, size)
77 }
78
79 pub fn close(&mut self) -> ah::Result<()> {
82 self.os.close()
83 }
84
85 pub fn sync(&mut self) -> ah::Result<()> {
88 self.os.sync()
89 }
90
91 #[cfg_attr(not(test), allow(dead_code))]
92 pub fn set_len(&mut self, size: u64) -> ah::Result<()> {
93 self.os.set_len(size)
94 }
95
96 pub fn seek(&mut self, offset: u64) -> ah::Result<u64> {
98 self.os.seek(offset)
99 }
100
101 pub fn read(&mut self, buffer: &mut [u8]) -> ah::Result<RawIoResult> {
103 self.os.read(buffer)
104 }
105
106 pub fn write(&mut self, buffer: &[u8]) -> ah::Result<RawIoResult> {
108 self.os.write(buffer)
109 }
110}
111
112