1use std::collections::HashMap;
2use std::sync::{Arc, Mutex};
3use std::io::{Read, Write, Seek, SeekFrom};
4use std::path::PathBuf;
5
6pub type Inode = u64;
7
8pub type FileDescriptor = i32;
22
23#[derive(Debug)]
24pub struct File {
25 pub inode: Inode,
26 pub data: Mutex<Vec<u8>>,
27 pub position: u64,
28 pub path: PathBuf
29}
30
31pub struct OpenFile {
32 pub file: Arc<File>,
33 pub position: u64,
34}
35
36impl Read for OpenFile {
37 fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
38 let file_data = &self.file.data.lock().unwrap();
39 let bytes_to_read = std::cmp::min(buf.len(), (file_data.len() - self.position as usize));
40 buf[..bytes_to_read].copy_from_slice(&file_data[self.position as usize..(self.position + bytes_to_read as u64) as usize]);
41 self.position += bytes_to_read as u64;
42 Ok(bytes_to_read)
43 }
44}
45
46impl Write for OpenFile {
47 fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
48 let mut file_data = self.file.data.lock().unwrap();
49 let new_size = std::cmp::max(file_data.len(), self.position as usize + buf.len());
50 file_data.resize(new_size, 0);
51 file_data[self.position as usize..self.position as usize + buf.len()]
52 .copy_from_slice(buf);
53 self.position += buf.len() as u64;
54 Ok(buf.len())
55 }
56
57 fn flush(&mut self) -> std::io::Result<()> {
58 Ok(())
59 }
60}
61
62pub struct FileSystem {
63 pub files: HashMap<Inode, Arc<File>>,
64 pub inodes: Inode,
65}
66
67impl FileSystem {
68 pub fn new() -> Self {
69 Self {
70 files: HashMap::new(),
71 inodes: 1,
72 }
73 }
74
75 pub fn lookup_inode(&mut self, path: &PathBuf) -> Option<Inode> {
76 let inode = self.files
77 .iter()
78 .find_map(|(&inode, file)| if file.path == *path { Some(inode) } else { None });
79 if inode == None {
80 return Some(self.create_file(Vec::new()))
81 } else {
82 None
83 }
84 }
85
86 pub fn create_file(&mut self, raw_data: Vec<u8>) -> Inode {
87 let inode = self.inodes;
88 let data = Mutex::new(raw_data);
89 let mut path = PathBuf::new();
90 let mut position = 0;
91 let file = File { inode, data, path, position};
92 self.files.insert(inode, Arc::new(file));
93 self.inodes += 1;
94 inode
95 }
96}
97