This commit is contained in:
Baptiste 2023-03-29 13:26:09 +02:00
commit 6ac67efe2d
4 changed files with 263 additions and 2 deletions

View File

@ -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<i32>,
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() {
}
}

View File

@ -1,2 +1,6 @@
pub mod directory;
pub mod filehdr;
pub mod filesys;
pub mod fsmisc;
pub mod filesys;
pub mod oftable;
pub mod openfile;

102
src/utility/bitmap.rs Normal file
View File

@ -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<u32>,
}
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<u32>> {
// 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::<u32>()];
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::<u32>();
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::<u8>::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(())
}
}

View File

@ -1 +1,2 @@
pub mod list;
pub mod list;
pub mod bitmap;