forked from Rativel/BurritOS
156 lines
4.6 KiB
Rust
156 lines
4.6 KiB
Rust
|
|
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<u8>, 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<u8>, 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<u8>, 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<u8>, 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::*;
|
|
|
|
|
|
} |