pub mod apploader;
pub mod bi2;
pub mod boot;
pub mod executable;
pub mod fst;
#[doc(inline)]
pub use apploader::*;
#[doc(inline)]
pub use bi2::*;
#[doc(inline)]
pub use boot::*;
#[doc(inline)]
pub use executable::*;
#[doc(inline)]
pub use fst::Fst;
use crate::helper::{ensure, ParseProblem, Parser, ProblemLocation, Seeker};
use crate::Result;
pub struct Gcm {
boot: Boot,
bi2: Bi2,
apploader: Apploader,
executable: Executable,
fst: Fst,
}
impl Gcm {
pub fn from_binary<D: Parser + Seeker>(reader: &mut D) -> Result<Gcm> {
let position = reader.position()?;
let boot = Boot::from_binary(reader)?;
ensure!(
position + 0x440 == reader.position()?,
ParseProblem::InvalidData("invalid boot", std::panic::Location::current())
);
let bi2 = Bi2::from_binary(reader)?;
ensure!(
position + 0x2440 == reader.position()?,
ParseProblem::InvalidData("invalid bi2", std::panic::Location::current())
);
let apploader = Apploader::from_binary(reader)?;
ensure!(
position + 0x2460 + (apploader.data.len() as u64) == reader.position()?,
ParseProblem::InvalidData("invalid apploader", std::panic::Location::current())
);
reader.goto(position + boot.main_executable_offset as u64)?;
let executable = Executable::from_binary(reader)?;
reader.goto(position + boot.fst_offset as u64)?;
let fst = Fst::from_binary(reader, boot.fst_size as usize)?;
Ok(Gcm {
boot,
bi2,
apploader,
executable,
fst,
})
}
pub fn boot(&self) -> &Boot { &self.boot }
pub fn bi2(&self) -> &Bi2 { &self.bi2 }
pub fn apploader(&self) -> &Apploader { &self.apploader }
pub fn executable(&self) -> &Executable { &self.executable }
pub fn fst(&self) -> &Fst { &self.fst }
}