Improve error handling and syntax
parent
37e1c765d1
commit
6420e4a6e3
|
@ -2,18 +2,56 @@
|
|||
|
||||
pub type Ident = [u8; 4];
|
||||
|
||||
pub fn b_iden(b: &[u8]) -> Ident {[b[0], b[1], b[2], b[3]]}
|
||||
pub type ResultS<T> = Result<T, &'static str>;
|
||||
|
||||
pub fn b_u32l(b: &[u8]) -> u32 {b[3] as (u32) << 24 | b[2] as (u32) << 16 |
|
||||
b[1] as (u32) << 8 | b[0] as u32}
|
||||
pub fn b_u16l(b: &[u8]) -> u16 {b[1] as (u16) << 8 | b[0] as u16}
|
||||
pub fn b_u32b(b: &[u8]) -> u32 {b[0] as (u32) << 24 | b[1] as (u32) << 16 |
|
||||
b[2] as (u32) << 8 | b[3] as u32}
|
||||
pub fn b_u16b(b: &[u8]) -> u16 {b[0] as (u16) << 8 | b[1] as u16}
|
||||
pub fn b_i32l(b: &[u8]) -> i32 {b_u32l(b) as i32}
|
||||
pub fn b_i16l(b: &[u8]) -> i16 {b_u16l(b) as i16}
|
||||
pub fn b_i32b(b: &[u8]) -> i32 {b_u32b(b) as i32}
|
||||
pub fn b_i16b(b: &[u8]) -> i16 {b_u16b(b) as i16}
|
||||
pub trait BinUtil
|
||||
{
|
||||
// Checked
|
||||
fn c_iden(&self, i: usize) -> ResultS<Ident>;
|
||||
fn c_u32b(&self, i: usize) -> ResultS<u32>;
|
||||
fn c_u16b(&self, i: usize) -> ResultS<u16>;
|
||||
|
||||
fn c_i32b(&self, i: usize) -> ResultS<i32>
|
||||
{match self.c_u32b(i) {Ok(n) => Ok(n as i32), Err(e) => Err(e)}}
|
||||
fn c_i16b(&self, i: usize) -> ResultS<i16>
|
||||
{match self.c_u16b(i) {Ok(n) => Ok(n as i16), Err(e) => Err(e)}}
|
||||
|
||||
// Optional
|
||||
fn o_iden(&self, i: usize) -> Option<Ident> {self.c_iden(i).ok()}
|
||||
fn o_u32b(&self, i: usize) -> Option<u32> {self.c_u32b(i).ok()}
|
||||
fn o_u16b(&self, i: usize) -> Option<u16> {self.c_u16b(i).ok()}
|
||||
fn o_i32b(&self, i: usize) -> Option<i32> {self.c_i32b(i).ok()}
|
||||
fn o_i16b(&self, i: usize) -> Option<i16> {self.c_i16b(i).ok()}
|
||||
|
||||
// Unchecked
|
||||
fn b_iden(&self, i: usize) -> Ident {self.c_iden(i).unwrap()}
|
||||
fn b_u32b(&self, i: usize) -> u32 {self.c_u32b(i).unwrap()}
|
||||
fn b_u16b(&self, i: usize) -> u16 {self.c_u16b(i).unwrap()}
|
||||
fn b_i32b(&self, i: usize) -> i32 {self.c_i32b(i).unwrap()}
|
||||
fn b_i16b(&self, i: usize) -> i16 {self.c_i16b(i).unwrap()}
|
||||
}
|
||||
|
||||
impl BinUtil for [u8]
|
||||
{
|
||||
fn c_iden(&self, i: usize) -> ResultS<Ident>
|
||||
{
|
||||
if i + 3 >= self.len() {return Err("not enough data")}
|
||||
Ok([self[i], self[i+1], self[i+2], self[i+3]])
|
||||
}
|
||||
|
||||
fn c_u32b(&self, i: usize) -> ResultS<u32>
|
||||
{
|
||||
if i + 3 >= self.len() {return Err("not enough data")}
|
||||
Ok(self[i ] as (u32) << 24 | self[i+1] as (u32) << 16 |
|
||||
self[i+2] as (u32) << 8 | self[i+3] as (u32))
|
||||
}
|
||||
|
||||
fn c_u16b(&self, i: usize) -> ResultS<u16>
|
||||
{
|
||||
if i + 1 >= self.len() {return Err("not enough data")}
|
||||
Ok(self[i] as (u16) << 8 | self[i+1] as (u16))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn d_u32b(n: u32) -> [u8; 4] {[(n >> 24) as u8, (n >> 16) as u8,
|
||||
(n >> 8) as u8, (n >> 0) as u8]}
|
||||
|
|
|
@ -3,30 +3,29 @@
|
|||
use durandal::bin::*;
|
||||
|
||||
/// Checks for an AppleSingle header. Returns offset to the resource fork.
|
||||
pub fn check_apple_single(b: &[u8]) -> usize
|
||||
pub fn check_apple_single(b: &[u8]) -> Option<usize>
|
||||
{
|
||||
if b_u32b(&b[0..4]) != 0x51600 || b_u32b(&b[4..8]) != 0x20000
|
||||
{return 0}
|
||||
if b.o_u32b(0)? != 0x51600 || b.o_u32b(4)? != 0x20000 {return None}
|
||||
|
||||
let num = b_u16b(&b[24..26]) as usize;
|
||||
let num = b.o_u16b(24)? as usize;
|
||||
|
||||
for i in 0..num
|
||||
{
|
||||
let p = 26 + (12 * i);
|
||||
let fid = b_u32b(&b[p+0..p+ 4]);
|
||||
let ofs = b_u32b(&b[p+4..p+ 8]) as usize;
|
||||
let len = b_u32b(&b[p+8..p+12]) as usize;
|
||||
let fid = b.o_u32b(p )?;
|
||||
let ofs = b.o_u32b(p+4)? as usize;
|
||||
let len = b.o_u32b(p+8)? as usize;
|
||||
|
||||
if fid == 1 {return if ofs + len > b.len() {0} else {ofs}}
|
||||
if fid == 1 {return if ofs + len > b.len() {None} else {Some(ofs)}}
|
||||
}
|
||||
|
||||
0
|
||||
None
|
||||
}
|
||||
|
||||
/// Checks for a MacBin header. Returns offset to the resource fork.
|
||||
pub fn check_mac_bin(b: &[u8]) -> usize
|
||||
pub fn check_mac_bin(b: &[u8]) -> Option<usize>
|
||||
{
|
||||
if b[0] != 0 || b[1] > 63 || b[74] != 0 || b[123] > 0x81 {return 0}
|
||||
if b[0] != 0 || b[1] > 63 || b[74] != 0 || b[123] > 0x81 {return None}
|
||||
|
||||
let mut crc = 0;
|
||||
|
||||
|
@ -39,15 +38,15 @@ pub fn check_mac_bin(b: &[u8]) -> usize
|
|||
}
|
||||
}
|
||||
|
||||
if crc == b_u16b(&b[124..126]) {128} else {0}
|
||||
if crc == b.o_u16b(124)? {Some(128)} else {None}
|
||||
}
|
||||
|
||||
/// Reads a MacBin or AppleSingle header if there is one and returns the
|
||||
/// offset from the start of the header to the resource fork (if one is found.)
|
||||
pub fn try_mac_header(b: &[u8]) -> usize
|
||||
{
|
||||
let ofs = check_mac_bin(b);
|
||||
if ofs != 0 {ofs} else {check_apple_single(b)}
|
||||
let ofs = check_mac_bin(b).unwrap_or(0);
|
||||
if ofs != 0 {ofs} else {check_apple_single(b).unwrap_or(0)}
|
||||
}
|
||||
|
||||
// EOF
|
||||
|
|
|
@ -12,11 +12,11 @@ const PACK_RLE16 : u16 = 3;
|
|||
const PACK_RLE32 : u16 = 4;
|
||||
|
||||
/// Read a colorTable structure.
|
||||
fn get_clut(b: &[u8]) -> Vec<Color>
|
||||
fn get_clut(b: &[u8]) -> ResultS<Vec<Color>>
|
||||
{
|
||||
// = b_u32b(&b[ ..4]); ctSeed
|
||||
let dev = b_u16b(&b[4..6]) & 0x8000 != 0; // ctFlags
|
||||
let num = b_u16b(&b[6..8]) as usize + 1; // ctSize
|
||||
// = b.c_u32b(0)?; ctSeed
|
||||
let dev = b.c_u16b(4)? & 0x8000 != 0; // ctFlags
|
||||
let num = b.c_u16b(6)? as usize + 1; // ctSize
|
||||
let mut map = Vec::new();
|
||||
|
||||
map.resize(num, Color{r: 0, g: 0, b: 0, a: 0});
|
||||
|
@ -24,16 +24,16 @@ fn get_clut(b: &[u8]) -> Vec<Color>
|
|||
for i in 0..num
|
||||
{
|
||||
let p = 8 + i * 8;
|
||||
let n = (b_u16b(&b[p ..p+2]) & 0xff) as usize;
|
||||
let r = (b_u16b(&b[p+2..p+4]) >> 8 ) as u8;
|
||||
let g = (b_u16b(&b[p+4..p+6]) >> 8 ) as u8;
|
||||
let b = (b_u16b(&b[p+6..p+8]) >> 8 ) as u8;
|
||||
let n = (b.c_u16b(p )? & 0xff) as usize;
|
||||
let r = (b.c_u16b(p+2)? >> 8 ) as u8;
|
||||
let g = (b.c_u16b(p+4)? >> 8 ) as u8;
|
||||
let b = (b.c_u16b(p+6)? >> 8 ) as u8;
|
||||
|
||||
// with device mapping, we ignore the index entirely
|
||||
map[if dev {i} else {n}] = Color{r, g, b, a: 255};
|
||||
}
|
||||
|
||||
map
|
||||
Ok(map)
|
||||
}
|
||||
|
||||
/// Read a sequence of packed RLE data.
|
||||
|
@ -51,12 +51,12 @@ fn read_rle_data<F, N>(cmp: bool, len: usize, o: &mut Vec<u8>, mut rd: F)
|
|||
}
|
||||
|
||||
/// Read run-length encoded data.
|
||||
fn read_rle(b: &[u8], pt: usize, ln: bool) -> Result<(Vec<u8>, usize), &str>
|
||||
fn read_rle(b: &[u8], pt: usize, ln: bool) -> ResultS<(Vec<u8>, usize)>
|
||||
{
|
||||
let mut p = 0;
|
||||
let mut o = Vec::with_capacity(pt);
|
||||
let sz = if pt > 250 {(b_u16b(&b[0..2]) as usize + 2, p += 2).0}
|
||||
else {( b[0] as usize + 1, p += 1).0};
|
||||
let sz = if pt > 250 {(b.c_u16b(0)? as usize + 2, p += 2).0}
|
||||
else {(b[0] as usize + 1, p += 1).0};
|
||||
|
||||
while p < sz
|
||||
{
|
||||
|
@ -75,7 +75,7 @@ fn read_rle(b: &[u8], pt: usize, ln: bool) -> Result<(Vec<u8>, usize), &str>
|
|||
}
|
||||
|
||||
/// Expand packed pixel data based on bit depth.
|
||||
fn expand_data(b: Vec<u8>, depth: u16) -> Result<Vec<u8>, &'static str>
|
||||
fn expand_data(b: Vec<u8>, depth: u16) -> ResultS<Vec<u8>>
|
||||
{
|
||||
let mut o = Vec::with_capacity(match depth {
|
||||
4 => b.len() * 2,
|
||||
|
@ -98,7 +98,7 @@ fn expand_data(b: Vec<u8>, depth: u16) -> Result<Vec<u8>, &'static str>
|
|||
}
|
||||
|
||||
/// Process a CopyBits operation.
|
||||
fn read_bitmap_area(mut im: Image, b: &[u8], packed: bool, clip: bool) -> Result<Image, &str>
|
||||
fn read_bitmap_area(mut im: Image, b: &[u8], packed: bool, clip: bool) -> ResultS<Image>
|
||||
{
|
||||
const SIZE_HEAD: usize = 46;
|
||||
|
||||
|
@ -106,38 +106,40 @@ fn read_bitmap_area(mut im: Image, b: &[u8], packed: bool, clip: bool) -> Result
|
|||
|
||||
let (w, h) = (im.w(), im.h());
|
||||
|
||||
let pf = b_u16b(&b[p ..p+2]); // rowBytes
|
||||
let yb = b_u16b(&b[p+ 2..p+ 4]) as usize; // Bounds
|
||||
let xb = b_u16b(&b[p+ 4..p+ 6]) as usize; // 〃
|
||||
let ye = b_u16b(&b[p+ 6..p+ 8]) as usize; // 〃
|
||||
let xe = b_u16b(&b[p+ 8..p+10]) as usize; // 〃
|
||||
// = b_u16b(&b[p+10..p+12]); pmVersion
|
||||
let pack = b_u16b(&b[p+12..p+14]); // packType
|
||||
// = b_u32b(&b[p+14..p+18]); packSize
|
||||
// = b_u32b(&b[p+18..p+22]); hRes
|
||||
// = b_u32b(&b[p+22..p+26]); vRes
|
||||
// = b_u16b(&b[p+26..p+28]); pixelType
|
||||
let dept = b_u16b(&b[p+28..p+30]); // pixelSize
|
||||
// = b_u16b(&b[p+30..p+32]); cmpCount
|
||||
// = b_u16b(&b[p+32..p+34]); cmpSize
|
||||
// = b_u32b(&b[p+34..p+38]); planeBytes
|
||||
// = b_u32b(&b[p+38..p+42]); pmTable
|
||||
// = b_u32b(&b[p+42..p+46]); pmReserved
|
||||
let pf = b.c_u16b(p )?; // rowBytes
|
||||
let yb = b.c_u16b(p+ 2)? as usize; // Bounds
|
||||
let xb = b.c_u16b(p+ 4)? as usize; // 〃
|
||||
let ye = b.c_u16b(p+ 6)? as usize; // 〃
|
||||
let xe = b.c_u16b(p+ 8)? as usize; // 〃
|
||||
// = b.c_u16b(p+10)?; pmVersion
|
||||
let pack = b.c_u16b(p+12)?; // packType
|
||||
// = b.c_u32b(p+14)?; packSize
|
||||
// = b.c_u32b(p+18)?; hRes
|
||||
// = b.c_u32b(p+22)?; vRes
|
||||
// = b.c_u16b(p+26)?; pixelType
|
||||
let dept = b.c_u16b(p+28)?; // pixelSize
|
||||
// = b.c_u16b(p+30)?; cmpCount
|
||||
// = b.c_u16b(p+32)?; cmpSize
|
||||
// = b.c_u32b(p+34)?; planeBytes
|
||||
// = b.c_u32b(p+38)?; pmTable
|
||||
// = b.c_u32b(p+42)?; pmReserved
|
||||
|
||||
p += SIZE_HEAD;
|
||||
|
||||
if pf & 0x8000 == 0 {return Err("PICT1 not supported")}
|
||||
if xe - xb != w || ye - yb != h {return Err("image bounds are incorrect")}
|
||||
|
||||
let map = if packed {get_clut(&b[p..])} else {Vec::new()};
|
||||
let pt = (pf & 0x3fff) as usize;
|
||||
let map = if packed {get_clut(&b[p..])?} else {Vec::new()};
|
||||
|
||||
let rle = pack == PACK_DEFAULT ||
|
||||
(pack == PACK_RLE16 && dept == 16) ||
|
||||
(pack == PACK_RLE32 && dept == 32);
|
||||
|
||||
let pt = (pf & 0x3fff) as usize;
|
||||
|
||||
p += 18 + if packed {8 + map.len() * 8} else {0}; // srcRect, dstRect, mode
|
||||
|
||||
if clip {let sz = b_u16b(&b[p..p+2]) as usize; p += sz} // maskRgn
|
||||
if clip {let sz = b.c_u16b(p)? as usize; p += sz} // maskRgn
|
||||
|
||||
match dept {
|
||||
1 | 2 | 4 | 8 =>
|
||||
|
@ -176,7 +178,7 @@ fn read_bitmap_area(mut im: Image, b: &[u8], packed: bool, clip: bool) -> Result
|
|||
{
|
||||
for _ in 0..h {
|
||||
for _ in 0..w
|
||||
{im.cr.push(Color::from_r5g5b5(b_u16b((&b[p..p+2], p += 2).0)))}
|
||||
{im.cr.push(Color::from_r5g5b5(b.c_u16b((p, p += 2).0)?))}
|
||||
}
|
||||
|
||||
Ok(im)
|
||||
|
@ -192,7 +194,7 @@ fn read_bitmap_area(mut im: Image, b: &[u8], packed: bool, clip: bool) -> Result
|
|||
p += pp;
|
||||
|
||||
for x in 0..w
|
||||
{im.cr.push(Color::from_r5g5b5(b_u16b(&d[x*2..x*2+2])))}
|
||||
{im.cr.push(Color::from_r5g5b5(d.c_u16b(x*2)?))}
|
||||
}
|
||||
|
||||
Ok(im)
|
||||
|
@ -244,25 +246,25 @@ fn read_bitmap_area(mut im: Image, b: &[u8], packed: bool, clip: bool) -> Result
|
|||
}
|
||||
|
||||
/// Process a CompressedQuickTime operation.
|
||||
fn read_quicktime_c(_im: Image, _b: &[u8]) -> Result<Image, &str>
|
||||
fn read_quicktime_c(_im: Image, _b: &[u8]) -> ResultS<Image>
|
||||
{Err("compressed quicktime format not implemented")}
|
||||
|
||||
/// Load a PICT image.
|
||||
pub fn load_pict(b: &[u8]) -> Result<Image, &str>
|
||||
pub fn load_pict(b: &[u8]) -> ResultS<Image>
|
||||
{
|
||||
const SIZE_HEAD: usize = 10;
|
||||
|
||||
// size = b_u16b(&b[0.. 2]);
|
||||
// top = b_u16b(&b[2.. 4]);
|
||||
// left = b_u16b(&b[4.. 6]);
|
||||
let h = b_u16b(&b[6.. 8]) as usize;
|
||||
let w = b_u16b(&b[8..10]) as usize;
|
||||
// size = b.c_u16b(0)?;
|
||||
// top = b.c_u16b(2)?;
|
||||
// left = b.c_u16b(4)?;
|
||||
let h = b.c_u16b(6)? as usize;
|
||||
let w = b.c_u16b(8)? as usize;
|
||||
let im = Image::new(w, h);
|
||||
let mut p = SIZE_HEAD;
|
||||
|
||||
while p < b.len()
|
||||
{
|
||||
let op = b_u16b((&b[p..p+2], p += 2).0);
|
||||
let op = b.c_u16b((p, p += 2).0)?;
|
||||
|
||||
match op {
|
||||
0x0098 => return read_bitmap_area(im, &b[p..], true, false), // PackBitsRect
|
||||
|
@ -316,8 +318,8 @@ pub fn load_pict(b: &[u8]) -> Result<Image, &str>
|
|||
0x0034 => p += 8, // FillRect
|
||||
0x002d => p += 10, // LineJustify
|
||||
0x0c00 => p += 24, // HeaderOp
|
||||
0x0001 => p += (b_u16b(&b[p ..p+2]) & !1) as usize, // Clip
|
||||
0x00a1 => p += (b_u16b(&b[p+2..p+4]) & !1) as usize + 2, // LongComment
|
||||
0x0001 => p += (b.c_u16b(p )? & !1) as usize, // Clip
|
||||
0x00a1 => p += (b.c_u16b(p+2)? & !1) as usize + 2, // LongComment
|
||||
0x100..=
|
||||
0x7fff => p += (op >> 8) as usize * 2, // Reserved
|
||||
_ => return Err("invalid op in PICT")
|
||||
|
|
|
@ -37,7 +37,7 @@ fn main() -> io::Result<()>
|
|||
let arg = env::args().nth(1).expect("need at least 1 argument");
|
||||
let fp = fs::File::open(arg)?;
|
||||
let mm = unsafe{Mmap::map(&fp)?};
|
||||
let wad = wad::Wad::new(&mm);
|
||||
let wad = wad::Wad::new(&mm).unwrap();
|
||||
|
||||
println!("{:#?}", wad);
|
||||
|
||||
|
@ -45,8 +45,7 @@ fn main() -> io::Result<()>
|
|||
{
|
||||
if let Some(b) = ent.map.get(b"PICT")
|
||||
{
|
||||
let im = load_pict(b);
|
||||
match im {
|
||||
match load_pict(b) {
|
||||
Ok(im) => {
|
||||
println!("entry {} has PICT {}x{}", id, im.w(), im.h());
|
||||
write_ppm(&format!("out_{}.ppm", id), &im)?;
|
||||
|
|
|
@ -5,17 +5,17 @@ use durandal::bin::*;
|
|||
|
||||
impl Terminal
|
||||
{
|
||||
pub fn read(b: &[u8]) -> (usize, Terminal)
|
||||
pub fn read(b: &[u8]) -> ResultS<(usize, Terminal)>
|
||||
{
|
||||
const SIZE_HEAD : usize = 10;
|
||||
const SIZE_GROUP: usize = 12;
|
||||
const SIZE_FACE : usize = 6;
|
||||
|
||||
let len = b_u16b(&b[ .. 2]) as usize;
|
||||
let enc = b_u16b(&b[2.. 4]) & 1 != 0;
|
||||
let lns = b_u16b(&b[4.. 6]);
|
||||
let gnu = b_u16b(&b[6.. 8]) as usize;
|
||||
let fnu = b_u16b(&b[8..10]) as usize;
|
||||
let len = b.c_u16b(0)? as usize;
|
||||
let enc = b.c_u16b(2)? & 1 != 0;
|
||||
let lns = b.c_u16b(4)?;
|
||||
let gnu = b.c_u16b(6)? as usize;
|
||||
let fnu = b.c_u16b(8)? as usize;
|
||||
|
||||
let mut grp = Vec::with_capacity(gnu);
|
||||
let mut fcs = Vec::with_capacity(fnu);
|
||||
|
@ -25,12 +25,12 @@ impl Terminal
|
|||
|
||||
for _ in 0..gnu
|
||||
{
|
||||
// flg = b_u16b(&b[p ..p+ 2]);
|
||||
let typ = b_u16b(&b[p+ 2..p+ 4]).into();
|
||||
let per = b_i16b(&b[p+ 4..p+ 6]);
|
||||
let beg = b_u16b(&b[p+ 6..p+ 8]) as usize;
|
||||
let len = b_u16b(&b[p+ 8..p+10]) as usize;
|
||||
let lns = b_u16b(&b[p+10..p+12]);
|
||||
// flg = b.c_u16b(p )?;
|
||||
let typ = b.c_u16b(p+ 2)?.into();
|
||||
let per = b.c_i16b(p+ 4)?;
|
||||
let beg = b.c_u16b(p+ 6)? as usize;
|
||||
let len = b.c_u16b(p+ 8)? as usize;
|
||||
let lns = b.c_u16b(p+10)?;
|
||||
|
||||
let sta = end + beg;
|
||||
|
||||
|
@ -45,19 +45,19 @@ impl Terminal
|
|||
|
||||
for _ in 0..fnu
|
||||
{
|
||||
let ind = b_u16b(&b[p ..p+2]);
|
||||
let fce = b_u16b(&b[p+2..p+4]);
|
||||
let col = b_u16b(&b[p+4..p+6]);
|
||||
let ind = b.c_u16b(p )?;
|
||||
let fce = b.c_u16b(p+2)?;
|
||||
let col = b.c_u16b(p+4)?;
|
||||
|
||||
fcs.push(Face{ind, fce, col});
|
||||
|
||||
p += SIZE_FACE;
|
||||
}
|
||||
|
||||
(len, Terminal{lns, grp, fcs})
|
||||
Ok((len, Terminal{lns, grp, fcs}))
|
||||
}
|
||||
|
||||
pub fn chunk(b: &[u8]) -> Vec<Terminal>
|
||||
pub fn chunk(b: &[u8]) -> ResultS<Vec<Terminal>>
|
||||
{
|
||||
let mut v = Vec::new();
|
||||
let mut p = 0;
|
||||
|
@ -66,14 +66,14 @@ impl Terminal
|
|||
{
|
||||
let sta = p;
|
||||
|
||||
let (len, trm) = Terminal::read(&b[p..]);
|
||||
let (len, trm) = Terminal::read(&b[p..])?;
|
||||
|
||||
v.push(trm);
|
||||
|
||||
p = sta + len;
|
||||
}
|
||||
|
||||
v
|
||||
Ok(v)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -160,7 +160,7 @@ impl fmt::Debug for Group
|
|||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result
|
||||
{
|
||||
write!(f, "Group{{{:?} {} {}", self.typ, self.per, self.lns)?;
|
||||
if self.txt.len() != 0 {write!(f, "\n{}\n", self.txt)?}
|
||||
if self.txt.len() != 0 {write!(f, ";\n{}\n", self.txt)?}
|
||||
write!(f, "}}")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,29 +48,31 @@ impl<'a> fmt::Debug for Entry<'a>
|
|||
|
||||
impl<'a> Wad<'a>
|
||||
{
|
||||
pub fn new(b: &[u8]) -> Wad
|
||||
pub fn new(b: &[u8]) -> ResultS<Wad>
|
||||
{
|
||||
const SIZE_ENTRY_NEW: usize = 10;
|
||||
const SIZE_ENTRY_OLD: usize = 8;
|
||||
|
||||
let b = &b[try_mac_header(b)..];
|
||||
let ver = b_u16b(&b[ .. 2]);
|
||||
let dvr = b_u16b(&b[ 2.. 4]);
|
||||
let nam = &b[ 4..68];
|
||||
// crc = b_u32b(&b[68..72]);
|
||||
let dir = b_u32b(&b[72..76]) as usize;
|
||||
let num = b_u16b(&b[76..78]) as usize;
|
||||
let ext = b_u16b(&b[78..80]) as usize;
|
||||
// hdr = b_u16b(&b[80..82]);
|
||||
// bsz = b_u16b(&b[82..84]);
|
||||
// pck = b_u32b(&b[84..88]);
|
||||
let b = &b[try_mac_header(b)..];
|
||||
if b.len() < 128 {return Err("not enough data for header")}
|
||||
|
||||
let ver = b.c_u16b( 0)?;
|
||||
let dvr = b.c_u16b( 2)?;
|
||||
let nam = &b[4..68];
|
||||
// crc = b.c_u32b(68)?;
|
||||
let dir = b.c_u32b(72)? as usize;
|
||||
let num = b.c_u16b(76)? as usize;
|
||||
let ext = b.c_u16b(78)? as usize;
|
||||
// hdr = b.c_u16b(80)?;
|
||||
// bsz = b.c_u16b(82)?;
|
||||
// pck = b.c_u32b(84)?;
|
||||
|
||||
let ver = match ver {
|
||||
4 => Ver::MI,
|
||||
2 => Ver::M2,
|
||||
1 => Ver::M1Dir,
|
||||
0 => Ver::M1,
|
||||
_ => panic!("invalid wad version {}", ver),
|
||||
_ => return Err("invalid wad version"),
|
||||
};
|
||||
|
||||
let mut map = EntryMap::new();
|
||||
|
@ -80,11 +82,14 @@ impl<'a> Wad<'a>
|
|||
|
||||
for i in 0..num
|
||||
{
|
||||
let ofs = b_u32b(&b[p ..p+ 4]) as usize;
|
||||
let len = b_u32b(&b[p+4..p+ 8]) as usize;
|
||||
let ofs = b.c_u32b(p )? as usize;
|
||||
let len = b.c_u32b(p+4)? as usize;
|
||||
let ind = if o {i as u16}
|
||||
else {b_u16b(&b[p+8..p+10])};
|
||||
let ent = Entry{map: get_chunks(&b[ofs..ofs+len], o),
|
||||
else {b.c_u16b(p+8)?};
|
||||
|
||||
if ofs + len > b.len() {return Err("not enough data for entry")}
|
||||
|
||||
let ent = Entry{map: get_chunks(&b[ofs..ofs+len], o)?,
|
||||
ext: &b[p+h..p+h+ext]};
|
||||
|
||||
map.insert(ind, ent);
|
||||
|
@ -92,13 +97,13 @@ impl<'a> Wad<'a>
|
|||
p += h + ext;
|
||||
}
|
||||
|
||||
Wad{ver, dvr, ext,
|
||||
nam: mac_roman_conv(nam),
|
||||
ent: map}
|
||||
Ok(Wad{ver, dvr, ext,
|
||||
nam: mac_roman_conv(nam),
|
||||
ent: map})
|
||||
}
|
||||
}
|
||||
|
||||
fn get_chunks(b: &[u8], o: bool) -> ChunkMap
|
||||
fn get_chunks(b: &[u8], o: bool) -> ResultS<ChunkMap>
|
||||
{
|
||||
const SIZE_CHUNK_NEW: usize = 16;
|
||||
const SIZE_CHUNK_OLD: usize = 12;
|
||||
|
@ -109,15 +114,15 @@ fn get_chunks(b: &[u8], o: bool) -> ChunkMap
|
|||
|
||||
while p < b.len()
|
||||
{
|
||||
let k = b_iden(&b[p ..p+ 4]);
|
||||
// nx = b_u32b(&b[p+ 4..p+ 8]);
|
||||
let l = b_u32b(&b[p+ 8..p+12]) as usize;
|
||||
// o = b_u32b(&b[p+12..p+16]);
|
||||
let k = b.c_iden(p )?;
|
||||
// nx = b.c_u32b(p+ 4)?;
|
||||
let l = b.c_u32b(p+ 8)? as usize;
|
||||
// o = b.c_u32b(p+12)?;
|
||||
map.insert(k, &b[p+h ..p+h+l]);
|
||||
p += l + h;
|
||||
}
|
||||
|
||||
map
|
||||
Ok(map)
|
||||
}
|
||||
|
||||
// EOF
|
||||
|
|
Loading…
Reference in New Issue