Decoder now has Opt type of implementing additional info that required to deal with complex decoding and add more context to result objects
This commit is contained in:
parent
c49622e2ac
commit
10fd8bb7cc
11 changed files with 37 additions and 12 deletions
|
|
@ -1,4 +1,5 @@
|
||||||
mod decoder;
|
mod decoder;
|
||||||
|
mod entity;
|
||||||
mod esh;
|
mod esh;
|
||||||
mod fstring;
|
mod fstring;
|
||||||
mod raw;
|
mod raw;
|
||||||
|
|
|
||||||
|
|
@ -3,13 +3,15 @@ use anyhow::Result;
|
||||||
use std::str;
|
use std::str;
|
||||||
|
|
||||||
pub trait Decoder: Sized {
|
pub trait Decoder: Sized {
|
||||||
fn decode(raw: &Raw, offset: usize, size: usize) -> Result<Self>;
|
type Opt;
|
||||||
|
fn decode(raw: &Raw, offset: usize, size: usize, opt: Option<Self::Opt>) -> Result<Self>;
|
||||||
fn encode(&self) -> Result<Raw>;
|
fn encode(&self) -> Result<Raw>;
|
||||||
fn get_enc_size(&self) -> usize;
|
fn get_enc_size(&self) -> usize;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Decoder for String {
|
impl Decoder for String {
|
||||||
fn decode(raw: &Raw, offset: usize, size: usize) -> Result<Self> {
|
type Opt = ();
|
||||||
|
fn decode(raw: &Raw, offset: usize, size: usize, _: Option<()>) -> Result<Self> {
|
||||||
let str = &raw.mem[offset..];
|
let str = &raw.mem[offset..];
|
||||||
match str.iter().position(|&c| c == 0) {
|
match str.iter().position(|&c| c == 0) {
|
||||||
Some(pos) => Ok(str::from_utf8(&str[..pos])?.to_string()),
|
Some(pos) => Ok(str::from_utf8(&str[..pos])?.to_string()),
|
||||||
|
|
|
||||||
0
src/fot/entity.rs
Normal file
0
src/fot/entity.rs
Normal file
|
|
@ -76,7 +76,8 @@ impl ESHValue {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Decoder for ESHValue {
|
impl Decoder for ESHValue {
|
||||||
fn decode(raw: &Raw, offset: usize, _: usize) -> Result<Self> {
|
type Opt = ();
|
||||||
|
fn decode(raw: &Raw, offset: usize, _: usize, _: Option<()>) -> Result<Self> {
|
||||||
let mut rd = ReadStream::new(raw, offset);
|
let mut rd = ReadStream::new(raw, offset);
|
||||||
let data_type = rd.read_u32()?;
|
let data_type = rd.read_u32()?;
|
||||||
let data_size = rd.read_u32()?;
|
let data_size = rd.read_u32()?;
|
||||||
|
|
@ -248,7 +249,8 @@ pub struct ESH {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Decoder for ESH {
|
impl Decoder for ESH {
|
||||||
fn decode(raw: &Raw, offset: usize, _: usize) -> Result<Self> {
|
type Opt = ();
|
||||||
|
fn decode(raw: &Raw, offset: usize, _: usize, _: Option<()>) -> Result<Self> {
|
||||||
let mut rd = ReadStream::new(raw, offset);
|
let mut rd = ReadStream::new(raw, offset);
|
||||||
let tag: Tag = rd.read(0)?;
|
let tag: Tag = rd.read(0)?;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,8 @@ pub struct FString {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Decoder for FString {
|
impl Decoder for FString {
|
||||||
fn decode(raw: &Raw, offset: usize, _: usize) -> Result<Self> {
|
type Opt = ();
|
||||||
|
fn decode(raw: &Raw, offset: usize, _: usize, _: Option<()>) -> Result<Self> {
|
||||||
let mut rdr = Cursor::new(&raw.mem[offset..]);
|
let mut rdr = Cursor::new(&raw.mem[offset..]);
|
||||||
let flen = rdr.read_u32::<LittleEndian>()? as usize;
|
let flen = rdr.read_u32::<LittleEndian>()? as usize;
|
||||||
let len = flen & !(1 << 31);
|
let len = flen & !(1 << 31);
|
||||||
|
|
|
||||||
|
|
@ -46,7 +46,7 @@ impl Save {
|
||||||
return Err(anyhow!("Unable to determine world block size"));
|
return Err(anyhow!("Unable to determine world block size"));
|
||||||
}
|
}
|
||||||
|
|
||||||
let world = World::decode(&raw, world_offset, world_size)?;
|
let world = World::decode(&raw, world_offset, world_size, None)?;
|
||||||
Ok(Save { raw, world })
|
Ok(Save { raw, world })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,8 @@ pub struct SGD {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Decoder for SGD {
|
impl Decoder for SGD {
|
||||||
fn decode(raw: &Raw, offset: usize, _: usize) -> Result<Self> {
|
type Opt = ();
|
||||||
|
fn decode(raw: &Raw, offset: usize, _: usize, _: Option<()>) -> Result<Self> {
|
||||||
let mut rd = ReadStream::new(raw, offset);
|
let mut rd = ReadStream::new(raw, offset);
|
||||||
let tag: Tag = rd.read(0)?;
|
let tag: Tag = rd.read(0)?;
|
||||||
let unk1 = rd.read_bytes(0x48)?;
|
let unk1 = rd.read_bytes(0x48)?;
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,8 @@ pub struct SSG {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Decoder for SSG {
|
impl Decoder for SSG {
|
||||||
fn decode(raw: &Raw, offset: usize, _: usize) -> Result<Self> {
|
type Opt = ();
|
||||||
|
fn decode(raw: &Raw, offset: usize, _: usize, _: Option<()>) -> Result<Self> {
|
||||||
let mut rd = ReadStream::new(raw, offset);
|
let mut rd = ReadStream::new(raw, offset);
|
||||||
let tag: Tag = rd.read(0)?;
|
let tag: Tag = rd.read(0)?;
|
||||||
let unk1 = rd.read_bytes(0x14)?;
|
let unk1 = rd.read_bytes(0x14)?;
|
||||||
|
|
|
||||||
|
|
@ -43,8 +43,17 @@ impl<'a> ReadStream<'a> {
|
||||||
// "size" is not required to be actual size, it's only
|
// "size" is not required to be actual size, it's only
|
||||||
// a hint for Decoder::decode. Most of the structures are
|
// a hint for Decoder::decode. Most of the structures are
|
||||||
// dynamically determining their decoding and encoding sizes
|
// dynamically determining their decoding and encoding sizes
|
||||||
|
|
||||||
|
// read_opt - decode with optional paramters. required for complex structure
|
||||||
|
// with different origins (save / entfile) like entities
|
||||||
|
pub fn read_opt<T: Decoder>(&mut self, size: usize, opt: T::Opt) -> Result<T> {
|
||||||
|
let val = T::decode(&self.raw, self.offset(), size, Some(opt))?;
|
||||||
|
self.skip(val.get_enc_size());
|
||||||
|
Ok(val)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn read<T: Decoder>(&mut self, size: usize) -> Result<T> {
|
pub fn read<T: Decoder>(&mut self, size: usize) -> Result<T> {
|
||||||
let val = T::decode(&self.raw, self.offset(), size)?;
|
let val = T::decode(&self.raw, self.offset(), size, None)?;
|
||||||
self.skip(val.get_enc_size());
|
self.skip(val.get_enc_size());
|
||||||
Ok(val)
|
Ok(val)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,8 @@ pub struct Tag {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Decoder for Tag {
|
impl Decoder for Tag {
|
||||||
fn decode(raw: &Raw, offset: usize, size: usize) -> Result<Self> {
|
type Opt = ();
|
||||||
|
fn decode(raw: &Raw, offset: usize, size: usize, _: Option<()>) -> Result<Self> {
|
||||||
let mut rd = ReadStream::new(raw, offset);
|
let mut rd = ReadStream::new(raw, offset);
|
||||||
let name: String = rd.read(0)?;
|
let name: String = rd.read(0)?;
|
||||||
let version: String = rd.read(0)?;
|
let version: String = rd.read(0)?;
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,13 @@ impl World {
|
||||||
}
|
}
|
||||||
|
|
||||||
let name = &types[type_idx as usize];
|
let name = &types[type_idx as usize];
|
||||||
println!("offset {:x} idx {} unk1 {} name {}", rd.offset(), i, unk2, name);
|
println!(
|
||||||
|
"offset {:x} idx {} unk1 {} name {}",
|
||||||
|
rd.offset(),
|
||||||
|
i,
|
||||||
|
unk2,
|
||||||
|
name
|
||||||
|
);
|
||||||
let _: ESH = rd.read(0)?;
|
let _: ESH = rd.read(0)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -61,7 +67,8 @@ impl World {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Decoder for World {
|
impl Decoder for World {
|
||||||
fn decode(raw: &Raw, offset: usize, size: usize) -> Result<Self> {
|
type Opt = ();
|
||||||
|
fn decode(raw: &Raw, offset: usize, size: usize, _: Option<()>) -> Result<Self> {
|
||||||
let mut enc = ReadStream::new(raw, offset);
|
let mut enc = ReadStream::new(raw, offset);
|
||||||
|
|
||||||
let tag: Tag = enc.read(Self::WORLD_TAG_LEN)?;
|
let tag: Tag = enc.read(Self::WORLD_TAG_LEN)?;
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue