196 lines
4.9 KiB
Rust
196 lines
4.9 KiB
Rust
//! 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<FileEntry>; 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<FileEntry>] {
|
|
&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",
|
|
}
|
|
}
|
|
} |