Skip to content

Commit 91aa36c

Browse files
committed
Clean up VFS error handling
1 parent 9fc56d8 commit 91aa36c

File tree

3 files changed

+49
-38
lines changed

3 files changed

+49
-38
lines changed

src/vfs/disc.rs

+10-8
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use nodtool::{
1010
nod::{Disc, DiscStream, Fst, NodeKind, OwnedFileStream, PartitionBase, PartitionMeta},
1111
};
1212
use typed_path::Utf8UnixPath;
13-
use zerocopy::IntoBytes;
13+
use zerocopy::{FromZeros, IntoBytes};
1414

1515
use super::{
1616
next_non_empty, StaticFile, Vfs, VfsError, VfsFile, VfsFileType, VfsMetadata, VfsResult,
@@ -252,19 +252,21 @@ impl DiscFile {
252252
Self { inner: DiscFileInner::Stream(file), mtime }
253253
}
254254

255-
fn convert_to_mapped(&mut self) {
255+
fn convert_to_mapped(&mut self) -> io::Result<()> {
256256
match &mut self.inner {
257257
DiscFileInner::Stream(stream) => {
258-
let pos = stream.stream_position().unwrap();
259-
stream.seek(SeekFrom::Start(0)).unwrap();
260-
let mut data = vec![0u8; stream.len() as usize];
261-
stream.read_exact(&mut data).unwrap();
262-
let mut cursor = Cursor::new(Arc::from(data.as_slice()));
258+
let pos = stream.stream_position()?;
259+
stream.seek(SeekFrom::Start(0))?;
260+
let mut data = <[u8]>::new_box_zeroed_with_elems(stream.len() as usize)
261+
.map_err(|_| io::Error::from(io::ErrorKind::OutOfMemory))?;
262+
stream.read_exact(&mut data)?;
263+
let mut cursor = Cursor::new(Arc::from(data));
263264
cursor.set_position(pos);
264265
self.inner = DiscFileInner::Mapped(cursor);
265266
}
266267
DiscFileInner::Mapped(_) => {}
267268
};
269+
Ok(())
268270
}
269271
}
270272

@@ -304,7 +306,7 @@ impl Seek for DiscFile {
304306

305307
impl VfsFile for DiscFile {
306308
fn map(&mut self) -> io::Result<&[u8]> {
307-
self.convert_to_mapped();
309+
self.convert_to_mapped()?;
308310
match &mut self.inner {
309311
DiscFileInner::Stream(_) => unreachable!(),
310312
DiscFileInner::Mapped(data) => Ok(data.get_ref()),

src/vfs/std_fs.rs

+13-11
Original file line numberDiff line numberDiff line change
@@ -55,10 +55,10 @@ impl StdFile {
5555
pub fn new(path: Utf8NativePathBuf) -> Self { StdFile { path, file: None, mmap: None } }
5656

5757
pub fn file(&mut self) -> io::Result<&mut BufReader<fs::File>> {
58-
if self.file.is_none() {
59-
self.file = Some(BufReader::new(fs::File::open(&self.path)?));
60-
}
61-
Ok(self.file.as_mut().unwrap())
58+
Ok(match self.file {
59+
Some(ref mut file) => file,
60+
None => self.file.insert(BufReader::new(fs::File::open(&self.path)?)),
61+
})
6262
}
6363
}
6464

@@ -86,13 +86,15 @@ impl Seek for StdFile {
8686

8787
impl VfsFile for StdFile {
8888
fn map(&mut self) -> io::Result<&[u8]> {
89-
if self.file.is_none() {
90-
self.file = Some(BufReader::new(fs::File::open(&self.path)?));
91-
}
92-
if self.mmap.is_none() {
93-
self.mmap = Some(unsafe { memmap2::Mmap::map(self.file.as_ref().unwrap().get_ref())? });
94-
}
95-
Ok(self.mmap.as_ref().unwrap())
89+
let file = match self.file {
90+
Some(ref mut file) => file,
91+
None => self.file.insert(BufReader::new(fs::File::open(&self.path)?)),
92+
};
93+
let mmap = match self.mmap {
94+
Some(ref mmap) => mmap,
95+
None => self.mmap.insert(unsafe { memmap2::Mmap::map(file.get_ref())? }),
96+
};
97+
Ok(mmap)
9698
}
9799

98100
fn metadata(&mut self) -> io::Result<VfsMetadata> {

src/vfs/wad.rs

+26-19
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ use crate::{
2323
pub struct WadFs {
2424
file: Box<dyn VfsFile>,
2525
wad: WadFile,
26+
mtime: Option<FileTime>,
2627
}
2728

2829
enum WadFindResult<'a> {
@@ -34,9 +35,10 @@ enum WadFindResult<'a> {
3435

3536
impl WadFs {
3637
pub fn new(mut file: Box<dyn VfsFile>) -> io::Result<Self> {
38+
let mtime = file.metadata()?.mtime;
3739
let wad = process_wad(file.as_mut())
3840
.map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))?;
39-
Ok(Self { file, wad })
41+
Ok(Self { file, wad, mtime })
4042
}
4143

4244
fn find(&self, path: &str) -> Option<WadFindResult> {
@@ -81,7 +83,7 @@ impl Vfs for WadFs {
8183
match result {
8284
WadFindResult::Root => Err(VfsError::IsADirectory),
8385
WadFindResult::Static(data) => {
84-
Ok(Box::new(StaticFile::new(Arc::from(data), self.file.metadata()?.mtime)))
86+
Ok(Box::new(StaticFile::new(Arc::from(data), self.mtime)))
8587
}
8688
WadFindResult::Content(content_index, content) => {
8789
let offset = self.wad.content_offset(content_index);
@@ -93,7 +95,7 @@ impl Vfs for WadFs {
9395
&self.wad.title_key,
9496
&content.iv(),
9597
),
96-
self.file.metadata()?.mtime,
98+
self.mtime,
9799
)))
98100
}
99101
WadFindResult::Window(offset, len) => {
@@ -129,20 +131,23 @@ impl Vfs for WadFs {
129131
}
130132

131133
fn metadata(&mut self, path: &Utf8UnixPath) -> VfsResult<VfsMetadata> {
132-
let mtime = self.file.metadata()?.mtime;
133134
if let Some(result) = self.find(path.as_str()) {
134135
match result {
135136
WadFindResult::Root => {
136-
Ok(VfsMetadata { file_type: VfsFileType::Directory, len: 0, mtime })
137-
}
138-
WadFindResult::Static(data) => {
139-
Ok(VfsMetadata { file_type: VfsFileType::File, len: data.len() as u64, mtime })
140-
}
141-
WadFindResult::Content(_, content) => {
142-
Ok(VfsMetadata { file_type: VfsFileType::File, len: content.size.get(), mtime })
137+
Ok(VfsMetadata { file_type: VfsFileType::Directory, len: 0, mtime: self.mtime })
143138
}
139+
WadFindResult::Static(data) => Ok(VfsMetadata {
140+
file_type: VfsFileType::File,
141+
len: data.len() as u64,
142+
mtime: self.mtime,
143+
}),
144+
WadFindResult::Content(_, content) => Ok(VfsMetadata {
145+
file_type: VfsFileType::File,
146+
len: content.size.get(),
147+
mtime: self.mtime,
148+
}),
144149
WadFindResult::Window(_, len) => {
145-
Ok(VfsMetadata { file_type: VfsFileType::File, len, mtime })
150+
Ok(VfsMetadata { file_type: VfsFileType::File, len, mtime: self.mtime })
146151
}
147152
}
148153
} else {
@@ -168,19 +173,21 @@ impl WadContent {
168173
Self { inner: WadContentInner::Stream(inner), mtime }
169174
}
170175

171-
fn convert_to_mapped(&mut self) {
176+
fn convert_to_mapped(&mut self) -> io::Result<()> {
172177
match &mut self.inner {
173178
WadContentInner::Stream(stream) => {
174-
let pos = stream.stream_position().unwrap();
175-
stream.seek(SeekFrom::Start(0)).unwrap();
176-
let mut data = vec![0u8; stream.len() as usize];
177-
stream.read_exact(&mut data).unwrap();
178-
let mut cursor = Cursor::new(Arc::from(data.as_slice()));
179+
let pos = stream.stream_position()?;
180+
stream.seek(SeekFrom::Start(0))?;
181+
let mut data = <[u8]>::new_box_zeroed_with_elems(stream.len() as usize)
182+
.map_err(|_| io::Error::from(io::ErrorKind::OutOfMemory))?;
183+
stream.read_exact(&mut data)?;
184+
let mut cursor = Cursor::new(Arc::from(data));
179185
cursor.set_position(pos);
180186
self.inner = WadContentInner::Mapped(cursor);
181187
}
182188
WadContentInner::Mapped(_) => {}
183189
};
190+
Ok(())
184191
}
185192
}
186193

@@ -220,7 +227,7 @@ impl Seek for WadContent {
220227

221228
impl VfsFile for WadContent {
222229
fn map(&mut self) -> io::Result<&[u8]> {
223-
self.convert_to_mapped();
230+
self.convert_to_mapped()?;
224231
match &mut self.inner {
225232
WadContentInner::Stream(_) => unreachable!(),
226233
WadContentInner::Mapped(data) => Ok(data.get_ref()),

0 commit comments

Comments
 (0)