summaryrefslogtreecommitdiff
path: root/src/devices/file.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/file.rs')
-rw-r--r--src/devices/file.rs288
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();
- }
-}