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; +    } +} | 
