Added generic header crate.

This commit is contained in:
Filipe Rodrigues 2021-09-13 15:28:24 +01:00
parent a6c36b20db
commit 846659968c
4 changed files with 92 additions and 0 deletions

View File

@ -4,6 +4,7 @@ members = [
"ndsz-nds",
"ndsz-fat",
"ndsz-narc",
"ndsz-generic-header",
"ndsz-mknds",
"ndsz-unnds",
"ndsz-unnarc",

View File

@ -0,0 +1,23 @@
[package]
edition = "2018"
name = "ndsz-generic-header"
version = "0.0.0"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
# Bytes
byteorder = "1.4.3"
# Util
zutil = {git = "https://github.com/Zenithsiz/zutil", rev = "2a029369ac5aa4e7dbd6f6afb78ae419ee18666f"}
# Error handling
thiserror = "1.0.28"
# Logging
log = "0.4.14"
# Serde
serde = {version = "1.0.130", features = ["derive"]}

View File

@ -0,0 +1,13 @@
//! Errors
/// Error for [`Header::from_bytes`](super::Header::from_bytes)
#[derive(PartialEq, Clone, Debug, thiserror::Error)]
pub enum FromBytesError {
/// Wrong constant
#[error("Wrong constant: {constant:#x}")]
WrongConstant { constant: u32 },
/// Wrong header size
#[error("Wrong header size: {header_size:#x}")]
WrongHeaderSize { header_size: u16 },
}

View File

@ -0,0 +1,55 @@
//! Generic header for most nds file formats
//!
//! Adapted from `https://loveemu.hatenablog.com/entry/20091002/nds_formats`,
//! which itself is adapted from `http://llref.emutalk.net/nds_formats.htm` (dead link)
// Modules
mod error;
// Exports
pub use error::FromBytesError;
// Imports
use byteorder::{ByteOrder, LittleEndian};
/// Header
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
pub struct Header {
/// Magic
pub magic: [u8; 4],
/// Section size
pub section_size: u32,
/// Number of sub-sections
pub sub_sections_len: u16,
}
impl Header {
/// Parses a header from bytes
pub fn from_bytes(bytes: &[u8; 0x10]) -> Result<Self, FromBytesError> {
let bytes = zutil::array_split!(bytes,
magic : [0x4],
constant : [0x4],
section_size : [0x4],
header_size : [0x2],
sub_sections_len: [0x2],
);
let constant = LittleEndian::read_u32(bytes.constant);
let header_size = LittleEndian::read_u16(bytes.header_size);
if constant != 0xfffe0001 {
return Err(FromBytesError::WrongConstant { constant });
}
if header_size != 0x10 {
return Err(FromBytesError::WrongHeaderSize { header_size });
}
Ok(Self {
magic: *bytes.magic,
section_size: LittleEndian::read_u32(bytes.section_size),
sub_sections_len: LittleEndian::read_u16(bytes.sub_sections_len),
})
}
}