summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Bridle <ben@derelict.engineering>2024-07-30 18:30:46 +1200
committerBen Bridle <ben@derelict.engineering>2024-07-30 18:30:46 +1200
commitebfb38ebb2dff3dcb353b9d8cd01d41d9abf486e (patch)
tree03494c577c1a9c755c64ef999c074bcc8ca4dcb5
parentc23f1eda935a514b886b79f85ce0dab3080c33ef (diff)
downloadbedrock-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.rs18
-rw-r--r--src/devices/file/circular_path_buffer.rs9
-rw-r--r--src/devices/file/directory_listing.rs12
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() {