use std::io::{ErrorKind, Read, Seek, SeekFrom}; use std::fs::{File, OpenOptions}; pub struct FileDevice { pub name: Vec, pub rename: Vec, pub file: Option, pub operation_state: bool, pub pointer: u32, pub file_size: u32, } impl FileDevice { pub fn new() -> Self { Self { name: Vec::new(), rename: Vec::new(), file: None, operation_state: false, pointer: 0, file_size: 0, } } pub fn push_name_byte(&mut self, byte: u8) { if byte != 0 { self.name.push(byte); return } // If char was null, attempt to open the file and read file size. let path: std::ffi::OsString = std::os::unix::ffi::OsStringExt::from_vec( std::mem::take(&mut self.name)); let try_open = OpenOptions::new().read(true).write(true).open(path); if let Ok(file) = try_open { if let Ok(metadata) = file.metadata() { // Success. self.file = Some(file); match u32::try_from(metadata.len()) { Ok(len) => self.file_size = len, Err(_) => self.file_size = u32::MAX, } return; } } // Failure. self.close(); } pub fn set_file_size(&mut self) { if let Some(file) = &self.file { if let Ok(()) = file.set_len(self.file_size.into()) { return; }; } self.close(); } pub fn read(&mut self) -> u8 { if let Some(file) = &mut self.file { let mut buffer: [u8; 1] = [0; 1]; match file.read_exact(&mut buffer) { Ok(()) => return buffer[0], Err(err) => match err.kind() { ErrorKind::UnexpectedEof => return 0, _ => unimplemented!("File read error: ErrorKind::{:?}", err.kind()), } } } self.close(); return 0; } pub fn seek(&mut self) { if let Some(file) = &mut self.file { let point = SeekFrom::Start(self.pointer.into()); if let Ok(pointer) = file.seek(point) { if let Ok(pointer_u32) = pointer.try_into() { self.pointer = pointer_u32; return; } }; } self.close(); } pub fn close(&mut self) { self.file = None; self.pointer = 0; self.file_size = 0; } }