Compare commits

...
Sign in to create a new pull request.

1 commit

Author SHA1 Message Date
7921064ae2 moved short name str into separate buffer 2025-07-29 20:34:35 +02:00

View file

@ -64,24 +64,30 @@ pub struct DirEntry {
file_size: u32, 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>, long_name: Option<String>,
} }
impl Display for DirEntry { impl Display for DirEntry {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 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) { // add slash to end of dir_names
name.push('/'); let dir_slash = if self.is_dir() { "/" } else { " " };
}
write!( write!(
f, f,
"{} {}", "{} {}{}",
self.attr, self.attr,
// self.create_time().format("%a %b %d %H:%M:%S%.3f %Y"), // self.create_time().format("%a %b %d %H:%M:%S%.3f %Y"),
// self.write_time().format("%a %b %d %H:%M:%S%.3f %Y"), // self.write_time().format("%a %b %d %H:%M:%S%.3f %Y"),
name, name,
dir_slash,
)?; )?;
Ok(()) Ok(())
@ -92,7 +98,7 @@ impl DirEntry {
pub fn load(bytes: &[u8]) -> anyhow::Result<DirEntry> { pub fn load(bytes: &[u8]) -> anyhow::Result<DirEntry> {
assert_eq!(bytes.len(), 32); 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 attr = Attr::from_bits_truncate(bytes[11]);
let create_time_tenths = bytes[13]; 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 { Ok(DirEntry {
name, name,
attr, attr,
@ -141,6 +173,7 @@ impl DirEntry {
write_time, write_time,
write_date, write_date,
file_size, file_size,
short_name,
long_name: None, long_name: None,
}) })
} }
@ -216,29 +249,19 @@ impl DirEntry {
std::str::from_utf8(self.extension()).ok() std::str::from_utf8(self.extension()).ok()
} }
pub fn name_string(&self) -> Option<String> { fn short_name(&self) -> &[u8] {
if let Some(long_filename) = self.long_name() { &self.short_name
return Some(long_filename.to_owned());
} }
let name = std::str::from_utf8(&self.name[..8]).ok()?.trim_ascii_end(); fn short_name_str(&self) -> Option<&str> {
let ext = std::str::from_utf8(&self.name[8..]).ok()?.trim_ascii_end(); let mut short_name = self.short_name();
let mut s = String::new(); // remove trailing zeros
while short_name.last() == Some(&0) {
if self.attr.contains(Attr::Hidden) { short_name = &short_name[..short_name.len() - 1];
s.push('.');
} }
s += name; std::str::from_utf8(short_name).ok()
if !ext.is_empty() {
s.push('.');
s += ext;
}
Some(s)
} }
pub fn long_name(&self) -> Option<&str> { pub fn long_name(&self) -> Option<&str> {
@ -249,6 +272,33 @@ impl DirEntry {
self.long_name = Some(long_name); 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 { pub fn attr(&self) -> Attr {
self.attr self.attr
} }
@ -540,7 +590,7 @@ impl<R: Read> DirIter<R> {
.map_err(|e| { .map_err(|e| {
anyhow::anyhow!( anyhow::anyhow!(
"failed to get long filename for {}: {}", "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 e
) )
})? { })? {