Move the write_cluster method from filesystem to builder. Filesystem doesn't know about disks and partitions.

This commit is contained in:
Bas Wiel, van de 2024-05-03 09:12:06 +02:00
parent f0d98d0d0e
commit 3a6c63eac2
2 changed files with 55 additions and 54 deletions

View File

@ -75,6 +75,46 @@ impl DiskBuilder {
}
}
/// Writes the data of a cluster to the disk.
///
/// This method takes the data of a cluster, represented as a `Vec<u8>`, and writes it to the disk.
/// If the provided data is shorter than the size of a cluster, it is padded with zeroes.
/// Each cluster is divided into sectors, and the data is written sector by sector.
///
/// # Arguments
///
/// * `data`: The data of the cluster to be written to the disk.
/// * `cluster_address`: The address of the cluster on the disk where the data will be written.
/// * `partition`: A reference to the partition where the cluster resides.
/// * `disk`: A mutable reference to the disk where the data will be written.
///
/// # Errors
///
/// This method returns an `std::io::Error` if there is an I/O error during writing.
pub fn write_cluster(&mut self, cluster_address: u32, data: &[u8]) -> Result<(), std::io::Error> {
let bytes_per_cluster = self.filesystem.get_sectors_per_cluster() * 512;
let mut bytes = data.to_vec();
// If our data won't fill the cluster, pad it up to the right size with zero values.
if bytes.len() < bytes_per_cluster {
bytes.resize(bytes_per_cluster, 0);
}
// Calculate the base offset to figure out where the cluster should live on the disk
let mut sector_address = (cluster_address as usize
* self.filesystem.get_sectors_per_cluster() as usize
+ self.filesystem.get_first_data_sector() as usize)
- 2 * self.filesystem.get_sectors_per_cluster() as usize;
for chunk in bytes.chunks_exact(512) {
let mut chunk_array = [0u8; 512];
chunk_array.copy_from_slice(chunk);
self.partition.write_sector(&mut self.disk, sector_address as u32, chunk_array)?;
sector_address += 1;
}
Ok(())
}
/// The builder is the struct that does all manner of validation before trying to
/// create a Disk so that what we create will make sense.
pub fn build(&mut self) -> Result<(), std::io::Error> {

View File

@ -424,53 +424,6 @@ impl Fat {
Ok(())
}
/// Writes the data of a cluster to the disk.
///
/// This method takes the data of a cluster, represented as a `Vec<u8>`, and writes it to the disk.
/// If the provided data is shorter than the size of a cluster, it is padded with zeroes.
/// Each cluster is divided into sectors, and the data is written sector by sector.
///
/// # Arguments
///
/// * `data`: The data of the cluster to be written to the disk.
/// * `cluster_address`: The address of the cluster on the disk where the data will be written.
/// * `partition`: A reference to the partition where the cluster resides.
/// * `disk`: A mutable reference to the disk where the data will be written.
///
/// # Errors
///
/// This method returns an `std::io::Error` if there is an I/O error during writing.
pub fn write_cluster(
&self,
data: &mut Vec<u8>,
cluster_address: u16,
partition: &Partition,
disk: &mut Disk,
) -> Result<(), std::io::Error> {
// Ensure data has the correct size
let cluster_size = self.sectors_per_cluster as usize * 512;
if data.len() < cluster_size {
data.resize(cluster_size, 0);
}
// Iterate over data in chunks and write sectors
let rootdir_sector_count = ((self.root_dir_entries * 32) / 512) & !512;
let first_data_sector = self.reserved_sector_count
+ (self.fat_copies as u16 * self.sectors_per_fat)
+ rootdir_sector_count;
let mut sector_address = (cluster_address as usize * self.sectors_per_cluster as usize
+ first_data_sector as usize)
- 2 * self.sectors_per_cluster as usize;
for chunk in data.chunks_exact(512) {
let mut chunk_array = [0u8; 512];
chunk_array.copy_from_slice(chunk);
partition.write_sector(disk, sector_address as u32, chunk_array)?;
sector_address += 1;
}
Ok(())
}
/// Writes the allocation tables to the disk for the specified partition.
///
/// This method takes a mutable reference to self, representing the file system, and
@ -551,13 +504,6 @@ impl Fat {
}
}
}
self.write_cluster(
&mut bytes.to_vec(),
directory.get_start_cluster() as u16,
partition,
disk,
)?;
Ok(())
}
@ -779,6 +725,21 @@ impl Fat {
file_size
}
}
/// Get the sectors per cluster value
pub fn get_sectors_per_cluster(&self) -> usize {
self.sectors_per_cluster as usize
}
/// Return the sector address of the first data sector
pub fn get_first_data_sector(&self) -> u32 {
// Iterate over data in chunks and write sectors
let rootdir_sector_count = ((self.root_dir_entries * 32) / 512) & !512;
let first_data_sector = self.reserved_sector_count
+ (self.fat_copies as u16 * self.sectors_per_fat)
+ rootdir_sector_count;
first_data_sector as u32
}
}
/// Enum representing different types of FAT (File Allocation Table) file systems.