1use core::cell::Cell;
2
3use crate::Inode;
4use alloc::string::String;
5use alloc::sync::Arc;
6use alloc::vec::Vec;
7use bitflags::*;
8
9pub struct UserBuffer {
15 pub buffers: Vec<&'static mut [u8]>,
17}
18
19impl UserBuffer {
20 pub fn new(buffers: Vec<&'static mut [u8]>) -> Self {
22 Self { buffers }
23 }
24 pub fn len(&self) -> usize {
26 let mut total: usize = 0;
27 for b in self.buffers.iter() {
28 total += b.len();
29 }
30 total
31 }
32
33 pub fn is_empty(&self) -> bool {
35 self.buffers.is_empty()
36 }
37}
38
39impl IntoIterator for UserBuffer {
40 type Item = *mut u8;
41 type IntoIter = UserBufferIterator;
42 fn into_iter(self) -> Self::IntoIter {
43 UserBufferIterator {
45 buffers: self.buffers,
46 current_buffer: 0,
47 current_idx: 0,
48 }
49 }
50}
51
52pub struct UserBufferIterator {
54 buffers: Vec<&'static mut [u8]>,
55 current_buffer: usize,
56 current_idx: usize,
57}
58
59impl Iterator for UserBufferIterator {
60 type Item = *mut u8;
61 fn next(&mut self) -> Option<Self::Item> {
62 if self.current_buffer >= self.buffers.len() {
63 None
64 } else {
65 let r = &mut self.buffers[self.current_buffer][self.current_idx] as *mut _;
67 if self.current_idx + 1 == self.buffers[self.current_buffer].len() {
68 self.current_idx = 0;
69 self.current_buffer += 1;
70 } else {
71 self.current_idx += 1;
72 }
73 Some(r)
74 }
75 }
76}
77
78bitflags! {
79 pub struct OpenFlags: u32 {
81 const RDONLY = 0;
83 const WRONLY = 1 << 0;
85 const RDWR = 1 << 1;
87 const CREATE = 1 << 9;
89 const TRUNC = 1 << 10;
91 }
92}
93
94impl OpenFlags {
95 pub fn read_write(&self) -> (bool, bool) {
98 if self.is_empty() {
100 (true, false)
101 } else if self.contains(Self::WRONLY) {
102 (false, true)
103 } else {
104 (true, true)
105 }
106 }
107}
108
109#[derive(Clone)]
111pub struct FileHandle {
112 pub inode: Option<Arc<Inode>>,
114 pub read: bool,
116 pub write: bool,
118 pub offset: Cell<usize>,
120}
121
122impl FileHandle {
123 pub fn new(read: bool, write: bool, inode: Arc<Inode>) -> Self {
125 Self {
126 inode: Some(inode),
127 read,
128 write,
129 offset: Cell::new(0),
130 }
131 }
132
133 pub fn empty(read: bool, write: bool) -> Self {
135 Self {
136 inode: None,
137 read,
138 write,
139 offset: Cell::new(0),
140 }
141 }
142
143 pub fn readable(&self) -> bool {
145 self.read
146 }
147
148 pub fn writable(&self) -> bool {
150 self.write
151 }
152
153 pub fn read(&self, mut buf: UserBuffer) -> isize {
155 let mut total_read_size: usize = 0;
156 if let Some(inode) = &self.inode {
157 for slice in buf.buffers.iter_mut() {
159 let read_size = inode.read_at(self.offset.get(), slice);
160 if read_size == 0 {
161 break;
162 }
163 self.offset.set(self.offset.get() + read_size);
164 total_read_size += read_size;
165 }
166 total_read_size as _
167 } else {
168 -1
169 }
170 }
171
172 pub fn write(&self, buf: UserBuffer) -> isize {
174 let mut total_write_size: usize = 0;
175 if let Some(inode) = &self.inode {
176 for slice in buf.buffers.iter() {
178 let write_size = inode.write_at(self.offset.get(), slice);
179 assert_eq!(write_size, slice.len());
180 self.offset.set(self.offset.get() + write_size);
181 total_write_size += write_size;
182 }
183 total_write_size as _
184 } else {
185 -1
186 }
187 }
188}
189
190pub trait FSManager {
192 fn open(&self, path: &str, flags: OpenFlags) -> Option<Arc<FileHandle>>;
194
195 fn find(&self, path: &str) -> Option<Arc<Inode>>;
197
198 fn link(&self, src: &str, dst: &str) -> isize;
200
201 fn unlink(&self, path: &str) -> isize;
203
204 fn readdir(&self, path: &str) -> Option<Vec<String>>;
206}