Skip to content
This repository was archived by the owner on Jun 22, 2023. It is now read-only.

Commit 4c8a110

Browse files
committed
Cleaned up error messages
1 parent ff21a52 commit 4c8a110

File tree

3 files changed

+31
-59
lines changed

3 files changed

+31
-59
lines changed

Cargo.lock

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "fo2dat"
3-
version = "0.0.8"
3+
version = "0.0.9"
44
authors = ["Adam Kewley <[email protected]>"]
55

66
[dependencies]
@@ -11,4 +11,3 @@ flate2 = "1.0.1"
1111

1212
[profile.release]
1313
lto = true
14-
panic = "abort"

src/lib.rs

+29-56
Original file line numberDiff line numberDiff line change
@@ -72,10 +72,8 @@ pub fn read_tree_entries(data: &[u8]) -> TreeEntryIterator {
7272

7373
pub fn read_tree_entry(data: &[u8]) -> io::Result<(TreeEntry, usize)> {
7474
if data.len() < TREE_ENTRY_MIN_SIZE {
75-
let err_kind = std::io::ErrorKind::InvalidData;
7675
let err_msg = format!("remaining tree data is too small to actually fit a tree entry");
77-
let err = std::io::Error::new(err_kind, err_msg);
78-
return Err(err);
76+
return Err(Error::new(ErrorKind::InvalidData, err_msg));
7977
}
8078

8179
let filename_len =
@@ -99,10 +97,8 @@ pub fn read_tree_entry(data: &[u8]) -> io::Result<(TreeEntry, usize)> {
9997
Ok(filename)
10098
},
10199
Err(_) => {
102-
let err_kind = std::io::ErrorKind::InvalidData;
103100
let err_msg = format!("cannot decode filename as ASCII");
104-
let err = std::io::Error::new(err_kind, err_msg);
105-
Err(err)
101+
Err(Error::new(ErrorKind::InvalidData, err_msg))
106102
}
107103
}?;
108104

@@ -142,41 +138,33 @@ fn mmap_dat(dat_path_str: &str) -> io::Result<Mmap> {
142138
let dat_file = File::open(dat_path)?;
143139
unsafe { Mmap::map(&dat_file) }
144140
} else {
145-
let err_kind = std::io::ErrorKind::NotFound;
146141
let err_msg = format!("{}: no such file", dat_path_str);
147-
let err = std::io::Error::new(err_kind, err_msg);
148-
return Err(err);
142+
return Err(Error::new(ErrorKind::NotFound, err_msg));
149143
}
150144
}
151145

152146
fn find_entries(dat_file: &[u8]) -> io::Result<TreeEntryIterator> {
153147
let len = dat_file.len();
154148

155149
if len < DAT_FILE_MIN_SIZE {
156-
let err_kind = std::io::ErrorKind::InvalidData;
157150
let err_msg = format!("is too small: must be at least 8 bytes long");
158-
let err = std::io::Error::new(err_kind, err_msg);
159-
return Err(err);
151+
return Err(Error::new(ErrorKind::InvalidData, err_msg));
160152
}
161153

162154
let file_size =
163155
LittleEndian::read_u32(&dat_file[len-4..len]) as usize;
164156

165157
if file_size != len {
166-
let err_kind = std::io::ErrorKind::InvalidData;
167158
let err_msg = format!("size on disk ({}) doesn't match size from dat_file size field ({})", len, file_size);
168-
let err = std::io::Error::new(err_kind, err_msg);
169-
return Err(err);
159+
return Err(Error::new(ErrorKind::InvalidData, err_msg));
170160
}
171161

172162
let tree_size =
173163
LittleEndian::read_u32(&dat_file[len-8..len-4]) as usize;
174164

175165
if tree_size + DAT_FILE_FOOTER_BYTES > file_size {
176-
let err_kind = std::io::ErrorKind::InvalidData;
177166
let err_msg = format!("size on disk ({}) is too small to fit the tree data ({}) plus footers", len, tree_size);
178-
let err = std::io::Error::new(err_kind, err_msg);
179-
return Err(err);
167+
return Err(Error::new(ErrorKind::InvalidData, err_msg));
180168
}
181169

182170
let tree_entries_start = len - tree_size - 4;
@@ -187,65 +175,50 @@ fn find_entries(dat_file: &[u8]) -> io::Result<TreeEntryIterator> {
187175
Ok(read_tree_entries(tree_entries_data))
188176
}
189177

190-
pub fn extract_all_entries(dat_path: &str, output_path: &str) -> io::Result<()> {
191-
let output_path = Path::new(&output_path);
178+
pub fn extract_all_entries(dat_path: &str, output_dir: &str) -> io::Result<()> {
179+
let output_dir = Path::new(&output_dir);
192180

193-
if !output_path.exists() {
194-
let err_kind = std::io::ErrorKind::NotFound;
195-
let err_msg = format!("{}: no such directory", output_path.to_str().unwrap());
196-
let err = std::io::Error::new(err_kind, err_msg);
197-
return Err(err);
198-
} else if !output_path.is_dir() {
199-
let err_kind = std::io::ErrorKind::InvalidInput;
200-
let err_msg = format!("{}: not a directory", output_path.to_str().unwrap());
201-
let err = std::io::Error::new(err_kind, err_msg);
202-
return Err(err);
181+
if !output_dir.exists() {
182+
let err_msg = format!("{}: no such directory", output_dir.to_str().unwrap());
183+
return Err(Error::new(ErrorKind::NotFound, err_msg));
184+
} else if !output_dir.is_dir() {
185+
let err_msg = format!("{}: not a directory", output_dir.to_str().unwrap());
186+
return Err(Error::new(ErrorKind::InvalidInput, err_msg));
203187
} else {
204188
let dat_data = mmap_dat(dat_path)?;
205189
let tree_entries = find_entries(&dat_data)?;
206190

207191
for tree_entry in tree_entries {
208192
let tree_entry = tree_entry?;
209-
extract_entry(&dat_data, &output_path, tree_entry)?;
193+
let entry_data = get_entry_data(&dat_data, &tree_entry)?;
194+
let output_path = output_dir.join(&tree_entry.filename);
195+
write_data(&entry_data, &output_path)?;
210196
}
211197
}
212198

213199
Ok(())
214200
}
215201

216-
fn get_data_slice_for_entry<'a>(dat_data: &'a[u8], entry: &TreeEntry) -> io::Result<&'a[u8]> {
217-
let start = entry.offset;
218-
let end = entry.offset + entry.packed_size;
202+
fn get_entry_data<'a>(dat_data: &'a [u8], entry: &TreeEntry) -> io::Result<&'a [u8]> {
203+
let data_start = entry.offset;
204+
let data_end = data_start + entry.packed_size;
219205

220-
if start > dat_data.len() {
221-
let err_msg = format!("{}: start offset ({}) is outside of the data's bounds", entry.filename.to_str().unwrap(), entry.offset);
222-
Err(Error::new(ErrorKind::InvalidData, err_msg))
223-
} else if end > dat_data.len() {
224-
let err_msg = format!("{}: end index({}) is outside the data's bounds", entry.filename.to_str().unwrap(), entry.offset + entry.packed_size);
225-
Err(Error::new(ErrorKind::InvalidData, err_msg))
226-
} else {
227-
Ok(&dat_data[start..end])
206+
match dat_data.get(data_start..data_end) {
207+
Some(entry_data) => {
208+
Ok(entry_data)
209+
},
210+
None => {
211+
let err_msg = format!("{}: data range ({}-{}) is out of bounds", entry.filename.to_str().unwrap(), data_start, data_end);
212+
Err(Error::new(ErrorKind::InvalidData, err_msg))
213+
}
228214
}
229215
}
230216

231-
fn extract_entry(dat_data: &[u8], output_dir: &Path, entry: TreeEntry) -> io::Result<()> {
232-
let entry_data = get_data_slice_for_entry(&dat_data, &entry)?;
233-
let output_path = output_dir.join(&entry.filename);
234-
217+
fn write_data(entry_data: &[u8], output_path: &Path) -> io::Result<()> {
235218
if let Some(parent) = output_path.parent() {
236219
std::fs::create_dir_all(parent)?;
237220
}
238221

239-
if output_path.exists() {
240-
eprintln!("{}: already exists: skipping", output_path.to_str().unwrap());
241-
} else {
242-
write_entry_data_to_output(&entry_data, &output_path)?;
243-
}
244-
245-
Ok(())
246-
}
247-
248-
fn write_entry_data_to_output(entry_data: &[u8], output_path: &Path) -> io::Result<()> {
249222
let mut output_file = File::create(&output_path)?;
250223

251224
if is_zlib_compressed(&entry_data) {

0 commit comments

Comments
 (0)