moved short name str into separate buffer
This commit is contained in:
parent
372aa34022
commit
7921064ae2
1 changed files with 78 additions and 28 deletions
|
|
@ -64,24 +64,30 @@ pub struct DirEntry {
|
|||
|
||||
file_size: u32,
|
||||
|
||||
// buffer for holding short name str representation
|
||||
// initial dot if hidden (1)
|
||||
// stem (8)
|
||||
// dot (1)
|
||||
// extension (3)
|
||||
short_name: [u8; 13],
|
||||
long_name: Option<String>,
|
||||
}
|
||||
|
||||
impl Display for DirEntry {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
let mut name = self.name_string().unwrap_or_else(|| "<unknown>".to_owned());
|
||||
let name = self.name_str().unwrap_or("<unknown>");
|
||||
|
||||
if self.attr.contains(Attr::Directory) {
|
||||
name.push('/');
|
||||
}
|
||||
// add slash to end of dir_names
|
||||
let dir_slash = if self.is_dir() { "/" } else { " " };
|
||||
|
||||
write!(
|
||||
f,
|
||||
"{} {}",
|
||||
"{} {}{}",
|
||||
self.attr,
|
||||
// self.create_time().format("%a %b %d %H:%M:%S%.3f %Y"),
|
||||
// self.write_time().format("%a %b %d %H:%M:%S%.3f %Y"),
|
||||
name,
|
||||
dir_slash,
|
||||
)?;
|
||||
|
||||
Ok(())
|
||||
|
|
@ -92,7 +98,7 @@ impl DirEntry {
|
|||
pub fn load(bytes: &[u8]) -> anyhow::Result<DirEntry> {
|
||||
assert_eq!(bytes.len(), 32);
|
||||
|
||||
let name = bytes[..11].try_into().unwrap();
|
||||
let name: [u8; 11] = bytes[..11].try_into().unwrap();
|
||||
let attr = Attr::from_bits_truncate(bytes[11]);
|
||||
|
||||
let create_time_tenths = bytes[13];
|
||||
|
|
@ -130,6 +136,32 @@ impl DirEntry {
|
|||
)
|
||||
}
|
||||
|
||||
let mut short_name = [0; 13];
|
||||
|
||||
let mut short_name_iter = short_name.iter_mut();
|
||||
|
||||
if attr.contains(Attr::Hidden) {
|
||||
// if hidden: lead with '.'
|
||||
*short_name_iter.next().unwrap() = b'.';
|
||||
}
|
||||
|
||||
if name[0] != 0 && name[0] != 0xe5 {
|
||||
// dir_entry is not free
|
||||
|
||||
for c in name[..8].iter().filter(|&x| x != &0x20) {
|
||||
*short_name_iter.next().unwrap() = *c;
|
||||
}
|
||||
|
||||
if &name[8..] != &[0x20, 0x20, 0x20] {
|
||||
// if extension is not empty: add dot and extension
|
||||
*short_name_iter.next().unwrap() = b'.';
|
||||
|
||||
for c in name[8..].iter().filter(|&x| x != &0x20) {
|
||||
*short_name_iter.next().unwrap() = *c;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(DirEntry {
|
||||
name,
|
||||
attr,
|
||||
|
|
@ -141,6 +173,7 @@ impl DirEntry {
|
|||
write_time,
|
||||
write_date,
|
||||
file_size,
|
||||
short_name,
|
||||
long_name: None,
|
||||
})
|
||||
}
|
||||
|
|
@ -216,29 +249,19 @@ impl DirEntry {
|
|||
std::str::from_utf8(self.extension()).ok()
|
||||
}
|
||||
|
||||
pub fn name_string(&self) -> Option<String> {
|
||||
if let Some(long_filename) = self.long_name() {
|
||||
return Some(long_filename.to_owned());
|
||||
fn short_name(&self) -> &[u8] {
|
||||
&self.short_name
|
||||
}
|
||||
|
||||
fn short_name_str(&self) -> Option<&str> {
|
||||
let mut short_name = self.short_name();
|
||||
|
||||
// remove trailing zeros
|
||||
while short_name.last() == Some(&0) {
|
||||
short_name = &short_name[..short_name.len() - 1];
|
||||
}
|
||||
|
||||
let name = std::str::from_utf8(&self.name[..8]).ok()?.trim_ascii_end();
|
||||
let ext = std::str::from_utf8(&self.name[8..]).ok()?.trim_ascii_end();
|
||||
|
||||
let mut s = String::new();
|
||||
|
||||
if self.attr.contains(Attr::Hidden) {
|
||||
s.push('.');
|
||||
}
|
||||
|
||||
s += name;
|
||||
|
||||
if !ext.is_empty() {
|
||||
s.push('.');
|
||||
|
||||
s += ext;
|
||||
}
|
||||
|
||||
Some(s)
|
||||
std::str::from_utf8(short_name).ok()
|
||||
}
|
||||
|
||||
pub fn long_name(&self) -> Option<&str> {
|
||||
|
|
@ -249,6 +272,33 @@ impl DirEntry {
|
|||
self.long_name = Some(long_name);
|
||||
}
|
||||
|
||||
pub fn name_str(&self) -> Option<&str> {
|
||||
if let Some(long_filename) = self.long_name() {
|
||||
return Some(long_filename);
|
||||
}
|
||||
|
||||
self.short_name_str()
|
||||
|
||||
// let name = std::str::from_utf8(&self.name[..8]).ok()?.trim_ascii_end();
|
||||
// let ext = std::str::from_utf8(&self.name[8..]).ok()?.trim_ascii_end();
|
||||
|
||||
// let mut s = String::new();
|
||||
|
||||
// if self.attr.contains(Attr::Hidden) {
|
||||
// s.push('.');
|
||||
// }
|
||||
|
||||
// s += name;
|
||||
|
||||
// if !ext.is_empty() {
|
||||
// s.push('.');
|
||||
|
||||
// s += ext;
|
||||
// }
|
||||
|
||||
// Some(s)
|
||||
}
|
||||
|
||||
pub fn attr(&self) -> Attr {
|
||||
self.attr
|
||||
}
|
||||
|
|
@ -540,7 +590,7 @@ impl<R: Read> DirIter<R> {
|
|||
.map_err(|e| {
|
||||
anyhow::anyhow!(
|
||||
"failed to get long filename for {}: {}",
|
||||
dir_entry.name_string().as_deref().unwrap_or("<invalid>"),
|
||||
dir_entry.name_str().as_deref().unwrap_or("<invalid>"),
|
||||
e
|
||||
)
|
||||
})? {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue