diff options
Diffstat (limited to 'src/devices/file.rs')
-rw-r--r-- | src/devices/file.rs | 90 |
1 files changed, 90 insertions, 0 deletions
diff --git a/src/devices/file.rs b/src/devices/file.rs new file mode 100644 index 0000000..f442dd8 --- /dev/null +++ b/src/devices/file.rs @@ -0,0 +1,90 @@ +use std::io::{ErrorKind, Read, Seek, SeekFrom}; +use std::fs::{File, OpenOptions}; + +pub struct FileDevice { + pub name: Vec<u8>, + pub rename: Vec<u8>, + + pub file: Option<File>, + 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; + } +} |