1#[cfg(feature = "alloc")]
4use alloc::boxed::Box;
5#[cfg(feature = "alloc")]
6use alloc::vec;
7use firefly_rust::*;
8
9#[cfg(feature = "alloc")]
10pub struct DirBuf {
11 raw: Box<[u8]>,
12}
13
14#[cfg(feature = "alloc")]
15impl DirBuf {
16 #[must_use]
18 pub fn list_dirs(name: &str) -> Self {
19 let size = Dir::list_dirs_buf_size(name);
20 let mut buf = vec![0; size];
21 Dir::list_dirs(name, &mut buf);
22 Self {
23 raw: buf.into_boxed_slice(),
24 }
25 }
26
27 #[must_use]
29 pub fn list_files(name: &str) -> Self {
30 let size = Dir::list_files_buf_size(name);
31 let mut buf = vec![0; size];
32 Dir::list_files(name, &mut buf);
33 Self {
34 raw: buf.into_boxed_slice(),
35 }
36 }
37
38 #[must_use]
40 pub fn iter(&self) -> DirIter<'_> {
41 DirIter { raw: &self.raw }
42 }
43}
44
45pub struct Dir<'a> {
46 raw: &'a [u8],
47}
48
49impl<'a> Dir<'a> {
50 #[must_use]
51 pub fn list_dirs_buf_size(name: &str) -> usize {
52 let path_ptr = name.as_ptr();
53 let size = unsafe { b::list_dirs_buf_size(path_ptr as u32, name.len() as u32) };
54 size as usize
55 }
56
57 #[must_use]
58 pub fn list_files_buf_size(name: &str) -> usize {
59 let path_ptr = name.as_ptr();
60 let size = unsafe { b::list_files_buf_size(path_ptr as u32, name.len() as u32) };
61 size as usize
62 }
63
64 pub fn list_dirs(name: &str, buf: &'a mut [u8]) -> Self {
65 let path_ptr = name.as_ptr();
66 let buf_ptr = buf.as_mut_ptr();
67 unsafe {
68 b::list_dirs(
69 path_ptr as u32,
70 name.len() as u32,
71 buf_ptr as u32,
72 buf.len() as u32,
73 );
74 }
75 Self { raw: buf }
76 }
77
78 pub fn list_files(name: &str, buf: &'a mut [u8]) -> Self {
79 let path_ptr = name.as_ptr();
80 let buf_ptr = buf.as_mut_ptr();
81 unsafe {
82 b::list_files(
83 path_ptr as u32,
84 name.len() as u32,
85 buf_ptr as u32,
86 buf.len() as u32,
87 );
88 }
89 Self { raw: buf }
90 }
91
92 #[must_use]
94 pub const fn iter(&self) -> DirIter<'a> {
95 DirIter { raw: self.raw }
96 }
97}
98
99pub struct DirIter<'a> {
100 raw: &'a [u8],
101}
102
103impl<'a> Iterator for DirIter<'a> {
104 type Item = &'a str;
105
106 fn next(&mut self) -> Option<Self::Item> {
107 let len = self.raw.first()?;
108 let len = *len as usize;
109 let raw_name = self.raw.get(1..=len)?;
110 let name = core::str::from_utf8(raw_name).unwrap_or("");
114 self.raw = self.raw.get((len + 1)..).unwrap_or(&[]);
115 Some(name)
116 }
117}
118
119pub fn run_app(author_id: &str, app_id: &str) {
124 let author_ptr = author_id.as_ptr() as u32;
125 let app_ptr = app_id.as_ptr() as u32;
126 let author_len = author_id.len() as u32;
127 let app_len = app_id.len() as u32;
128 unsafe {
129 b::run_app(author_ptr, author_len, app_ptr, app_len);
130 }
131}
132
133#[must_use]
134pub fn get_file_size(path: &str) -> usize {
135 let path_ptr = path.as_ptr() as u32;
136 let path_len = path.len() as u32;
137 let size = unsafe { b::get_file_size(path_ptr, path_len) };
138 size as usize
139}
140
141pub fn load_file<'a>(path: &str, buf: &'a mut [u8]) -> FileRef<'a> {
146 let path_ptr = path.as_ptr() as u32;
147 let path_len = path.len() as u32;
148 let buf_ptr = buf.as_mut_ptr() as u32;
149 let buf_len = buf.len() as u32;
150 unsafe {
151 b::load_file(path_ptr, path_len, buf_ptr, buf_len);
152 }
153 unsafe { FileRef::from_bytes(buf) }
154}
155
156#[cfg(feature = "alloc")]
160#[must_use]
161pub fn load_file_buf(path: &str) -> Option<FileBuf> {
162 let size = get_file_size(path);
163 if size == 0 {
164 return None;
165 }
166 let mut buf = vec![0u8; size];
167 let path_ptr = path.as_ptr() as u32;
168 let path_len = path.len() as u32;
169 let buf_ptr = buf.as_mut_ptr() as u32;
170 let buf_len = buf.len() as u32;
171 unsafe {
172 b::load_file(path_ptr, path_len, buf_ptr, buf_len);
173 }
174 let buf = buf.into_boxed_slice();
175 Some(unsafe { FileBuf::from_bytes(buf) })
176}
177
178pub fn dump_file(path: &str, buf: &[u8]) {
179 let path_ptr = path.as_ptr() as u32;
180 let path_len = path.len() as u32;
181 let buf_ptr = buf.as_ptr() as u32;
182 let buf_len = buf.len() as u32;
183 unsafe {
184 b::dump_file(path_ptr, path_len, buf_ptr, buf_len);
185 }
186}
187
188pub fn append_file(path: &str, buf: &[u8]) {
189 let path_ptr = path.as_ptr() as u32;
190 let path_len = path.len() as u32;
191 let buf_ptr = buf.as_ptr() as u32;
192 let buf_len = buf.len() as u32;
193 unsafe {
194 b::append_file(path_ptr, path_len, buf_ptr, buf_len);
195 }
196}
197
198pub fn remove_file(path: &str) {
199 let path_ptr = path.as_ptr() as u32;
200 let path_len = path.len() as u32;
201 unsafe {
202 b::remove_file(path_ptr, path_len);
203 }
204}
205
206pub fn remove_dir(path: &str) {
207 let path_ptr = path.as_ptr() as u32;
208 let path_len = path.len() as u32;
209 unsafe {
210 b::remove_dir(path_ptr, path_len);
211 }
212}
213
214pub fn create_dir(path: &str) {
215 let path_ptr = path.as_ptr() as u32;
216 let path_len = path.len() as u32;
217 unsafe {
218 b::create_dir(path_ptr, path_len);
219 }
220}
221
222#[must_use]
224pub fn write_partition(part: u8, path: &str) -> bool {
225 let path_ptr = path.as_ptr() as u32;
226 let path_len = path.len() as u32;
227 let code = unsafe { b::write_partition(u32::from(part), path_ptr, path_len) };
228 code == 0
229}
230
231pub fn switch_partition(part: u8) {
232 unsafe {
233 b::switch_partition(u32::from(part));
234 }
235}
236
237mod b {
239 #[link(wasm_import_module = "sudo")]
240 unsafe extern "C" {
241 pub(super) unsafe fn list_dirs_buf_size(path_ptr: u32, path_len: u32) -> u32;
242 pub(super) unsafe fn list_dirs(
243 path_ptr: u32,
244 path_len: u32,
245 buf_ptr: u32,
246 buf_len: u32,
247 ) -> u32;
248 pub(super) unsafe fn list_files_buf_size(path_ptr: u32, path_len: u32) -> u32;
249 pub(super) unsafe fn list_files(
250 path_ptr: u32,
251 path_len: u32,
252 buf_ptr: u32,
253 buf_len: u32,
254 ) -> u32;
255 pub(super) unsafe fn run_app(author_ptr: u32, author_len: u32, app_ptr: u32, app_len: u32);
256 pub(super) unsafe fn get_file_size(path_ptr: u32, path_len: u32) -> u32;
257 pub(super) unsafe fn load_file(
258 path_ptr: u32,
259 path_len: u32,
260 buf_ptr: u32,
261 buf_len: u32,
262 ) -> u32;
263 pub(super) unsafe fn dump_file(
264 path_ptr: u32,
265 path_len: u32,
266 buf_ptr: u32,
267 buf_len: u32,
268 ) -> u32;
269 pub(super) unsafe fn append_file(
270 path_ptr: u32,
271 path_len: u32,
272 buf_ptr: u32,
273 buf_len: u32,
274 ) -> u32;
275 pub(super) unsafe fn remove_file(path_ptr: u32, path_len: u32);
276 pub(super) unsafe fn remove_dir(path_ptr: u32, path_len: u32);
277 pub(super) unsafe fn create_dir(path_ptr: u32, path_len: u32);
278 pub(super) unsafe fn write_partition(part: u32, path_ptr: u32, path_len: u32) -> u32;
279 pub(super) unsafe fn switch_partition(part: u32);
280 }
281}