From 52929cef24703ace37859c24477140c880958b59 Mon Sep 17 00:00:00 2001 From: AmauryBrodu <60550980+AmauryBrodu@users.noreply.github.com> Date: Wed, 29 Mar 2023 13:17:21 +0200 Subject: [PATCH 1/2] added the bitmap, tests still need to be done --- src/utility/bitmap.rs | 102 ++++++++++++++++++++++++++++++++++++++++++ src/utility/mod.rs | 3 +- 2 files changed, 104 insertions(+), 1 deletion(-) create mode 100644 src/utility/bitmap.rs diff --git a/src/utility/bitmap.rs b/src/utility/bitmap.rs new file mode 100644 index 0000000..a34e5b4 --- /dev/null +++ b/src/utility/bitmap.rs @@ -0,0 +1,102 @@ +pub const BITS_IN_BYTE: usize = 8; +pub const BITS_IN_WORD: usize = 32; + +use std::fs::File; +use std::io::{Cursor, Write, Read}; + +pub struct BitMap { + num_bits: usize, + num_words: usize, + map: Vec, +} + +impl BitMap { + + pub fn mark(&mut self, which: usize) { + assert!(which >= 0 && which < self.num_bits); + self.map[which / BITS_IN_WORD] |= 1 << (which % BITS_IN_WORD); + } + + pub fn test(&self, which: usize) -> bool { + assert!(which < self.num_bits); + (self.map[which / BITS_IN_WORD] & (1 << (which % BITS_IN_WORD))) != 0 + } + + pub fn find(&mut self) -> i32 { + for i in 0..self.num_bits { + if !self.test(i) { + self.mark(i); + return i as i32; + } + } + -1 + } + + pub fn clear(&mut self, which: usize) { + assert!(which < self.num_bits, "index out of range"); + + let word_idx = which / BITS_IN_WORD; + let bit_idx = which % BITS_IN_WORD; + self.map[word_idx] &= !(1 << bit_idx); + } + + pub fn num_clear(&self) -> i32 { + let mut count = 0; + for i in 0..self.num_bits { + if !self.test(i) { + count += 1; + } + } + count + } + + pub fn print(&self) { + println!("Bitmap set:"); + for i in 0..self.num_bits { + if self.test(i) { + print!("{}, ", i); + } + } + println!(); + } + + + + pub fn fetch_from(&mut self, file_path: &str) -> std::io::Result<&Vec> { + // Ouvre le fichier en mode lecture seule + let mut file = File::open(file_path)?; + + // Lit les octets du fichier dans un buffer + let mut buffer = vec![0; self.num_words * std::mem::size_of::()]; + file.read_exact(&mut buffer)?; + + // Convertit les octets en vecteur de u32 + self.map = vec![0; self.num_words]; + for i in 0..self.num_words { + let j = i * std::mem::size_of::(); + let bytes = [ + buffer[j], buffer[j+1], buffer[j+2], buffer[j+3] + ]; + self.map[i] = u32::from_le_bytes(bytes); + } + + Ok(&self.map) + } + + pub fn write_back(&mut self, file_path: &str) -> std::io::Result<()> { + // Encapsule le vecteur dans un std::io::Cursor pour l'utiliser comme un std::io::Write + let mut cursor = Cursor::new(Vec::::new()); + for u32_val in self.map.as_mut_slice() { + cursor.write_all(&u32_val.to_le_bytes())?; + } + + // Ouvre le fichier en mode écriture + let mut file = File::create(file_path)?; + + // Écrit les données dans le fichier + file.write_all(&cursor.into_inner())?; + + Ok(()) + } + +} \ No newline at end of file diff --git a/src/utility/mod.rs b/src/utility/mod.rs index 651aed7..6db23f2 100644 --- a/src/utility/mod.rs +++ b/src/utility/mod.rs @@ -1 +1,2 @@ -pub mod list; \ No newline at end of file +pub mod list; +pub mod bitmap; \ No newline at end of file From 99a69c7998ef8b4c8e54fcc63dcf792c2a14eda4 Mon Sep 17 00:00:00 2001 From: AmauryBrodu <60550980+AmauryBrodu@users.noreply.github.com> Date: Wed, 29 Mar 2023 13:20:44 +0200 Subject: [PATCH 2/2] filehdr nearly done --- src/filesys/filehdr.rs | 154 +++++++++++++++++++++++++++++++++++++++++ src/filesys/mod.rs | 6 ++ 2 files changed, 160 insertions(+) create mode 100644 src/filesys/mod.rs diff --git a/src/filesys/filehdr.rs b/src/filesys/filehdr.rs index e69de29..e6dcad9 100644 --- a/src/filesys/filehdr.rs +++ b/src/filesys/filehdr.rs @@ -0,0 +1,154 @@ +use crate::simulator::disk; +use crate::{simulator::disk::SECTOR_SIZE, utility::bitmap::BitMap}; +pub const MAX_HEADER_SECTORS: i32 = 32; +pub const DATAS_IN_FIRST_SECTOR: i32 = (SECTOR_SIZE - 5 * 8) /8; +pub const DATAS_IN_SECTOR: i32 = (SECTOR_SIZE - 1 * 8) /8; +pub const MAX_DATA_SECTORS: i32 = ((MAX_HEADER_SECTORS-1) * DATAS_IN_SECTOR + DATAS_IN_FIRST_SECTOR); +pub const MAX_FILE_LENGTH: i32 = ((MAX_DATA_SECTORS) * SECTOR_SIZE); + +use crate::DrvDisk; +use crate::Disk; + +pub struct FileHdr { + is_dir: i32, + num_bytes: i32, + num_sectors: i32, + data_sectors: Vec, + num_header_sectors: i32, + header_sectors: [i32; MAX_HEADER_SECTORS as usize], +} + +impl FileHdr { + + pub fn allocate(&mut self, mut free_map: BitMap, file_size: i32) -> bool { + self.num_bytes = file_size; + if file_size > MAX_FILE_LENGTH { + panic!("file size is too long"); + } + + self.num_sectors = (file_size + SECTOR_SIZE -1) / SECTOR_SIZE; + self.num_header_sectors = ((self.num_sectors - DATAS_IN_FIRST_SECTOR)+DATAS_IN_SECTOR-1) / DATAS_IN_SECTOR; + + // Check if there is enough free sectors for both of them + if free_map.num_clear() < self.num_sectors + self.num_header_sectors { + return false; + } + + for i in 0..self.num_header_sectors { + self.header_sectors[i as usize] = free_map.find(); + } + + self.data_sectors = vec![0; MAX_DATA_SECTORS as usize]; + for i in 0..self.num_sectors { + self.data_sectors[i as usize] = free_map.find(); + } + + return true; + } + + pub fn re_allocate(&mut self, mut free_map: BitMap, old_file_size: i32, new_file_size: i32) -> bool { + let mut new_num_sectors = ((new_file_size + SECTOR_SIZE -1) / SECTOR_SIZE) - self.num_sectors; + self.num_bytes = new_file_size; + + let mut new_num_header_sectors = (((self.num_sectors - DATAS_IN_FIRST_SECTOR)+DATAS_IN_SECTOR-1) / DATAS_IN_SECTOR) - self.num_header_sectors; + + assert!(new_file_size <= MAX_FILE_LENGTH); + + if free_map.num_clear() < new_num_sectors + new_num_header_sectors { + return false; + } + + for i in 0..new_num_header_sectors { + self.header_sectors[(i + self.num_header_sectors)as usize] = free_map.find(); + } + + for i in 0..new_num_sectors { + self.data_sectors[(i + self.num_sectors) as usize] = free_map.find(); + } + + return true; + + + + } + + pub fn deallocate(&mut self, mut free_map: BitMap) { + for i in 0..self.num_sectors { + assert!(free_map.test(self.data_sectors[i as usize] as usize)); + free_map.clear(self.data_sectors[i as usize]as usize); + } + + for i in 0..self.num_header_sectors { + assert!(free_map.test(self.header_sectors[i as usize] as usize)); + free_map.clear(self.header_sectors[i as usize]as usize); + } + } + + //TODO: fetchFrom WriteBack + + + pub fn byte_to_sector(&self,offset: i32) -> i32 { + return self.data_sectors[ (offset / SECTOR_SIZE) as usize]; + } + + pub fn file_length(&self) -> i32 { + return self.num_bytes; + } + + pub fn change_file_length(&mut self, new_size: i32) { + self.num_bytes = new_size; + assert!(new_size <= MAX_FILE_LENGTH); + + } + + pub fn max_file_length(&self) -> i32 { + return self.num_sectors * SECTOR_SIZE; + } + + pub fn print(&self) { + let mut data = Vec::new(); + println!("FileHeader contents. File size: {}. File blocks:", self.num_bytes); + for i in 0..self.num_sectors { + print!("{} ", self.data_sectors[i as usize]); + } + println!("\nFile contents:"); + let mut k = 0; + for i in 0..self.num_sectors { + let disk = Disk::init_disk(); + let mut drv_disk = DrvDisk::init_drv_disk(disk); + drv_disk.read_sector(self.data_sectors[i as usize], &mut data); + for j in 0..SECTOR_SIZE.min(self.num_bytes - k) { + let c = data[j as usize]; + if c >= 0x20 && c <= 0x7E { + print!("{}", c as char); + } else { + print!("\\{:x}", c); + } + k += 1; + } + println!(""); + } + } + + pub fn is_dir(&self) -> bool{ + return self.is_dir == 1; + } + + pub fn set_file(&mut self) { + self.is_dir = 0; + } + + pub fn set_dir(&mut self) { + self.is_dir = 1; + } + +} + +#[cfg(test)] +mod test { + + #[test] + fn test_allocate() { + + } +} \ No newline at end of file diff --git a/src/filesys/mod.rs b/src/filesys/mod.rs new file mode 100644 index 0000000..14f5368 --- /dev/null +++ b/src/filesys/mod.rs @@ -0,0 +1,6 @@ +pub mod directory; +pub mod filehdr; +pub mod filesys; +pub mod fsmisc; +pub mod oftable; +pub mod openfile; \ No newline at end of file