use crate::{simulator::{self, disk}, drivers::drv_disk::{DrvDisk, self}, utility::bitmap::BitMap}; use super::{filehdr::FileHdr, filesys::{Filesys, self}}; pub const MAX_FILE_NAME_SIZE : i32 = 500; pub struct OpenFile { pub name : String, // the file's pub hdr : FileHdr, // Header for this file pub seekPosition : i32, // Current position in the file (in byte) pub fSector : i32 // this file first sector on the disk (fichiers stockés de maniere contigue) } //division arrondie vers le bas pub fn div_round_down(a : i32, b : i32) -> i32{ a/b } //division arrondie vers le haut pub fn div_round_up(a : i32, b : i32) -> i32{ let mut result = a/b; if a%b > 0 { result + 1 } else { result } } impl OpenFile { /* Creer un "fichier ouvert", charge le file_hdr depuis disk */ pub fn open_file(sector : i32) -> OpenFile{ let file_hdr : FileHdr = FileHdr::init_file_hdr(); let name : String = String::from(""); //ici appel a fetchFrom(sector) sur file_hdr OpenFile { name: name, hdr: file_hdr, seekPosition: 0, fSector: sector } } pub fn seek(file : &mut OpenFile, position : i32){ file.seekPosition = position; } /* params : into : buffer de reception num_bytes : nombre d'octets à lire position : position du premier octet à lire dans le fichier (header compté??) */ pub fn read_at(driver_disk : &mut DrvDisk, file : &mut OpenFile, into : &mut Vec, num_bytes : i32, position : i32) -> i32 { let mut nbr_octet_lu = num_bytes; let file_length = file.hdr.file_length(); //on transforme position (position en octets) en un numéro de secteur let sector_position = position/disk::SECTOR_SIZE; if ( num_bytes <= 0)||( position < 0)||( position >= file_length) { return 0; } if (position + num_bytes > file_length) { nbr_octet_lu = file_length - position; } DrvDisk::read_multiple_sector(driver_disk, sector_position, &mut into[..]); nbr_octet_lu } /* params : from : données à écrire num_bytes : nombre d'octets à écrire depuis from position : position du premier octet à écrire dans le fichier(header compté??) */ pub fn write_at(driver_disk : &mut DrvDisk, file : &mut OpenFile, from : &Vec, num_bytes_to_write : i32, position : i32) -> i32 { let mut file_length = file.hdr.file_length(); let mut max_file_length = file.hdr.max_file_length(); //on transforme position (position en octets) en un numéro de secteur let sector_position = position/disk::SECTOR_SIZE; let mut num_bytes = num_bytes_to_write; //le nombre d'octets que l'on va réellement écrire, on ne pourra pas forcément ecrire la taille demandée en paramètre if (num_bytes <= 0)||(position < 0) ||(position > file_length){ return 0; } if num_bytes + file_length > max_file_length { //bit_map represente les secteur du disque, pour savoir ou trouver de la place let mut bit_map = BitMap::init_bitmap(disk::NUM_SECTORS as usize); bit_map.fetch_from(filesys::FREE_MAP_FILE_PATH); if !file.hdr.re_allocate(&mut bit_map, file_length, position + num_bytes){ //plus de place sur le disquen on se contente d'écrire ce que l'on peut num_bytes = file_length - position; } else { //write_back the header and freemap to disk file.hdr.write_back(file.fSector, driver_disk); bit_map.write_back(filesys::FREE_MAP_FILE_PATH); } } else if position + num_bytes > file_length{ file.hdr.change_file_length(position + num_bytes); } DrvDisk::write_multiple_sector(driver_disk, sector_position, &from[..]); num_bytes } pub fn read(driver_disk : &mut DrvDisk, file : &mut OpenFile, into : &mut Vec, num_bytes : i32) -> i32 { let result = OpenFile::read_at(driver_disk, file, into, num_bytes, file.seekPosition); file.seekPosition += result; result } pub fn write(driver_disk : &mut DrvDisk, file : &mut OpenFile, from : & Vec, num_bytes : i32) -> i32 { let result = OpenFile::write_at(driver_disk, file, from, num_bytes, file.seekPosition); file.seekPosition += result; result } pub fn get_name(&self) -> String { return self.name.clone(); } } #[cfg(test)] mod tests { use super::*; }