diff options
| author | Ben Bridle <ben@derelict.engineering> | 2025-03-25 12:46:49 +1300 | 
|---|---|---|
| committer | Ben Bridle <ben@derelict.engineering> | 2025-03-25 12:48:49 +1300 | 
| commit | ab84ad75629b0a4124221023ca91411d2cd62a32 (patch) | |
| tree | 0c333f06bec5270084aaec71cf173c798420207b /src/devices/file_device.rs | |
| parent | 07ae3438917fd854a46924a410f6890cd0651f1b (diff) | |
| download | bedrock-pc-ab84ad75629b0a4124221023ca91411d2cd62a32.zip | |
Restructure program
This commit also includes changes to devices according to the latest
devices specification, in particular the math and system devices.
Diffstat (limited to 'src/devices/file_device.rs')
| -rw-r--r-- | src/devices/file_device.rs | 155 | 
1 files changed, 95 insertions, 60 deletions
| diff --git a/src/devices/file_device.rs b/src/devices/file_device.rs index 61966b1..f8d8fa0 100644 --- a/src/devices/file_device.rs +++ b/src/devices/file_device.rs @@ -1,20 +1,4 @@ -mod bedrock_file_path; -mod bedrock_path_buffer; -mod buffered_file; -mod directory_listing; -mod entry; -mod operations; - -use buffered_file::BufferedFile; -use bedrock_file_path::BedrockFilePath; -use bedrock_path_buffer::BedrockPathBuffer; -use directory_listing::DirectoryListing; -use entry::{Entry, EntryType}; -use operations::{create_file, move_entry, delete_entry}; - -use bedrock_core::*; - -use std::path::{Component, Path, PathBuf}; +use crate::*;  pub struct FileDevice { @@ -39,6 +23,59 @@ pub struct FileDevice {      pub enable_delete: bool,  } + +impl Device for FileDevice { +    fn read(&mut self, port: u8) -> u8 { +        match port { +            0x0 => read_b!(self.entry.is_some()), +            0x1 => read_b!(self.success), +            0x2 => self.path_buffer.read(), +            0x3 => read_b!(self.entry_type()), +            0x4 => self.read_byte(), +            0x5 => self.read_byte(), +            0x6 => self.read_child_path(), +            0x7 => read_b!(self.child_type()), +            0x8 => read_hh!(self.pointer()), +            0x9 => read_hl!(self.pointer()), +            0xa => read_lh!(self.pointer()), +            0xb => read_ll!(self.pointer()), +            0xc => read_hh!(self.length()), +            0xd => read_hl!(self.length()), +            0xe => read_lh!(self.length()), +            0xf => read_ll!(self.length()), +            _ => unreachable!(), +        } +    } + +    fn write(&mut self, port: u8, value: u8) -> Option<Signal> { +        match port { +            0x0 => self.write_to_entry_port(value), +            0x1 => self.write_to_action_port(value), +            0x2 => self.path_buffer.set_pointer(value), +            0x3 => self.ascend_to_parent(), +            0x4 => self.write_byte(value), +            0x5 => self.write_byte(value), +            0x6 => self.set_child_path(value), +            0x7 => self.descend_to_child(), +            0x8 => write_hh!(self.pointer_write, value), +            0x9 => write_hl!(self.pointer_write, value), +            0xa => write_lh!(self.pointer_write, value), +            0xb => {write_ll!(self.pointer_write, value); self.commit_pointer()}, +            0xc => write_hh!(self.length_write, value), +            0xd => write_hl!(self.length_write, value), +            0xe => write_lh!(self.length_write, value), +            0xf => {write_ll!(self.length_write, value); self.commit_length()}, +            _ => unreachable!(), +        }; +        return None; +    } + +    fn wake(&mut self) -> bool { +        false +    } +} + +  impl FileDevice {      pub fn new() -> Self {          #[cfg(target_family = "unix")] @@ -279,59 +316,57 @@ impl FileDevice {      }  } +  impl Drop for FileDevice {      fn drop(&mut self) {          self.flush();      }  } -impl Device for FileDevice { -    fn read(&mut self, port: u8) -> u8 { -        match port { -            0x0 => read_b!(self.entry.is_some()), -            0x1 => read_b!(self.success), -            0x2 => self.path_buffer.read(), -            0x3 => read_b!(self.entry_type()), -            0x4 => self.read_byte(), -            0x5 => self.read_byte(), -            0x6 => self.read_child_path(), -            0x7 => read_b!(self.child_type()), -            0x8 => read_hh!(self.pointer()), -            0x9 => read_hl!(self.pointer()), -            0xa => read_lh!(self.pointer()), -            0xb => read_ll!(self.pointer()), -            0xc => read_hh!(self.length()), -            0xd => read_hl!(self.length()), -            0xe => read_lh!(self.length()), -            0xf => read_ll!(self.length()), -            _ => unreachable!(), + +/// Create a new file if it doesn't already exist, returning true if successful. +pub fn create_file(destination: &Path) -> bool { +    if entry_exists(destination) { +        false +    } else { +        if let Some(parent_path) = destination.parent() { +            let _ = std::fs::create_dir_all(parent_path);          } +        std::fs::OpenOptions::new().write(true).create_new(true) +            .open(destination).is_ok()      } +} -    fn write(&mut self, port: u8, value: u8) -> Option<Signal> { -        match port { -            0x0 => self.write_to_entry_port(value), -            0x1 => self.write_to_action_port(value), -            0x2 => self.path_buffer.set_pointer(value), -            0x3 => self.ascend_to_parent(), -            0x4 => self.write_byte(value), -            0x5 => self.write_byte(value), -            0x6 => self.set_child_path(value), -            0x7 => self.descend_to_child(), -            0x8 => write_hh!(self.pointer_write, value), -            0x9 => write_hl!(self.pointer_write, value), -            0xa => write_lh!(self.pointer_write, value), -            0xb => {write_ll!(self.pointer_write, value); self.commit_pointer()}, -            0xc => write_hh!(self.length_write, value), -            0xd => write_hl!(self.length_write, value), -            0xe => write_lh!(self.length_write, value), -            0xf => {write_ll!(self.length_write, value); self.commit_length()}, -            _ => unreachable!(), -        }; -        return None; +/// Move an entry from one location to another, returning true if successful. +pub fn move_entry(source: &Path, destination: &Path) -> bool { +    if !entry_exists(source) || entry_exists(destination) { +        return false;      } +    std::fs::rename(source, destination).is_ok() +} -    fn wake(&mut self) -> bool { -        false +/// Delete an entry, returning true if successful. +pub fn delete_entry(source: &Path) -> bool { +    use std::fs::{remove_file, remove_dir_all}; +    use std::io::ErrorKind; + +    match remove_file(source) { +        Ok(_) => true, +        Err(error) => match error.kind() { +            ErrorKind::NotFound => true, +            ErrorKind::IsADirectory => match remove_dir_all(source) { +                Ok(_) => true, +                Err(error) => match error.kind() { +                    ErrorKind::NotFound => true, +                    _ => false, +                } +            } +            _ => false, +        }      }  } + +/// Returns true if an entry already exists at the given path. +fn entry_exists(source: &Path) -> bool { +    std::fs::metadata(source).is_ok() +} | 
