diff options
Diffstat (limited to 'src/devices/file.rs')
-rw-r--r-- | src/devices/file.rs | 288 |
1 files changed, 0 insertions, 288 deletions
diff --git a/src/devices/file.rs b/src/devices/file.rs deleted file mode 100644 index 0bea2f4..0000000 --- a/src/devices/file.rs +++ /dev/null @@ -1,288 +0,0 @@ -mod bedrock_file_path; -mod buffered_file; -mod circular_path_buffer; -mod directory_listing; -mod entry; -mod operations; - -pub use bedrock_file_path::*; -pub use buffered_file::*; -pub use circular_path_buffer::*; -pub use directory_listing::*; -pub use entry::*; -use operations::*; - -use std::path::{Component, Path, PathBuf}; -use std::mem::take; - - -pub struct FileDevice { - pub base_path: PathBuf, - pub default_path: PathBuf, - - pub open_buffer: CircularPathBuffer, - pub move_buffer: CircularPathBuffer, - pub name_buffer: CircularPathBuffer, - - pub entry: Option<(Entry, BedrockFilePath)>, - pub cached_dir: Option<(Entry, BedrockFilePath)>, - - pub success: bool, - pub pointer: u32, - pub length: u32, - - pub enable_read: bool, - pub enable_write: bool, - pub enable_create: bool, - pub enable_move: bool, - pub enable_delete: bool, -} - -impl FileDevice { - pub fn new() -> Self { - #[cfg(target_family = "unix")] - let default_base: PathBuf = PathBuf::from("/"); - #[cfg(target_family = "windows")] - let default_base: PathBuf = PathBuf::from(""); - - Self { - base_path: default_base, - default_path: match std::env::current_dir() { - Ok(dir) => PathBuf::from(dir), - Err(_) => PathBuf::from(""), - }, - - open_buffer: CircularPathBuffer::new(), - move_buffer: CircularPathBuffer::new(), - name_buffer: CircularPathBuffer::new(), - - entry: None, - cached_dir: None, - - success: false, - pointer: 0, - length: 0, - - enable_read: true, - enable_write: true, - enable_create: true, - enable_move: true, - enable_delete: false, - } - } - - /// Commit any pending writes to the currently-open file. - pub fn flush_entry(&mut self) { - if let Some((Entry::File(buffered_file), _)) = &mut self.entry { - buffered_file.flush(); - } - } - - /// Safely close the currently-open entry, cleaning up entry variables. - pub fn close_entry(&mut self) { - self.open_buffer.clear(); - self.move_buffer.clear(); - self.name_buffer.clear(); - self.flush_entry(); - self.pointer = 0; - self.length = 0; - if let Some((Entry::Directory(dir), path)) = take(&mut self.entry) { - self.cached_dir = Some((Entry::Directory(dir), path)); - } - } - - /// Process a byte received from the OPEN port. - pub fn write_to_open_port(&mut self, byte: u8) { - if let Some(buffer) = self.open_buffer.push_byte(byte) { - self.close_entry(); - if let Some(path) = BedrockFilePath::from_buffer(buffer, &self.base_path) { - self.success = self.open_entry(path).is_ok(); - } - } - } - - /// Opens the entry at the given path. - pub fn open_entry(&mut self, path: BedrockFilePath) -> Result<(), ()> { - match path.entry_type() { - Some(EntryType::File) => { - let open_result = std::fs::OpenOptions::new() - .read(self.enable_read) - .write(self.enable_write) - .open(path.as_path()); - // Keep the current entry open if we can't open the new path. - if let Ok(file) = open_result { - self.close_entry(); - self.name_buffer.populate(path.as_buffer()); - self.entry = Some((Entry::File(BufferedFile::new(file)), path)); - return Ok(()); - }; - } - Some(EntryType::Directory) => { - // Attempt to use the cached directory. - if let Some((dir, cached_path)) = take(&mut self.cached_dir) { - if cached_path == path { - self.close_entry(); - self.name_buffer.populate(cached_path.as_buffer()); - self.entry = Some((dir, cached_path)); - return Ok(()); - } - } - // Keep the current entry open if we can't open the new path. - if let Some(listing) = DirectoryListing::from_path(&path) { - self.close_entry(); - self.name_buffer.populate(path.as_buffer()); - self.entry = Some((Entry::Directory(listing), path)); - return Ok(()); - }; - } - // The entry either doesn't exist or is not a file or directory. - None => (), - } - return Err(()); - } - - pub fn write_to_move_port(&mut self, byte: u8) { - if let Some(buffer) = self.move_buffer.push_byte(byte) { - let blank_destination = buffer[0] == 0x00; - let destination = BedrockFilePath::from_buffer(buffer, &self.base_path); - self.success = false; - - if let Some((_, source)) = &self.entry { - if blank_destination { - if self.enable_delete { - self.success = delete_entry(&source.as_path()); - } - } else if let Some(dest) = destination { - if self.enable_move { - self.success = move_entry(&source.as_path(), &dest.as_path()); - } - } - } else if let Some(dest) = destination { - if self.enable_create { - self.success = create_file(&dest.as_path()); - } - } - - self.close_entry(); - } - } - - /// Attempt to open the parent directory of the current entry. - pub fn ascend_to_parent(&mut self) { - self.success = false; - if let Some((_, path)) = &self.entry { - if let Some(parent_path) = path.parent() { - self.success = self.open_entry(parent_path).is_ok(); - } - } else { - if let Some(default) = BedrockFilePath::from_path(&self.default_path, &self.base_path) { - self.success = self.open_entry(default).is_ok(); - } - } - } - - /// Attempt to open the currently-selected child of the current directory. - pub fn descend_to_child(&mut self) { - self.success = false; - if let Some((Entry::Directory(listing), _)) = &self.entry { - if let Some(child_path) = listing.child_path() { - self.success = self.open_entry(child_path).is_ok(); - }; - } - } - - pub fn set_name_pointer(&mut self, value: u8) { - self.name_buffer.set_pointer(value); - } - - /// Returns true if the currently-open entry is a directory. - pub fn entry_type(&self) -> bool { - match self.entry { - Some((Entry::Directory(_), _)) => true, - _ => false, - } - } - - /// Reads a byte from the name buffer of the currently-selected child. - pub fn read_child_name(&mut self) -> u8 { - if let Some((Entry::Directory(listing), _)) = &mut self.entry { - listing.child_name().read_byte() - } else { - 0 - } - } - - pub fn set_child_name_pointer(&mut self, byte: u8) { - if let Some((Entry::Directory(listing), _)) = &mut self.entry { - listing.child_name().set_pointer(byte); - } - } - - /// Returns true if the currently-selected child is a directory. - pub fn child_type(&self) -> bool { - if let Some((Entry::Directory(listing), _)) = &self.entry { - match listing.child_type() { - Some(EntryType::Directory) => true, - Some(EntryType::File) => false, - None => false, - } - } else { - false - } - } - - /// Reads a byte from the currently-open file. - pub fn read_byte(&mut self) -> u8 { - match &mut self.entry { - Some((Entry::File(buffered_file), _)) => buffered_file.read_byte(), - _ => 0, - } - } - - /// Writes a byte to the currently-open file. - pub fn write_byte(&mut self, byte: u8) { - match &mut self.entry { - Some((Entry::File(buffered_file), _)) => buffered_file.write_byte(byte), - _ => (), - } - } - - pub fn pointer(&mut self) -> u32 { - match &mut self.entry { - Some((Entry::File(buffered_file), _)) => buffered_file.pointer(), - Some((Entry::Directory(listing), _)) => listing.selected(), - _ => 0, - } - } - - pub fn commit_pointer(&mut self) { - let pointer = take(&mut self.pointer); - match &mut self.entry { - Some((Entry::File(buffered_file), _)) => buffered_file.set_pointer(pointer), - Some((Entry::Directory(listing), _)) => listing.set_selected(pointer), - _ => (), - } - } - - pub fn length(&mut self) -> u32 { - match &mut self.entry { - Some((Entry::File(buffered_file), _)) => buffered_file.length(), - Some((Entry::Directory(listing), _)) => listing.length(), - _ => 0, - } - } - - pub fn commit_length(&mut self) { - let length = take(&mut self.length); - match &mut self.entry { - Some((Entry::File(buffered_file), _)) => buffered_file.set_length(length), - _ => (), - } - } -} - -impl Drop for FileDevice { - fn drop(&mut self) { - self.close_entry(); - } -} |