utils: factorize reading file into vector
This commit is contained in:
parent
992144801b
commit
052c061917
|
@ -8,7 +8,7 @@ use nom::Err::{Error as NomError, Failure as NomFailure};
|
||||||
use crate::name_hashes;
|
use crate::name_hashes;
|
||||||
use crate::parsers::bhd;
|
use crate::parsers::bhd;
|
||||||
use crate::unpackers::errors::UnpackError;
|
use crate::unpackers::errors::UnpackError;
|
||||||
use crate::utils::fs as fs_utils;
|
use crate::utils::fs as utils_fs;
|
||||||
|
|
||||||
/// Parse a BHD file and extract its content from sister BDT.
|
/// Parse a BHD file and extract its content from sister BDT.
|
||||||
///
|
///
|
||||||
|
@ -20,10 +20,7 @@ pub fn extract_bhd(
|
||||||
names: &HashMap<String, String>,
|
names: &HashMap<String, String>,
|
||||||
output_path: &str
|
output_path: &str
|
||||||
) -> Result<(), UnpackError> {
|
) -> Result<(), UnpackError> {
|
||||||
let mut bhd_file = fs::File::open(bhd_path)?;
|
let bhd_data = utils_fs::open_file_to_vec(bhd_path)?;
|
||||||
let file_len = bhd_file.metadata()?.len() as usize;
|
|
||||||
let mut bhd_data = vec![0u8; file_len];
|
|
||||||
bhd_file.read_exact(&mut bhd_data)?;
|
|
||||||
let bhd = match bhd::parse(&bhd_data) {
|
let bhd = match bhd::parse(&bhd_data) {
|
||||||
Ok((_, bhd)) => bhd,
|
Ok((_, bhd)) => bhd,
|
||||||
Err(NomError(e)) | Err(NomFailure(e)) => return Err(UnpackError::parsing_err("BHD", e.1)),
|
Err(NomError(e)) | Err(NomFailure(e)) => return Err(UnpackError::parsing_err("BHD", e.1)),
|
||||||
|
@ -45,7 +42,7 @@ fn extract_files(
|
||||||
output_path: &str,
|
output_path: &str,
|
||||||
) -> Result<(), io::Error> {
|
) -> Result<(), io::Error> {
|
||||||
let output_path = path::Path::new(output_path);
|
let output_path = path::Path::new(output_path);
|
||||||
fs_utils::ensure_dir_exists(output_path)?;
|
utils_fs::ensure_dir_exists(output_path)?;
|
||||||
|
|
||||||
for bucket in &bhd.buckets {
|
for bucket in &bhd.buckets {
|
||||||
for entry in bucket {
|
for entry in bucket {
|
||||||
|
@ -64,7 +61,7 @@ fn extract_files(
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let file_path = output_path.join(rel_path);
|
let file_path = output_path.join(rel_path);
|
||||||
fs_utils::ensure_dir_exists(file_path.parent().unwrap())?;
|
utils_fs::ensure_dir_exists(file_path.parent().unwrap())?;
|
||||||
let mut output_file = fs::File::create(file_path)?;
|
let mut output_file = fs::File::create(file_path)?;
|
||||||
output_file.write_all(&data)?;
|
output_file.write_all(&data)?;
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,12 +6,10 @@ use nom::Err::{Error as NomError, Failure as NomFailure};
|
||||||
|
|
||||||
use crate::parsers::bhf;
|
use crate::parsers::bhf;
|
||||||
use crate::unpackers::errors::UnpackError;
|
use crate::unpackers::errors::UnpackError;
|
||||||
|
use crate::utils::fs as utils_fs;
|
||||||
|
|
||||||
pub fn extract_bhf(bhf_path: &str) -> Result<(), UnpackError> {
|
pub fn extract_bhf(bhf_path: &str) -> Result<(), UnpackError> {
|
||||||
let mut bhf_file = fs::File::open(bhf_path)?;
|
let bhf_data = utils_fs::open_file_to_vec(bhf_path)?;
|
||||||
let file_len = bhf_file.metadata()?.len() as usize;
|
|
||||||
let mut bhf_data = vec![0u8; file_len];
|
|
||||||
bhf_file.read_exact(&mut bhf_data)?;
|
|
||||||
let bhf = match bhf::parse(&bhf_data) {
|
let bhf = match bhf::parse(&bhf_data) {
|
||||||
Ok((_, bhf)) => { bhf }
|
Ok((_, bhf)) => { bhf }
|
||||||
Err(NomError(e)) | Err(NomFailure(e)) => return Err(UnpackError::parsing_err("BHF", e.1)),
|
Err(NomError(e)) | Err(NomFailure(e)) => return Err(UnpackError::parsing_err("BHF", e.1)),
|
||||||
|
@ -22,6 +20,8 @@ pub fn extract_bhf(bhf_path: &str) -> Result<(), UnpackError> {
|
||||||
if bdt_path.is_none() {
|
if bdt_path.is_none() {
|
||||||
return Err(UnpackError::Naming(format!("Can't find BDT for BHF: {}", bhf_path)))
|
return Err(UnpackError::Naming(format!("Can't find BDT for BHF: {}", bhf_path)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::io::{Read, Write};
|
use std::io::Write;
|
||||||
use std::path;
|
use std::path;
|
||||||
|
|
||||||
use nom::Err::{Error as NomError, Failure as NomFailure};
|
use nom::Err::{Error as NomError, Failure as NomFailure};
|
||||||
|
|
||||||
use crate::parsers::bnd;
|
use crate::parsers::bnd;
|
||||||
use crate::unpackers::errors::UnpackError;
|
use crate::unpackers::errors::UnpackError;
|
||||||
use crate::utils::fs as fs_utils;
|
use crate::utils::fs as utils_fs;
|
||||||
|
|
||||||
/// Extract BND file contents to disk.
|
/// Extract BND file contents to disk.
|
||||||
///
|
///
|
||||||
|
@ -32,7 +32,7 @@ pub fn extract_bnd(
|
||||||
overwrite: bool
|
overwrite: bool
|
||||||
) -> Result<(), UnpackError> {
|
) -> Result<(), UnpackError> {
|
||||||
let output_dir = path::Path::new(output_dir);
|
let output_dir = path::Path::new(output_dir);
|
||||||
fs_utils::ensure_dir_exists(output_dir)?;
|
utils_fs::ensure_dir_exists(output_dir)?;
|
||||||
for file_info in &bnd.file_infos {
|
for file_info in &bnd.file_infos {
|
||||||
// Extract all entries, print but ignore path errors.
|
// Extract all entries, print but ignore path errors.
|
||||||
match extract_bnd_entry(file_info, bnd_data, output_dir, overwrite) {
|
match extract_bnd_entry(file_info, bnd_data, output_dir, overwrite) {
|
||||||
|
@ -83,10 +83,7 @@ fn extract_bnd_entry(
|
||||||
/// Wraps around `load_bnd` to load the BND from disk. It returns the
|
/// Wraps around `load_bnd` to load the BND from disk. It returns the
|
||||||
/// parsed BND metadata and the whole file as a byte vector.
|
/// parsed BND metadata and the whole file as a byte vector.
|
||||||
pub fn load_bnd_file(bnd_path: &str) -> Result<(bnd::Bnd, Vec<u8>), UnpackError> {
|
pub fn load_bnd_file(bnd_path: &str) -> Result<(bnd::Bnd, Vec<u8>), UnpackError> {
|
||||||
let mut bnd_file = fs::File::open(bnd_path)?;
|
let bnd_data = utils_fs::open_file_to_vec(bnd_path)?;
|
||||||
let file_len = bnd_file.metadata()?.len() as usize;
|
|
||||||
let mut bnd_data = vec![0u8; file_len];
|
|
||||||
bnd_file.read_exact(&mut bnd_data)?;
|
|
||||||
Ok((load_bnd(&bnd_data)?, bnd_data))
|
Ok((load_bnd(&bnd_data)?, bnd_data))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@ use nom::Err::{Error as NomError, Failure as NomFailure};
|
||||||
|
|
||||||
use crate::parsers::dcx;
|
use crate::parsers::dcx;
|
||||||
use crate::unpackers::errors::UnpackError;
|
use crate::unpackers::errors::UnpackError;
|
||||||
|
use crate::utils::fs as utils_fs;
|
||||||
|
|
||||||
/// Extract DCX file content to disk.
|
/// Extract DCX file content to disk.
|
||||||
pub fn extract_dcx(dcx_path: &str, output_path: &str) -> Result<(), UnpackError> {
|
pub fn extract_dcx(dcx_path: &str, output_path: &str) -> Result<(), UnpackError> {
|
||||||
|
@ -17,10 +18,7 @@ pub fn extract_dcx(dcx_path: &str, output_path: &str) -> Result<(), UnpackError>
|
||||||
|
|
||||||
/// Load a DCX file in memory along with its decompressed content.
|
/// Load a DCX file in memory along with its decompressed content.
|
||||||
pub fn load_dcx(dcx_path: &str) -> Result<(dcx::Dcx, Vec<u8>), UnpackError> {
|
pub fn load_dcx(dcx_path: &str) -> Result<(dcx::Dcx, Vec<u8>), UnpackError> {
|
||||||
let mut dcx_file = fs::File::open(dcx_path)?;
|
let dcx_data = utils_fs::open_file_to_vec(dcx_path)?;
|
||||||
let file_len = dcx_file.metadata()?.len() as usize;
|
|
||||||
let mut dcx_data = vec![0u8; file_len];
|
|
||||||
dcx_file.read_exact(&mut dcx_data)?;
|
|
||||||
let (data, dcx) = match dcx::parse(&dcx_data) {
|
let (data, dcx) = match dcx::parse(&dcx_data) {
|
||||||
Ok(result) => result,
|
Ok(result) => result,
|
||||||
Err(NomError(e)) | Err(NomFailure(e)) => return Err(UnpackError::parsing_err("DCX", e.1)),
|
Err(NomError(e)) | Err(NomFailure(e)) => return Err(UnpackError::parsing_err("DCX", e.1)),
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::io;
|
use std::io::{self, Read};
|
||||||
use std::path;
|
use std::path;
|
||||||
|
|
||||||
/// Ensure a directory exists, creating it with parents if necessary.
|
/// Ensure a directory exists, creating it with parents if necessary.
|
||||||
|
@ -24,6 +24,15 @@ pub fn strip_extension(path: &path::PathBuf) -> Option<path::PathBuf> {
|
||||||
Some(pb)
|
Some(pb)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Open a binary file and read it to the end in a byte vector.
|
||||||
|
pub fn open_file_to_vec(path: &str) -> Result<Vec<u8>, io::Error> {
|
||||||
|
let mut file = fs::File::open(path)?;
|
||||||
|
let file_len = file.metadata()?.len() as usize;
|
||||||
|
let mut data = vec![0u8; file_len];
|
||||||
|
file.read_exact(&mut data)?;
|
||||||
|
Ok(data)
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
Reference in a new issue