Browse Source

Add OpenOptions

pull/10/head
Fenrir 8 years ago
parent
commit
9c2c664b63
  1. 181
      src/services/fs.rs

181
src/services/fs.rs

@ -4,16 +4,68 @@ use collections::Vec;
use path::Path; use path::Path;
use libctru::services::fs; use libctru::services::fs::*;
#[derive(Copy, Clone, Debug)]
pub enum PathType {
Invalid,
Empty,
Binary,
ASCII,
UTF16,
}
#[derive(Copy, Clone, Debug)]
pub enum ArchiveID {
RomFS,
Savedata,
Extdata,
SharedExtdata,
SystemSavedata,
Sdmc,
SdmcWriteOnly,
BossExtdata,
CardSpiFS,
ExtDataAndBossExtdata,
SystemSaveData2,
NandRW,
NandRO,
NandROWriteAccess,
SaveDataAndContent,
SaveDataAndContent2,
NandCtrFS,
TwlPhoto,
NandTwlFS,
GameCardSavedata,
UserSavedata,
DemoSavedata,
}
pub struct Fs { pub struct Fs {
pd: PhantomData<i32>, pd: PhantomData<i32>,
} }
pub struct Archive {
id: ArchiveID,
handle: u64,
}
pub struct File {
handle: u32,
}
pub struct OpenOptions {
read: bool,
write: bool,
create: bool,
arch_handle: u64,
}
impl Fs { impl Fs {
pub fn init() -> Result<Fs, i32> { pub fn init() -> Result<Fs, i32> {
unsafe { unsafe {
let r = fs::fsInit(); let r = fsInit();
if r < 0 { if r < 0 {
Err(r) Err(r)
} else { } else {
@ -26,8 +78,8 @@ impl Fs {
let mut handle = 0u64; let mut handle = 0u64;
unsafe { unsafe {
let id = ArchiveID::Sdmc; let id = ArchiveID::Sdmc;
let path = fs::fsMakePath(PathType::Empty.into(), ptr::null() as *const _); let path = fsMakePath(PathType::Empty.into(), ptr::null() as *const _);
let ret = fs::FSUSER_OpenArchive(&mut handle, id.into(), path); let ret = FSUSER_OpenArchive(&mut handle, id.into(), path);
if ret < 0 { if ret < 0 {
Err(ret) Err(ret)
} else { } else {
@ -40,70 +92,97 @@ impl Fs {
} }
} }
impl Drop for Fs { impl Archive {
fn drop(&mut self) { pub fn file_open(&self, path: &Path) -> Result<File, i32> {
unsafe { self.file_open_options().read(true).create(true).open(path)
fs::fsExit();
} }
pub fn file_open_options(&self) -> OpenOptions {
OpenOptions {
read: false,
write: false,
create: false,
arch_handle: self.handle,
} }
} }
pub fn id(&self) -> ArchiveID {
self.id
}
}
pub struct Archive { impl OpenOptions {
id: ArchiveID, pub fn read(&mut self, read: bool) -> &mut OpenOptions {
handle: u64, self.read = read;
self
} }
impl Archive { pub fn write(&mut self, write: bool) -> &mut OpenOptions {
pub fn open_file(&self, p: &Path) -> Result<File, i32> { self.write = write;
self
}
pub fn create(&mut self, create: bool) -> &mut OpenOptions {
self.create = create;
self
}
pub fn open<P: AsRef<Path>>(&self, path: P) -> Result<File, i32> {
self._open(path.as_ref(), self.get_open_flags())
}
fn _open(&self, path: &Path, flags: u32) -> Result<File, i32> {
unsafe { unsafe {
let mut handle: u32 = 0; let mut file_handle: u32 = 0;
let wide = p.as_os_str().encode_wide().collect::<Vec<_>>(); let wide = path.as_os_str().encode_wide().collect::<Vec<_>>();
let path = fs::fsMakePath(PathType::UTF16.into(), wide.as_slice().as_ptr() as *mut _); let ctr_path = fsMakePath(PathType::UTF16.into(), wide.as_slice().as_ptr() as *mut _);
let ret = fs::FSUSER_OpenFile(&mut handle, self.handle, path, fs::FS_OPEN_READ, 0); let ret = FSUSER_OpenFile(&mut file_handle, self.arch_handle, ctr_path, flags, 0);
if ret < 0 { if ret < 0 {
Err(ret) Err(ret)
} else { } else {
Ok(File { handle: handle }) Ok(File { handle: file_handle })
} }
} }
} }
pub fn id(&self) -> ArchiveID { fn get_open_flags(&self) -> u32 {
self.id match (self.read, self.write, self.create) {
(true, false, false) => FS_OPEN_READ,
(false, true, false) => FS_OPEN_WRITE,
(true, false, true) => FS_OPEN_READ | FS_OPEN_CREATE,
(true, true, false) => FS_OPEN_READ | FS_OPEN_WRITE,
(true, true, true) => FS_OPEN_READ | FS_OPEN_WRITE | FS_OPEN_CREATE,
_ => 0, //failure case
}
} }
} }
impl Drop for Archive { impl Drop for Fs {
fn drop(&mut self) { fn drop(&mut self) {
unsafe { unsafe {
fs::FSUSER_CloseArchive(self.handle); fsExit();
} }
} }
} }
pub struct File {
handle: u32,
}
impl Drop for File { impl Drop for Archive {
fn drop(&mut self) { fn drop(&mut self) {
unsafe { unsafe {
fs::FSFILE_Close(self.handle); FSUSER_CloseArchive(self.handle);
} }
} }
} }
#[derive(Copy, Clone, Debug)] impl Drop for File {
pub enum PathType { fn drop(&mut self) {
Invalid, unsafe {
Empty, FSFILE_Close(self.handle);
Binary, }
ASCII, }
UTF16,
} }
impl From<PathType> for fs::FS_PathType { impl From<PathType> for FS_PathType {
fn from(p: PathType) -> Self { fn from(p: PathType) -> Self {
use self::PathType::*; use self::PathType::*;
use libctru::services::fs::FS_PathType::*; use libctru::services::fs::FS_PathType::*;
@ -117,8 +196,8 @@ impl From<PathType> for fs::FS_PathType {
} }
} }
impl From<fs::FS_PathType> for PathType { impl From<FS_PathType> for PathType {
fn from(f: fs::FS_PathType) -> Self { fn from(f: FS_PathType) -> Self {
use self::PathType::*; use self::PathType::*;
use libctru::services::fs::FS_PathType::*; use libctru::services::fs::FS_PathType::*;
match f { match f {
@ -131,33 +210,7 @@ impl From<fs::FS_PathType> for PathType {
} }
} }
#[derive(Copy, Clone, Debug)] impl From<ArchiveID> for FS_ArchiveID {
pub enum ArchiveID {
RomFS,
Savedata,
Extdata,
SharedExtdata,
SystemSavedata,
Sdmc,
SdmcWriteOnly,
BossExtdata,
CardSpiFS,
ExtDataAndBossExtdata,
SystemSaveData2,
NandRW,
NandRO,
NandROWriteAccess,
SaveDataAndContent,
SaveDataAndContent2,
NandCtrFS,
TwlPhoto,
NandTwlFS,
GameCardSavedata,
UserSavedata,
DemoSavedata,
}
impl From<ArchiveID> for fs::FS_ArchiveID {
fn from(a: ArchiveID) -> Self { fn from(a: ArchiveID) -> Self {
use self::ArchiveID::*; use self::ArchiveID::*;
use libctru::services::fs::FS_ArchiveID::*; use libctru::services::fs::FS_ArchiveID::*;

Loading…
Cancel
Save