add new error handling

png-branch
an 2018-12-11 03:08:23 -05:00
parent 932ec1a668
commit f0212fe162
8 changed files with 38 additions and 27 deletions

View File

@ -7,4 +7,5 @@ edition = "2018"
[dependencies]
memmap = "0.6"
generic-array = "0.12"
failure = "0.1"
#gtk = "0.4"

View File

@ -1,8 +1,8 @@
//! Binary data conversion utilities.
pub type Ident = [u8; 4];
use crate::durandal::err::*;
pub type ResultS<T> = Result<T, &'static str>;
pub type Ident = [u8; 4];
pub trait BinUtil
{
@ -35,19 +35,19 @@ impl BinUtil for [u8]
{
fn c_iden(&self, i: usize) -> ResultS<Ident>
{
if i + 3 >= self.len() {return Err("not enough data")}
if i + 3 >= self.len() {return err_msg("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")}
if i + 3 >= self.len() {return err_msg("not enough data")}
Ok(u32::from_be_bytes([self[i], self[i+1], self[i+2], self[i+3]]))
}
fn c_u16b(&self, i: usize) -> ResultS<u16>
{
if i + 1 >= self.len() {return Err("not enough data")}
if i + 1 >= self.len() {return err_msg("not enough data")}
Ok(u16::from_be_bytes([self[i], self[i+1]]))
}
}

9
src/durandal/err.rs Normal file
View File

@ -0,0 +1,9 @@
//! Error handling.
pub use failure::{Error, Fail};
pub type ResultS<T> = Result<T, Error>;
pub fn err_msg<T>(s: &'static str) -> ResultS<T> {Err(failure::err_msg(s))}
// EOF

View File

@ -3,6 +3,7 @@
#[allow(dead_code)]
pub mod bin;
pub mod crc;
pub mod err;
pub mod image;
pub mod machead;
pub mod pict;

View File

@ -1,6 +1,6 @@
//! QuickDraw PICT format loader.
use crate::durandal::{bin::*, image::*};
use crate::durandal::{bin::*, err::*, image::*};
use generic_array::*;
const PACK_DEFAULT: u16 = 0;
@ -66,7 +66,7 @@ fn read_rle(b: &[u8], pt: usize, ln: bool) -> ResultS<(Vec<u8>, usize)>
}
if o.len() == pt {Ok((o, p))}
else {Err("incorrect size for compressed scanline")}
else {err_msg("incorrect size for compressed scanline")}
}
/// Expand packed pixel data based on bit depth.
@ -76,7 +76,7 @@ fn expand_data(b: Vec<u8>, depth: u16) -> ResultS<Vec<u8>>
4 => b.len() * 2,
2 => b.len() * 4,
1 => b.len() * 8,
_ => return Err("invalid bit depth")
_ => return err_msg("invalid bit depth")
});
for ch in b {
@ -84,7 +84,7 @@ fn expand_data(b: Vec<u8>, depth: u16) -> ResultS<Vec<u8>>
4 => for i in 1..=0 {o.push(ch >> i * 4 & 0xfu8)}, // 2 nibbles
2 => for i in 3..=0 {o.push(ch >> i * 2 & 0x3u8)}, // 4 dibits
1 => for i in 7..=0 {o.push(ch >> i * 1 & 0x1u8)}, // 8 bits
_ => return Err("invalid bit depth")
_ => return err_msg("invalid bit depth")
}
}
@ -118,8 +118,8 @@ fn read_bitmap_area(mut im: Image, b: &[u8], packed: bool, clip: bool) -> Result
p += 46; // size of header
if pf & 0x8000 == 0 {return Err("PICT1 not supported")}
if xe - xb != w || ye - yb != h {return Err("image bounds are incorrect")}
if pf & 0x8000 == 0 {return err_msg("PICT1 not supported")}
if xe - xb != w || ye - yb != h {return err_msg("image bounds are incorrect")}
let map = if packed {get_clut(&b[p..])?} else {Vec::new()};
@ -156,7 +156,7 @@ fn read_bitmap_area(mut im: Image, b: &[u8], packed: bool, clip: bool) -> Result
Ok(im)
}
else {Err("invalid configuration")},
else {err_msg("invalid configuration")},
16 =>
if pt < 8 || pack == PACK_NONE {
// uncompressed R5G5B5
@ -179,7 +179,7 @@ fn read_bitmap_area(mut im: Image, b: &[u8], packed: bool, clip: bool) -> Result
Ok(im)
}
else {Err("invalid configuration")},
else {err_msg("invalid configuration")},
32 =>
if pt < 8 || pack == PACK_NONE || pack == PACK_NOPAD {
// uncompressed RGB8 or XRGB8
@ -209,14 +209,14 @@ fn read_bitmap_area(mut im: Image, b: &[u8], packed: bool, clip: bool) -> Result
Ok(im)
}
else {Err("invalid configuration")},
_ => Err("invalid bit depth")
else {err_msg("invalid configuration")},
_ => err_msg("invalid bit depth")
}
}
/// Process a CompressedQuickTime operation.
fn read_quicktime_c(_im: Image, _b: &[u8]) -> ResultS<Image>
{Err("compressed quicktime format not implemented")}
{err_msg("compressed quicktime format not implemented")}
/// Load a PICT image.
pub fn load_pict(b: &[u8]) -> ResultS<Image>
@ -289,11 +289,11 @@ pub fn load_pict(b: &[u8]) -> ResultS<Image>
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")
_ => return err_msg("invalid op in PICT")
}
}
Err("no image in data")
err_msg("no image in data")
}
// EOF

View File

@ -1,7 +1,7 @@
pub mod durandal;
pub mod marathon;
use crate::durandal::{bin::ResultS, image::Image, pict::load_pict};
use crate::durandal::{err::*, image::Image, pict::load_pict};
use crate::marathon::{wad, term};
use memmap::Mmap;
use std::{io, io::Write, fs, env};
@ -25,7 +25,7 @@ impl Minf
use crate::durandal::text::mac_roman_conv;
use crate::durandal::bin::*;
if b.len() < 88 {return Err("not enough data for Minf")}
if b.len() < 88 {return err_msg("not enough data for Minf")}
let env_code = b.c_u16b( 0)?;
let physi_id = b.c_u16b( 2)?;
@ -56,12 +56,12 @@ fn write_ppm(fname: &str, im: &Image) -> io::Result<()>
Ok(())
}
fn main() -> io::Result<()>
fn main() -> ResultS<()>
{
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).unwrap();
let wad = wad::Wad::new(&mm)?;
println!("{:#?}", wad);

View File

@ -1,4 +1,4 @@
use crate::durandal::{bin::*, text::*};
use crate::durandal::{bin::*, err::*, text::*};
use std::fmt;
impl Terminal

View File

@ -1,6 +1,6 @@
//! Marathon Wad format handling.
use crate::durandal::{bin::*, machead::try_mac_header, text::mac_roman_conv};
use crate::durandal::{bin::*, err::*, machead::try_mac_header, text::mac_roman_conv};
use std::{collections::BTreeMap, fmt};
type Chunk <'a> = &'a[u8];
@ -47,7 +47,7 @@ impl Wad<'_>
pub fn new(b: &[u8]) -> ResultS<Wad>
{
let b = &b[try_mac_header(b)..];
if b.len() < 128 {return Err("not enough data for Wad header")}
if b.len() < 128 {return err_msg("not enough data for Wad header")}
let wadver = b.c_u16b( 0)?;
let dataver = b.c_u16b( 2)?;
@ -65,7 +65,7 @@ impl Wad<'_>
2 => Ver::Over,
1 => Ver::Dir,
0 => Ver::Base,
_ => return Err("invalid Wad version"),
_ => return err_msg("invalid Wad version"),
};
let is_old = match wadver {Ver::Base => true, _ => false};
@ -80,7 +80,7 @@ impl Wad<'_>
let size = b.c_u32b(p+4)? as usize;
let index = if !is_old {b.c_u16b(p+8)?} else {i as u16};
if offset + size > b.len() {return Err("not enough data for entry")}
if offset + size > b.len() {return err_msg("not enough data for entry")}
let chunks = get_chunks(&b[offset..offset+size], is_old)?;
let appdata = &b[p+entsize..p+entsize+appsize];