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,
|
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());
|
}
|
||||||
|
|
||||||
|
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();
|
std::str::from_utf8(short_name).ok()
|
||||||
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 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
|
||||||
)
|
)
|
||||||
})? {
|
})? {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue