Skip to content

Commit

Permalink
implement format guessing
Browse files Browse the repository at this point in the history
  • Loading branch information
Ryan-rsm-McKenzie committed Jan 24, 2024
1 parent 5b9f1c7 commit 3f505a6
Show file tree
Hide file tree
Showing 6 changed files with 59 additions and 0 deletions.
1 change: 1 addition & 0 deletions data/common_guess_test/data/misc/example.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
hello world!
Binary file added data/common_guess_test/fo4.ba2
Binary file not shown.
Binary file added data/common_guess_test/tes3.bsa
Binary file not shown.
Binary file added data/common_guess_test/tes4.bsa
Binary file not shown.
55 changes: 55 additions & 0 deletions src/guess.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
use crate::cc;
use core::mem;
use std::io::Read;

#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum FileFormat {
TES3,
TES4,
FO4,
}

const BSA: u32 = cc::make_four(b"BSA");
const BTDX: u32 = cc::make_four(b"BTDX");

#[allow(clippy::module_name_repetitions)]
pub fn guess_format<In>(source: &mut In) -> Option<FileFormat>
where
In: ?Sized + Read,
{
let mut buf = [0u8; mem::size_of::<u32>()];
source.read_exact(&mut buf).ok()?;
let magic = u32::from_le_bytes(buf);
match magic {
0x100 => Some(FileFormat::TES3),
BSA => Some(FileFormat::TES4),
BTDX => Some(FileFormat::FO4),
_ => None,
}
}

#[cfg(test)]
mod tests {
use crate::FileFormat;
use anyhow::Context as _;
use std::{fs::File, path::Path};

#[test]
fn guess() -> anyhow::Result<()> {
let root = Path::new("data/common_guess_test");
let tests = [
(FileFormat::TES3, "tes3.bsa"),
(FileFormat::TES4, "tes4.bsa"),
(FileFormat::FO4, "fo4.ba2"),
];

for (format, file_name) in tests {
let mut file = File::open(root.join(file_name))
.with_context(|| format!("failed to open file: {file_name}"))?;
let guess = crate::guess_format(&mut file);
assert_eq!(guess, Some(format));
}

Ok(())
}
}
3 changes: 3 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,15 @@ mod cc;
mod containers;
mod derive;
pub mod fo4;
mod guess;
mod hashing;
mod io;
mod protocols;
pub mod tes3;
pub mod tes4;

pub use guess::{guess_format, FileFormat};

pub struct Borrowed<'borrow>(pub &'borrow [u8]);

pub struct Copied<'copy>(pub &'copy [u8]);
Expand Down

0 comments on commit 3f505a6

Please sign in to comment.