//! Simple File System for Aios //! //! Provides basic file operations for package installation and management #![allow(dead_code)] /// Simple file entry #[derive(Debug, Clone, Copy)] pub struct FileEntry { pub name: [u8; 32], pub size: usize, pub file_type: FileType, pub data_offset: usize, } #[derive(Debug, Clone, Copy, PartialEq)] pub enum FileType { Regular, Directory, Executable, } /// Simple in-memory file system pub struct SimpleFS { files: [Option; 64], file_count: usize, data_storage: [u8; 2048], // 2KB storage (reduced from 8KB) data_used: usize, } impl SimpleFS { pub fn new() -> Self { SimpleFS { files: [None; 64], file_count: 0, data_storage: [0; 2048], data_used: 0, } } /// Create a file pub fn create_file(&mut self, name: &str, content: &[u8], file_type: FileType) -> Result<(), &'static str> { if self.file_count >= 64 { return Err("File system full"); } if name.len() > 31 { return Err("Filename too long"); } if self.data_used + content.len() > self.data_storage.len() { return Err("Not enough storage space"); } // Check if file already exists if self.find_file(name).is_some() { return Err("File already exists"); } // Create file entry let mut file_name = [0u8; 32]; let name_bytes = name.as_bytes(); for i in 0..name_bytes.len() { file_name[i] = name_bytes[i]; } let file_entry = FileEntry { name: file_name, size: content.len(), file_type, data_offset: self.data_used, }; // Store file data for i in 0..content.len() { self.data_storage[self.data_used + i] = content[i]; } self.data_used += content.len(); // Add file entry self.files[self.file_count] = Some(file_entry); self.file_count += 1; Ok(()) } /// Find a file by name pub fn find_file(&self, name: &str) -> Option<&FileEntry> { for i in 0..self.file_count { if let Some(file) = &self.files[i] { if self.str_eq(&file.name, name) { return Some(file); } } } None } /// List all files pub fn list_files(&self) -> &[Option] { &self.files[..self.file_count] } /// Read file content pub fn read_file(&self, name: &str) -> Option<&[u8]> { if let Some(file) = self.find_file(name) { let start = file.data_offset; let end = start + file.size; Some(&self.data_storage[start..end]) } else { None } } /// Delete a file pub fn delete_file(&mut self, name: &str) -> Result<(), &'static str> { let mut found_index = None; for i in 0..self.file_count { if let Some(file) = &self.files[i] { if self.str_eq(&file.name, name) { found_index = Some(i); break; } } } if let Some(index) = found_index { // Remove file by shifting array for i in index..self.file_count.saturating_sub(1) { self.files[i] = self.files[i + 1]; } self.files[self.file_count - 1] = None; self.file_count -= 1; Ok(()) } else { Err("File not found") } } /// Get file count pub fn file_count(&self) -> usize { self.file_count } /// Helper function to compare string with byte array fn str_eq(&self, arr: &[u8; 32], s: &str) -> bool { let s_bytes = s.as_bytes(); if s_bytes.len() > 32 { return false; } // Find the end of the string in the array (null terminator) let mut arr_len = 0; for i in 0..32 { if arr[i] == 0 { break; } arr_len += 1; } if arr_len != s_bytes.len() { return false; } for i in 0..arr_len { if arr[i] != s_bytes[i] { return false; } } true } /// Get filename as string pub fn filename_str(file: &FileEntry) -> &str { let mut len = 0; for i in 0..32 { if file.name[i] == 0 { break; } len += 1; } core::str::from_utf8(&file.name[..len]).unwrap_or("") } } impl FileType { pub fn as_str(&self) -> &'static str { match self { FileType::Regular => "file", FileType::Directory => "dir", FileType::Executable => "exec", } } }