diff options
| author | Fenrir <[email protected]> | 2016-09-27 23:46:48 -0700 |
|---|---|---|
| committer | Fenrir <[email protected]> | 2016-09-27 23:46:48 -0700 |
| commit | 6ab8bd0efd7b8adcf04d8d39e54e20f2cc8b9a4d (patch) | |
| tree | 65bce7dc76f6a1b580d44ac50370b7c351de32e5 /src | |
| parent | Add read_dir function (directory iteration!) (diff) | |
| download | ctru-rs-6ab8bd0efd7b8adcf04d8d39e54e20f2cc8b9a4d.tar.xz ctru-rs-6ab8bd0efd7b8adcf04d8d39e54e20f2cc8b9a4d.zip | |
Add metadata struct and functions
Diffstat (limited to 'src')
| -rw-r--r-- | src/services/fs.rs | 55 |
1 files changed, 46 insertions, 9 deletions
diff --git a/src/services/fs.rs b/src/services/fs.rs index fabacfa..a01ae73 100644 --- a/src/services/fs.rs +++ b/src/services/fs.rs @@ -60,6 +60,11 @@ pub struct File { offset: u64, } +pub struct Metadata { + attributes: u32, + size: u64, +} + #[derive(Clone)] pub struct OpenOptions { read: bool, @@ -74,8 +79,8 @@ pub struct ReadDir { } pub struct DirEntry { - root: Arc<PathBuf>, entry: FS_DirectoryEntry, + root: Arc<PathBuf>, } struct Dir(u32); @@ -128,25 +133,27 @@ impl File { OpenOptions::new().write(true).create(true).archive(arch).open(path.as_ref()) } - pub fn len(&self) -> Result<u64, i32> { + pub fn set_len(&mut self, len: u64) -> Result<(), i32> { unsafe { - let mut len = 0; - let r = FSFILE_GetSize(self.handle, &mut len); + let r = FSFILE_SetSize(self.handle, len); if r < 0 { Err(r) } else { - Ok(len) + Ok(()) } } } - pub fn set_len(&mut self, len: u64) -> Result<(), i32> { + // Right now the only file metadata we really have is file size + // This will probably expand later on + pub fn metadata(&self) -> Result<Metadata, i32> { unsafe { - let r = FSFILE_SetSize(self.handle, len); + let mut size = 0; + let r = FSFILE_GetSize(self.handle, &mut size); if r < 0 { Err(r) } else { - Ok(()) + Ok(Metadata { attributes: 0, size: size }) } } } @@ -197,6 +204,20 @@ impl File { } } +impl Metadata { + pub fn is_dir(&self) -> bool { + self.attributes == self.attributes | FS_ATTRIBUTE_DIRECTORY + } + + pub fn is_file(&self) -> bool { + !self.is_dir() + } + + pub fn len(&self) -> u64 { + self.size + } +} + impl OpenOptions { pub fn new() -> OpenOptions { OpenOptions { @@ -290,6 +311,12 @@ impl DirEntry { self.root.join(&self.file_name()) } + // Requiring the user to explicitly pass in the Archive here is pretty ugly, + // But I'm not sure of how else to do it right now. + pub fn metadata(&self, arch: &Archive) -> Result<Metadata, i32> { + metadata(&arch, self.path()) + } + pub fn file_name(&self) -> OsString { let filename = truncate_utf16_at_nul(&self.entry.name); OsString::from_wide(filename) @@ -309,6 +336,16 @@ pub fn create_dir<P: AsRef<Path>>(arch: &Archive, path: P) -> Result<(), i32> { } } +pub fn metadata<P: AsRef<Path>>(arch: &Archive, path: P) -> Result<Metadata, i32> { + let maybe_file = File::open(&arch, path.as_ref()); + let maybe_dir = read_dir(&arch, path.as_ref()); + match (maybe_file, maybe_dir) { + (Ok(file), _) => file.metadata(), + (_, Ok(_dir)) => Ok(Metadata { attributes: FS_ATTRIBUTE_DIRECTORY, size: 0 }), + (Err(r), _) => Err(r), + } +} + pub fn remove_dir<P: AsRef<Path>>(arch: &Archive, path: P) -> Result<(), i32> { unsafe { let path = to_utf16(path.as_ref()); @@ -390,7 +427,7 @@ fn readdir(arch: &Archive, p: &Path) -> Result<ReadDir, i32> { } } -// TODO: Determine if interior NULLs are premitted in 3DS file paths +// TODO: Determine if we should check UTF-16 paths for interior NULs fn to_utf16(path: &Path) -> Vec<u16> { path.as_os_str().encode_wide().collect::<Vec<_>>() } |