Functionally things are working now. Let's clean up the mess!

This commit is contained in:
Bas Wiel, van de 2024-05-12 16:06:36 +02:00
parent f12061474d
commit b3b4f773c3
2 changed files with 46 additions and 33 deletions

View File

@ -7,7 +7,7 @@ use crate::{
},
downloader::ZipDownloader,
fat::{
direntry::{DirEntry, NodeId},
direntry::{DirEntry, DirEntryType, NodeId},
vbr::Vbr,
Fat,
},
@ -113,50 +113,57 @@ impl DiskBuilder {
/// and that `file.allocated_clusters` contains a valid list of disk addresses. It also
/// assumes that each address in `file.allocated_clusters` can hold a cluster of data
/// of size defined by `filesystem.get_sectors_per_cluster() * 512`.
pub fn write_file_to_storage(&mut self, file_id: NodeId) -> Result<(), std::io::Error> {
self.write_entry_to_storage(file_id)
}
/// 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")
})?
.value;
let cluster_size = self.get_cluster_size();
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 = &entry.value.clone();
let bytes = entry.get_data(); // Ensure this returns a &[u8]
if bytes.is_empty() {
return Ok(()); // If no data, nothing to write
let bytes = match entry.entry_type {
DirEntryType::File => entry.get_data().to_vec(),
DirEntryType::SysFile => entry.get_data().to_vec(),
DirEntryType::Directory => entry.children_bytes(&self.filesystem.arena)?,
};
if bytes.len() == 0 {
return Ok(());
}
let cluster_size = self.filesystem.get_sectors_per_cluster() * 512;
let chunks = bytes.chunks(cluster_size);
let addresses = &entry.allocated_clusters;
let chunks = bytes.chunks(cluster_size).collect::<Vec<_>>(); // Collect into Vec
let addresses = &entry.allocated_clusters; // Use a reference
if addresses.len() != chunks.len() {
// Ensure the number of allocated clusters matches the number of chunks
if entry.entry_type == DirEntryType::Directory {
if entry.directory_name() == "." || entry.directory_name() == ".." {
return Ok(());
}
}
/*if addresses.len() != chunks.len() && entry.entry_type != DirEntryType::Directory {
println!(
"We have {} clusters and {} chunks for {}",
addresses.len(),
chunks.len(), entry.directory_name()
);
return Err(std::io::Error::new(
std::io::ErrorKind::Other,
"Number of allocated clusters does not match the number of data chunks.",
));
}
}*/
let disk = &mut self.disk;
let partition = &mut self.partition;
// Write each chunk to its corresponding cluster
// Iterate over addresses and chunks to write data directly
for (address, chunk) in addresses.iter().zip(chunks) {
let mut sector: [u8; 512] = [0; 512]; // Create a buffer filled with zeros
sector[..chunk.len()].copy_from_slice(chunk); // Copy the chunk into the buffer
partition.write_sector(disk, *address, sector)?; // Now pass a reference to &[u8; 512]
// Call write_cluster using mutable filesystem
self.write_cluster(*address, chunk)?;
}
Ok(())
}
fn get_cluster_size(&self) -> usize {
self.filesystem.get_sectors_per_cluster() * 512
}
/// Writes the data of a cluster to the disk.
///
/// This method takes the data of a cluster, represented as a `&[u8]`, and writes it to the disk.
@ -407,6 +414,7 @@ impl DiskBuilder {
self.write_dirs()?;
self.write_allocation_tables()?;
self.disk.commit_storage()?;
println!("{:?}", self.filesystem.arena);
Ok(())
}

View File

@ -211,14 +211,14 @@ impl DirEntry {
sysfile: bool,
) -> Result<Self, std::io::Error> {
let attributes = match sysfile {
true => Attributes::new(true, false, false, false, false, false, false),
false => Attributes::new(true, true, true, true, false, false, false),
false => Attributes::new(true, false, false, false, false, false, false),
true => Attributes::new(true, true, true, true, false, false, false),
};
let entry_type = match sysfile {
true => DirEntryType::SysFile,
false => DirEntryType::File,
};
println!("So {} gets attributes {:?}", filename, attributes);
// Either use the provided TimeDate or get the current system TimeDate
let effective_timedate = create_timedate.unwrap_or_else(TimeDate::now);
@ -386,6 +386,10 @@ impl DirEntry {
/// assert_eq!(bytes, [0x32, 0x04]); // Assuming the start cluster number is 1234
/// ```
pub fn start_cluster_as_bytes(&self) -> [u8; 2] {
if self.allocated_clusters.len() == 0 {
// Our parent is the root directory
return [0,0];
}
let cluster: u16 = min(self.allocated_clusters[0], 65535) as u16;
cluster.to_le_bytes()
}
@ -441,7 +445,7 @@ impl DirEntry {
// Attempt to update the data field with the serialized bytes of all children
match self.children_bytes(arena) {
Ok(bytes) => {
self.data = bytes;
self.data = bytes.to_vec();
Ok(())
}
Err(e) => Err(e),
@ -462,6 +466,7 @@ impl DirEntry {
pub fn get_data(&self) -> &[u8] {
&self.data.as_slice()
}
pub fn is_directory(&self) -> bool {