Done for the day.

This commit is contained in:
Bas Wiel, van de 2024-05-09 19:44:29 +02:00
parent 9fe9a4a2e0
commit f12061474d
3 changed files with 49 additions and 82 deletions

View File

@ -7,7 +7,7 @@ use crate::{
},
downloader::ZipDownloader,
fat::{
direntry::{DirEntry, DirEntryType, Node, NodeId},
direntry::{DirEntry, NodeId},
vbr::Vbr,
Fat,
},
@ -119,8 +119,13 @@ impl DiskBuilder {
/// Writes an entry (file or directory) to storage based on its allocated clusters.
pub fn write_entry_to_storage(&mut self, entry_id: NodeId) -> Result<(), std::io::Error> {
let entry = &self.filesystem.arena.get_node(entry_id)
.ok_or_else(|| std::io::Error::new(std::io::ErrorKind::NotFound, "Entry node not found"))?
let entry = &self
.filesystem
.arena
.get_node(entry_id)
.ok_or_else(|| {
std::io::Error::new(std::io::ErrorKind::NotFound, "Entry node not found")
})?
.value;
let bytes = entry.get_data(); // Ensure this returns a &[u8]

View File

@ -246,7 +246,8 @@ impl Fat {
let vbr_lba = vbr_address.to_lba(&disk_geometry)?;
let vbr_bytes = disk.read_sector(vbr_lba)?;
let mut arena = Arena::new();
let root_directory = arena.insert_node(Node::new_directory("rootdir", Vec::new().as_slice()));
let root_directory =
arena.insert_node(Node::new_directory("rootdir", Vec::new().as_slice()));
if vbr_bytes[0] == 0 {
return Err(std::io::Error::new(
std::io::ErrorKind::Other,
@ -353,23 +354,33 @@ impl Fat {
self.allocation_table.mark_end_of_chain(*last)?;
}
// Create a new directory entry
let new_file = DirEntry::new(
filename,
entry_type,
None,
&allocated_clusters,
data.len() as u32,
Some(data),
)?;
// Insert the new file into the arena and get its NodeId
let file_id = self.arena.insert_node(Node::new_directory(filename, allocated_clusters.as_slice()));
let node_id = match entry_type {
DirEntryType::Directory => self
.arena
.insert_node(Node::new_directory(filename, allocated_clusters.as_slice())),
DirEntryType::File => self.arena.insert_node(Node::new_file(
filename,
None,
allocated_clusters,
data.len() as u32,
data.to_vec(),
false,
)?),
DirEntryType::SysFile => self.arena.insert_node(Node::new_file(
filename,
None,
allocated_clusters,
data.len() as u32,
data.to_vec(),
true,
)?),
};
// Add the new entry to the parent directory or use the root directory
if let Some(pid) = parent_id {
if let Some(parent_node) = self.arena.get_node_mut(pid) {
parent_node.value.children.push(file_id);
parent_node.value.children.push(node_id);
} else {
return Err(std::io::Error::new(
std::io::ErrorKind::NotFound,
@ -379,7 +390,7 @@ impl Fat {
} else {
self.arena
.get_node_mut(self.root_directory)
.map(|root| root.value.children.push(file_id));
.map(|root| root.value.children.push(node_id));
}
Ok(())

View File

@ -50,13 +50,6 @@ impl Node<DirEntry> {
data: Vec<u8>,
sysfile: bool, // Indicates whether the file is a system file or regular file
) -> Result<Self, std::io::Error> {
// Determine the DirEntryType based on sysfile flag
let entry_type = if sysfile {
DirEntryType::SysFile
} else {
DirEntryType::File
};
// Create the file entry using the DirEntry's create method
let file_entry = DirEntry::create_file(
filename,
@ -64,6 +57,7 @@ impl Node<DirEntry> {
&allocated_clusters,
file_size,
data,
sysfile,
)?;
// Return the new Node encapsulating the DirEntry
@ -147,7 +141,6 @@ pub enum DirEntryType {
File,
SysFile,
Directory,
RootDirectory,
}
impl fmt::Display for DirEntryType {
@ -155,7 +148,6 @@ impl fmt::Display for DirEntryType {
match self {
DirEntryType::Directory => write!(f, "Subdirectory"),
DirEntryType::File => write!(f, "Regular file"),
DirEntryType::RootDirectory => write!(f, "Root Directory"),
DirEntryType::SysFile => write!(f, "System file"),
}
}
@ -192,53 +184,19 @@ impl DirEntry {
allocated_clusters,
file_size,
data.unwrap().to_vec(),
false,
),
DirEntryType::SysFile => Self::create_sysfile(
DirEntryType::SysFile => Self::create_file(
filename,
create_timedate,
file_size,
allocated_clusters,
data,
file_size,
data.unwrap().to_vec(),
true,
),
DirEntryType::Directory => {
Self::create_directory(filename, create_timedate, allocated_clusters)
}
DirEntryType::RootDirectory => Self::create_rootdir(),
}
}
/// Deliver a standard system file with attribs System, Hidden and ReadOnly set plus sensible values for a file.
/// If you don't provide a TimeDate, the current system time on the host machine will be used.
fn create_sysfile(
filename: &str,
create_timedate: Option<TimeDate>,
file_size: u32,
allocated_clusters: &Vec<u32>,
data: Option<&[u8]>,
) -> Result<Self, std::io::Error> {
// Set of attributes appropriate for a system file
let attributes = Attributes::new(true, true, true, true, false, false, false);
match create_timedate {
None => Ok(DirEntry {
filename: FileName::new(filename)?,
attributes,
create_timedate: TimeDate::now(),
file_size,
entry_type: DirEntryType::SysFile,
children: Vec::new(),
allocated_clusters: allocated_clusters.to_vec(),
data: data.unwrap().to_vec(),
}),
_ => Ok(DirEntry {
filename: FileName::new(filename)?,
attributes,
create_timedate: create_timedate.unwrap(),
file_size,
entry_type: DirEntryType::SysFile,
children: Vec::new(),
allocated_clusters: allocated_clusters.to_vec(),
data: data.unwrap().to_vec(),
}),
}
}
@ -250,9 +208,16 @@ impl DirEntry {
allocated_clusters: &[u32],
file_size: u32,
data: Vec<u8>,
sysfile: bool,
) -> Result<Self, std::io::Error> {
// Set of attributes appropriate to a regular file
let attributes = Attributes::new(true, false, false, false, false, false, false);
let attributes = match sysfile {
true => Attributes::new(true, false, false, false, false, false, false),
false => Attributes::new(true, true, true, true, false, false, false),
};
let entry_type = match sysfile {
true => DirEntryType::SysFile,
false => DirEntryType::File,
};
// Either use the provided TimeDate or get the current system TimeDate
let effective_timedate = create_timedate.unwrap_or_else(TimeDate::now);
@ -265,7 +230,7 @@ impl DirEntry {
attributes,
create_timedate: effective_timedate,
file_size,
entry_type: DirEntryType::File,
entry_type,
children: Vec::new(),
allocated_clusters: allocated_clusters.to_vec(),
data,
@ -274,19 +239,6 @@ impl DirEntry {
}
}
fn create_rootdir() -> Result<Self, std::io::Error> {
Ok(DirEntry {
filename: FileName::new("ROOTDIR")?,
attributes: Attributes::new(false, false, false, false, false, true, false),
create_timedate: TimeDate::now(),
file_size: 0,
entry_type: DirEntryType::RootDirectory,
children: Vec::new(),
allocated_clusters: Vec::new(),
data: Vec::new(),
})
}
fn create_directory(
filename: &str,
create_timedate: Option<TimeDate>,
@ -515,7 +467,6 @@ impl DirEntry {
pub fn is_directory(&self) -> bool {
match self.get_type() {
DirEntryType::Directory => true,
DirEntryType::RootDirectory => true,
_ => false,
}
}