diff options
author | Ben Bridle <ben@derelict.engineering> | 2024-07-30 18:30:46 +1200 |
---|---|---|
committer | Ben Bridle <ben@derelict.engineering> | 2024-07-30 18:30:46 +1200 |
commit | ebfb38ebb2dff3dcb353b9d8cd01d41d9abf486e (patch) | |
tree | 03494c577c1a9c755c64ef999c074bcc8ca4dcb5 | |
parent | c23f1eda935a514b886b79f85ce0dab3080c33ef (diff) | |
download | bedrock-pc-ebfb38ebb2dff3dcb353b9d8cd01d41d9abf486e.zip |
Update file device to compile on Windows
Construction of OsStrings is handled differently between Windows and
Unix, using platform-specific APIs.
The method OsStr::as_bytes was also changed to OsStr::as_encoded_bytes
at some point between Rust versions 1.69 and 1.80.
-rw-r--r-- | src/devices/file.rs | 18 | ||||
-rw-r--r-- | src/devices/file/circular_path_buffer.rs | 9 | ||||
-rw-r--r-- | src/devices/file/directory_listing.rs | 12 |
3 files changed, 21 insertions, 18 deletions
diff --git a/src/devices/file.rs b/src/devices/file.rs index e8db41a..fc1b56c 100644 --- a/src/devices/file.rs +++ b/src/devices/file.rs @@ -13,13 +13,25 @@ pub use entry::*; use operations::*; use std::fs::{OpenOptions, metadata}; -use std::os::unix::ffi::OsStrExt; use std::path::{Component, Path, PathBuf}; fn is_blank_path(path: &Path) -> bool { path == PathBuf::new() } +fn bytes_to_path(bytes: &[u8]) -> PathBuf { + #[cfg(target_family = "unix")] + let os_string: std::ffi::OsString = { + std::os::unix::ffi::OsStringExt::from_vec(Vec::from(bytes)) + }; + #[cfg(target_family = "windows")] + let os_string: std::ffi::OsString = { + let wide: Vec<u16> = bytes.iter().map(|b| *b as u16).collect(); + std::os::windows::ffi::OsStringExt::from_wide(&wide) + }; + os_string.into() +} + pub struct FileDevice { /// The path to which the file device is confined. Files and directories /// outside of this directory cannot be accessed. @@ -117,7 +129,7 @@ impl FileDevice { let file_entry = Entry::File(BufferedFile::new(file)); self.entry = Some((file_entry, path.to_owned())); let relative = remove_base(&path, &self.base_path).unwrap(); - self.name_buffer.populate(relative.as_os_str().as_bytes()); + self.name_buffer.populate(relative.as_os_str().as_encoded_bytes()); return Ok(()); }; } else if metadata.is_dir() { @@ -125,7 +137,7 @@ impl FileDevice { let dir_entry = Entry::Directory(listing); self.entry = Some((dir_entry, path.to_owned())); let relative = remove_base(&path, &self.base_path).unwrap(); - self.name_buffer.populate(relative.as_os_str().as_bytes()); + self.name_buffer.populate(relative.as_os_str().as_encoded_bytes()); return Ok(()); }; }; diff --git a/src/devices/file/circular_path_buffer.rs b/src/devices/file/circular_path_buffer.rs index f828f73..e5d903b 100644 --- a/src/devices/file/circular_path_buffer.rs +++ b/src/devices/file/circular_path_buffer.rs @@ -1,6 +1,4 @@ -use std::ffi::OsString; -use std::os::unix::ffi::OsStringExt; -use std::path::PathBuf; +use super::*; pub struct CircularPathBuffer { buffer: [u8; 256], @@ -52,10 +50,9 @@ impl CircularPathBuffer { pub fn push_byte(&mut self, value: u8) -> Option<PathBuf> { if value == 0x00 { let pointer = self.pointer as usize; - let vec = self.buffer[..pointer].to_vec(); + let path = bytes_to_path(&self.buffer[..pointer]); self.clear(); - let os_string: OsString = OsStringExt::from_vec(vec); - Some(os_string.into()) + Some(path) } else { let pointer = self.pointer as usize; self.pointer = self.pointer.wrapping_add(1); diff --git a/src/devices/file/directory_listing.rs b/src/devices/file/directory_listing.rs index 0709fc3..6d669e5 100644 --- a/src/devices/file/directory_listing.rs +++ b/src/devices/file/directory_listing.rs @@ -1,10 +1,5 @@ use super::*; -use std::ffi::OsString; -use std::os::unix::ffi::{OsStrExt, OsStringExt}; -use std::path::{Component, Path, PathBuf}; - - pub struct DirectoryListing { children: Vec<DirectoryChild>, length: u32, @@ -26,7 +21,7 @@ impl DirectoryListing { }; let entry = continue_on_err!(entry_result); let path = continue_on_err!(remove_base(&entry.path(), &base)); - let byte_path = path.as_os_str().as_bytes(); + let byte_path = path.as_os_str().as_encoded_bytes(); if byte_path.len() > 255 { continue; }; @@ -87,8 +82,7 @@ impl DirectoryListing { pub fn child_path(&self) -> Option<PathBuf> { self.selected.and_then(|s| self.get(s).and_then(|i| { - let os_string: OsString = OsStringExt::from_vec(i.byte_path.clone()); - Some(os_string.into()) + Some(bytes_to_path(&i.byte_path)) })) } } @@ -113,7 +107,7 @@ pub fn remove_base(absolute_path: &Path, base_path: &Path) -> Result<PathBuf, () // Returns true if a dot character directly follows the right-most // forward-slash character in the path. fn filename_dot_prefixed(path: &Path) -> bool { - let bytes = path.as_os_str().as_bytes(); + let bytes = path.as_os_str().as_encoded_bytes(); // Find position of final forward-slash byte. let mut final_slash = None; for (i, byte) in bytes.iter().enumerate() { |