fix
This commit is contained in:
196
kernel/src/filesystem.rs
Normal file
196
kernel/src/filesystem.rs
Normal file
@ -0,0 +1,196 @@
|
||||
//! 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",
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user