1use crate::bindings;
14use crate::error::{Error, Result};
15
16pub const O_READ: i32 = bindings::OVE_FS_O_READ as i32;
18pub const O_WRITE: i32 = bindings::OVE_FS_O_WRITE as i32;
20pub const O_CREATE: i32 = bindings::OVE_FS_O_CREATE as i32;
22pub const O_APPEND: i32 = bindings::OVE_FS_O_APPEND as i32;
24
25pub fn mount(dev: Option<&[u8]>, mnt: Option<&[u8]>) -> Result<()> {
29 let dev_ptr = dev.map_or(core::ptr::null(), |d| d.as_ptr() as *const _);
30 let mnt_ptr = mnt.map_or(core::ptr::null(), |m| m.as_ptr() as *const _);
31 let rc = unsafe { bindings::ove_fs_mount(dev_ptr, mnt_ptr) };
32 Error::from_code(rc)
33}
34
35pub struct File {
37 handle: bindings::ove_file_t,
38}
39
40impl File {
41 pub fn open(path: &[u8], flags: i32) -> Result<Self> {
43 let mut handle: bindings::ove_file_t = core::ptr::null_mut();
44 let rc =
45 unsafe { bindings::ove_fs_open(&mut handle, path.as_ptr() as *const _, flags) };
46 Error::from_code(rc)?;
47 Ok(Self { handle })
48 }
49
50 pub fn read(&self, buf: &mut [u8]) -> Result<usize> {
52 let mut bytes_read: usize = 0;
53 let rc = unsafe {
54 bindings::ove_fs_read(
55 self.handle,
56 buf.as_mut_ptr() as *mut _,
57 buf.len(),
58 &mut bytes_read,
59 )
60 };
61 Error::from_code(rc)?;
62 Ok(bytes_read)
63 }
64
65 pub fn write(&self, buf: &[u8]) -> Result<usize> {
67 let mut bytes_written: usize = 0;
68 let rc = unsafe {
69 bindings::ove_fs_write(
70 self.handle,
71 buf.as_ptr() as *const _,
72 buf.len(),
73 &mut bytes_written,
74 )
75 };
76 Error::from_code(rc)?;
77 Ok(bytes_written)
78 }
79}
80
81impl Drop for File {
82 fn drop(&mut self) {
83 unsafe { bindings::ove_fs_close(self.handle) };
84 }
85}
86
87unsafe impl Send for File {}
90
91pub struct DirEntry {
93 inner: bindings::ove_dirent,
94}
95
96impl DirEntry {
97 pub fn name(&self) -> &[u8] {
99 let name_bytes = unsafe {
100 core::slice::from_raw_parts(self.inner.name.as_ptr() as *const u8, self.inner.name.len())
101 };
102 cstr_to_slice(name_bytes)
103 }
104
105 pub fn size(&self) -> u32 {
107 self.inner.size
108 }
109
110 pub fn is_dir(&self) -> bool {
112 self.inner.is_dir != 0
113 }
114}
115
116pub struct Dir {
118 handle: bindings::ove_dir_t,
119}
120
121impl Dir {
122 pub fn open(path: &[u8]) -> Result<Self> {
124 let mut handle: bindings::ove_dir_t = core::ptr::null_mut();
125 let rc =
126 unsafe { bindings::ove_fs_opendir(&mut handle, path.as_ptr() as *const _) };
127 Error::from_code(rc)?;
128 Ok(Self { handle })
129 }
130
131 pub fn read_entry(&mut self) -> Result<Option<DirEntry>> {
137 let mut entry: bindings::ove_dirent = unsafe { core::mem::zeroed() };
138 let rc = unsafe { bindings::ove_fs_readdir(self.handle, &mut entry) };
139 if rc != 0 || entry.name[0] == 0 {
140 return Ok(None);
141 }
142 Ok(Some(DirEntry { inner: entry }))
143 }
144}
145
146impl Drop for Dir {
147 fn drop(&mut self) {
148 unsafe { bindings::ove_fs_closedir(self.handle) };
149 }
150}
151
152unsafe impl Send for Dir {}
155
156fn cstr_to_slice(buf: &[u8]) -> &[u8] {
157 let mut len = 0;
158 while len < buf.len() && buf[len] != 0 {
159 len += 1;
160 }
161 &buf[..len]
162}