From e39ddaefb20546a2c8f35fd6fcd47fcfd9d654d0 Mon Sep 17 00:00:00 2001 From: Nicolas Stalder Date: Wed, 29 Apr 2020 23:34:49 +0200 Subject: [PATCH] Reliability > efficiency --- src/fs.rs | 14 +++++++++++--- src/path.rs | 42 +++++++++++++++++++++++++++++++++++------- 2 files changed, 46 insertions(+), 10 deletions(-) diff --git a/src/fs.rs b/src/fs.rs index 75d36016..9d0f4583 100644 --- a/src/fs.rs +++ b/src/fs.rs @@ -154,7 +154,7 @@ pub struct Filesystem<'a, Storage: driver::Storage> { } /// Regular file vs directory -#[derive(Clone,Copy,Debug,Eq,Hash,PartialEq)] +#[derive(Clone,Copy,Debug,Eq,Hash,PartialEq,ufmt::derive::uDebug,serde::Serialize,serde::Deserialize)] pub enum FileType { File, Dir, @@ -173,7 +173,7 @@ impl FileType { } /// File type (regular vs directory) and size of a file. -#[derive(Clone,Debug,Eq,PartialEq)] +#[derive(Clone,Debug,Eq,PartialEq,ufmt::derive::uDebug,serde::Serialize,serde::Deserialize)] pub struct Metadata { file_type: FileType, size: usize, @@ -960,7 +960,7 @@ impl io::Write for File<'_, '_, S> fn flush(&self) -> Result<()> { Ok(()) } } -#[derive(Clone,Debug,PartialEq)] +#[derive(Clone,Debug,PartialEq,Eq, ufmt::derive::uDebug,serde::Serialize,serde::Deserialize)] pub struct DirEntry { file_name: PathBuf, metadata: Metadata, @@ -995,6 +995,14 @@ impl DirEntry { &self.path } + #[cfg(feature = "dir-entry-path")] + #[doc(hidden)] + // This is used in `crypto-service` to "namespace" paths + // by mutating a DirEntry in-place. + pub unsafe fn path_buf_mut(&mut self) -> &mut PathBuf { + &mut self.path + } + } pub struct ReadDirAllocation { diff --git a/src/path.rs b/src/path.rs index d298a7eb..711315dc 100644 --- a/src/path.rs +++ b/src/path.rs @@ -1,6 +1,6 @@ //! Paths -use core::{convert::TryFrom, fmt, marker::PhantomData, mem::MaybeUninit, ops, ptr, slice, str}; +use core::{convert::TryFrom, fmt, marker::PhantomData, ops, ptr, slice, str}; use cstr_core::CStr; use cty::{c_char, size_t}; @@ -76,6 +76,11 @@ impl Path { pub fn exists(&self, fs: &crate::fs::Filesystem) -> bool { fs.metadata(self).is_ok() } + + // helpful for debugging wither the trailing nul is indeed a trailing nul. + pub fn as_str_ref_with_trailing_nul(&self) -> &str { + unsafe { str::from_utf8_unchecked(self.inner.to_bytes_with_nul()) } + } } impl AsRef for Path { @@ -87,7 +92,8 @@ impl AsRef for Path { impl fmt::Debug for Path { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "{:?}", self.as_ref()) + // helpful for debugging wither the trailing nul is indeed a trailing nul. + write!(f, "p{:?}", self.as_str_ref_with_trailing_nul()) } } @@ -245,12 +251,14 @@ impl PathBuf { impl From<&Path> for PathBuf { fn from(path: &Path) -> Self { - let mut buf = MaybeUninit::<[c_char; consts::PATH_MAX_PLUS_ONE]>::uninit(); let bytes = path.as_ref().as_bytes(); + + let mut buf = [0; consts::PATH_MAX_PLUS_ONE]; let len = bytes.len(); - unsafe { ptr::copy_nonoverlapping(bytes.as_ptr(), buf.as_mut_ptr().cast(), len) } + assert!(len <= consts::PATH_MAX); + unsafe { ptr::copy_nonoverlapping(bytes.as_ptr(), buf.as_mut_ptr().cast(), len + 1) } Self { - buf: unsafe { buf.assume_init() }, + buf, len: len + 1, } } @@ -262,7 +270,7 @@ impl From<&[u8]> for PathBuf { let mut buf = [0; consts::PATH_MAX_PLUS_ONE]; let len = bytes.len(); assert!(len <= consts::PATH_MAX); - assert!(bytes.iter().position(|x| *x == 0).is_none()); + assert!(bytes.is_ascii()); unsafe { ptr::copy_nonoverlapping(bytes.as_ptr(), buf.as_mut_ptr().cast(), len) } Self { buf, @@ -349,12 +357,32 @@ impl fmt::Display for PathBuf { impl core::cmp::PartialEq for PathBuf { fn eq(&self, other: &Self) -> bool { // from cstr_core - self == other + self.as_ref() == other.as_ref() + + // // use cortex_m_semihosting::hprintln; + // // hprintln!("inside PathBuf PartialEq"); + // // hprintln!("self.len {}, other.len {}", self.len, other.len).ok(); + // // hprintln!("self..len {:?}, other..len {:?}", &self.buf[..self.len], &other.buf[..other.len]).ok(); + // self.len == other.len && self.buf[..self.len - 1] == other.buf[..other.len - 1] } } impl core::cmp::Eq for PathBuf {} +// use core::cmp::Ordering; + +// impl Ord for PathBuf { +// fn cmp(&self, other: &Self) -> Ordering { +// self.len.cmp(&other.len) +// } +// } + +// impl PartialOrd for PathBuf { +// fn partial_cmp(&self, other: &Self) -> Option { +// Some(self.cmp(other)) +// } +// } + /// Errors that arise from converting byte buffers into paths #[derive(Clone, Copy, Debug)] pub enum Error {