From dd5bf0325275534e968c817a8c22e92b3d84ae54 Mon Sep 17 00:00:00 2001 From: Marrub Date: Sat, 9 Feb 2019 00:08:53 -0500 Subject: [PATCH] normalize line endings --- src/durandal/crc.rs | 56 ++++----- src/marathon/mod.rs | 18 +-- src/marathon/term.rs | 270 +++++++++++++++++++++---------------------- src/marathon/wad.rs | 228 ++++++++++++++++++------------------ 4 files changed, 286 insertions(+), 286 deletions(-) diff --git a/src/durandal/crc.rs b/src/durandal/crc.rs index 278d66b..692e86b 100644 --- a/src/durandal/crc.rs +++ b/src/durandal/crc.rs @@ -1,28 +1,28 @@ -//! Cyclic redundancy check function. - -fn crc_accum(a: u32) -> u32 -{ - if a & 1 == 1 {0xedb88320 ^ a >> 1} - else {a >> 1} -} - -fn crc_init() -> [u32; 256] -{ - let mut t = [0; 256]; - for n in 0..256 {t[n] = (0..8).fold(n as u32, |a, _| crc_accum(a));} - t -} - -pub fn crc32(b: &[u8], s: u32) -> u32 -{ - let t = crc_init(); - !b.iter().fold(s, |a, &o| {a >> 8 ^ t[(a & 0xff ^ o as u32) as usize]}) -} - -#[test] -fn crc32_lorem_ipsum() -{ - assert_eq!(crc32(b"Lorem ipsum dolor sit amet", !0), 0x5F29D461); -} - -// EOF +//! Cyclic redundancy check function. + +fn crc_accum(a: u32) -> u32 +{ + if a & 1 == 1 {0xedb88320 ^ a >> 1} + else {a >> 1} +} + +fn crc_init() -> [u32; 256] +{ + let mut t = [0; 256]; + for n in 0..256 {t[n] = (0..8).fold(n as u32, |a, _| crc_accum(a));} + t +} + +pub fn crc32(b: &[u8], s: u32) -> u32 +{ + let t = crc_init(); + !b.iter().fold(s, |a, &o| {a >> 8 ^ t[(a & 0xff ^ o as u32) as usize]}) +} + +#[test] +fn crc32_lorem_ipsum() +{ + assert_eq!(crc32(b"Lorem ipsum dolor sit amet", !0), 0x5F29D461); +} + +// EOF diff --git a/src/marathon/mod.rs b/src/marathon/mod.rs index 44818b8..55cf3b6 100644 --- a/src/marathon/mod.rs +++ b/src/marathon/mod.rs @@ -1,9 +1,9 @@ -//! Library for file data formats. - -pub mod machdr; -pub mod map; -pub mod pict; -pub mod term; -pub mod wad; - -// EOF +//! Library for file data formats. + +pub mod machdr; +pub mod map; +pub mod pict; +pub mod term; +pub mod wad; + +// EOF diff --git a/src/marathon/term.rs b/src/marathon/term.rs index 7a32ec2..aade008 100644 --- a/src/marathon/term.rs +++ b/src/marathon/term.rs @@ -1,135 +1,135 @@ -use crate::durandal::{bin::*, chunk::*, err::*, text::*}; -use std::fmt; - -fn read_group(b: &[u8], text: &[u8]) -> ResultS -{ - // flags = b.c_u16b( 0)?; - let ttype = b.c_u16b( 2)?; - let pdata = b.c_i16b( 4)?; - let start = b.c_u16b( 6)? as usize; - let size = b.c_u16b( 8)? as usize; - let lines = b.c_u16b(10)?; - let text = mac_roman_conv(&text[start..start+size]); - let ttype = GroupType::from_repr(ttype)?; - - Ok(Group{ttype, pdata, lines, text}) -} - -fn read_face(b: &[u8]) -> ResultS -{ - let start = b.c_u16b(0)? as usize; - let face = b.c_u16b(2)?; - let color = b.c_u16b(4)?; - - Ok(Face{start, face, color}) -} - -fn read_terminal(b: &[u8]) -> ResultS<(usize, Terminal)> -{ - const SIZE_GROUP: usize = 12; - const SIZE_FACE : usize = 6; - - let end = b.c_u16b(0)? as usize; - let encoded = b.c_u16b(2)? & 1 != 0; - let lines = b.c_u16b(4)?; - let group_n = b.c_u16b(6)? as usize; - let face_n = b.c_u16b(8)? as usize; - - let mut groups = Vec::with_capacity(group_n); - let mut faces = Vec::with_capacity( face_n); - - let mut p = 10; // size of header - - let text_st = p + SIZE_GROUP * group_n + SIZE_FACE * face_n; - let text = &b[text_st..end]; - let text = if encoded {fuck_string(text)} else {text.to_vec()}; - - for _ in 0..group_n { - groups.push(read_group(&b[p..], &text)?); - p += SIZE_GROUP; - } - - for _ in 0..face_n { - faces.push(read_face(&b[p..])?); - p += SIZE_FACE; - } - - Ok((end, Terminal{lines, groups, faces})) -} - -impl Chunker> for Terminal -{ - fn chunk(b: &[u8]) -> ResultS> - { - let mut v = Vec::new(); - let mut p = 0; - - while p < b.len() { - let (size, trm) = read_terminal(&b[p..])?; - v.push(trm); - p += size; - } - - Ok(v) - } -} - -#[derive(Debug)] -pub struct Terminal -{ - lines: u16, - groups: Vec, - faces: Vec, -} - -#[derive(Debug)] -pub struct Face -{ - start: usize, - face: u16, - color: u16, -} - -pub struct Group -{ - ttype: GroupType, - pdata: i16, - lines: u16, - text: String, -} - -c_enum! { - #[derive(Debug)] - pub enum GroupType: u16 - { - 0 => Logon, - 1 => Unfinished, - 2 => Success, - 3 => Failure, - 4 => Info, - 5 => End, - 6 => TeleInter, - 7 => TeleIntra, - 8 => Checkpoint, - 9 => Sound, - 10 => Movie, - 11 => Track, - 12 => Pict, - 13 => Logoff, - 14 => Camera, - 15 => Static, - 16 => Tag, - } -} - -impl fmt::Debug for Group -{ - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result - { - write!(f, "Group{{{:?} {} {}", self.ttype, self.pdata, self.lines)?; - if self.text.len() != 0 {write!(f, ";\n{}", self.text)?;} - write!(f, "}}") - } -} - -// EOF +use crate::durandal::{bin::*, chunk::*, err::*, text::*}; +use std::fmt; + +fn read_group(b: &[u8], text: &[u8]) -> ResultS +{ + // flags = b.c_u16b( 0)?; + let ttype = b.c_u16b( 2)?; + let pdata = b.c_i16b( 4)?; + let start = b.c_u16b( 6)? as usize; + let size = b.c_u16b( 8)? as usize; + let lines = b.c_u16b(10)?; + let text = mac_roman_conv(&text[start..start+size]); + let ttype = GroupType::from_repr(ttype)?; + + Ok(Group{ttype, pdata, lines, text}) +} + +fn read_face(b: &[u8]) -> ResultS +{ + let start = b.c_u16b(0)? as usize; + let face = b.c_u16b(2)?; + let color = b.c_u16b(4)?; + + Ok(Face{start, face, color}) +} + +fn read_terminal(b: &[u8]) -> ResultS<(usize, Terminal)> +{ + const SIZE_GROUP: usize = 12; + const SIZE_FACE : usize = 6; + + let end = b.c_u16b(0)? as usize; + let encoded = b.c_u16b(2)? & 1 != 0; + let lines = b.c_u16b(4)?; + let group_n = b.c_u16b(6)? as usize; + let face_n = b.c_u16b(8)? as usize; + + let mut groups = Vec::with_capacity(group_n); + let mut faces = Vec::with_capacity( face_n); + + let mut p = 10; // size of header + + let text_st = p + SIZE_GROUP * group_n + SIZE_FACE * face_n; + let text = &b[text_st..end]; + let text = if encoded {fuck_string(text)} else {text.to_vec()}; + + for _ in 0..group_n { + groups.push(read_group(&b[p..], &text)?); + p += SIZE_GROUP; + } + + for _ in 0..face_n { + faces.push(read_face(&b[p..])?); + p += SIZE_FACE; + } + + Ok((end, Terminal{lines, groups, faces})) +} + +impl Chunker> for Terminal +{ + fn chunk(b: &[u8]) -> ResultS> + { + let mut v = Vec::new(); + let mut p = 0; + + while p < b.len() { + let (size, trm) = read_terminal(&b[p..])?; + v.push(trm); + p += size; + } + + Ok(v) + } +} + +#[derive(Debug)] +pub struct Terminal +{ + lines: u16, + groups: Vec, + faces: Vec, +} + +#[derive(Debug)] +pub struct Face +{ + start: usize, + face: u16, + color: u16, +} + +pub struct Group +{ + ttype: GroupType, + pdata: i16, + lines: u16, + text: String, +} + +c_enum! { + #[derive(Debug)] + pub enum GroupType: u16 + { + 0 => Logon, + 1 => Unfinished, + 2 => Success, + 3 => Failure, + 4 => Info, + 5 => End, + 6 => TeleInter, + 7 => TeleIntra, + 8 => Checkpoint, + 9 => Sound, + 10 => Movie, + 11 => Track, + 12 => Pict, + 13 => Logoff, + 14 => Camera, + 15 => Static, + 16 => Tag, + } +} + +impl fmt::Debug for Group +{ + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result + { + write!(f, "Group{{{:?} {} {}", self.ttype, self.pdata, self.lines)?; + if self.text.len() != 0 {write!(f, ";\n{}", self.text)?;} + write!(f, "}}") + } +} + +// EOF diff --git a/src/marathon/wad.rs b/src/marathon/wad.rs index 0c69e80..24f5ebe 100644 --- a/src/marathon/wad.rs +++ b/src/marathon/wad.rs @@ -1,114 +1,114 @@ -//! Marathon Wad format handling. - -use crate::durandal::{bin::*, err::*, text::mac_roman_conv}; -use std::{collections::BTreeMap, fmt}; - -impl Wad<'_> -{ - pub fn new(b: &[u8]) -> ResultS - { - if b.len() < 128 {return Err(err_msg("not enough data for Wad header"));} - - let wadver = b.c_u16b( 0)?; - let dataver = b.c_u16b( 2)?; - let origname = mac_roman_conv(&b[4..68]); - // crc = b.c_u32b(68)?; - let dirofs = b.c_u32b(72)? as usize; - let numents = b.c_u16b(76)? as usize; - let appsize = b.c_u16b(78)? as usize; - let wcnksize = b.c_u16b(80)? as usize; - let wentsize = b.c_u16b(82)? as usize; - // parent = b.c_u32b(84)?; - let wadver = Ver::from_repr(wadver)?; - - let is_old = match wadver {Ver::Base => true, _ => false}; - let entsize = if !is_old {10} else {8 }; - let cnksize = if !is_old {16} else {12}; - - if entsize != wentsize {return Err(err_msg("invalid entry size"));} - if cnksize != wcnksize {return Err(err_msg("invalid chunk size"));} - - let mut entries = EntryMap::new(); - let mut p = dirofs; - - for i in 0..numents { - let offset = b.c_u32b(p )? as usize; - 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(err_msg("not enough data for entry"));} - - let chunks = get_chunks(&b[offset..offset+size], cnksize)?; - let appdata = &b[p..p+appsize]; - - entries.insert(index, Entry{chunks, appdata}); - - p += entsize + appsize; - } - - Ok(Wad{wadver, dataver, appsize, origname, entries}) - } -} - -fn get_chunks(b: &[u8], cnksize: usize) -> ResultS -{ - let mut chunks = ChunkMap::new(); - let mut p = 0; - - while p < b.len() { - let iden = b.c_iden(p )?; - // ofs = b.c_u32b(p+ 4)?; - let size = b.c_u32b(p+ 8)? as usize; - // pofs = b.c_u32b(p+12)?; - let beg = p + cnksize; - let end = beg + size; - chunks.insert(iden, &b[beg..end]); - p = end; - } - - Ok(chunks) -} - -type Chunk <'a> = &'a[u8]; -type ChunkMap<'a> = BTreeMap>; -type EntryMap<'a> = BTreeMap>; - -pub struct Entry<'a> -{ - pub chunks: ChunkMap<'a>, - pub appdata: &'a[u8], -} - -#[derive(Debug)] -pub struct Wad<'a> -{ - wadver: Ver, - dataver: u16, - origname: String, - appsize: usize, - pub entries: EntryMap<'a>, -} - -c_enum! { - #[derive(Debug)] - pub enum Ver: u16 - { - 0 => Base, - 1 => Dir, - 2 => Over, - 4 => Inf, - } -} - -impl fmt::Debug for Entry<'_> -{ - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result - { - write!(f, "Entry{{ ")?; - for (iden, _) in &self.chunks {write!(f, "{} ", mac_roman_conv(iden))?;} - if self.appdata.len() != 0 {write!(f, "\nappdata: {:?} ", self.appdata)?;} - write!(f, "}}") - } -} - -// EOF +//! Marathon Wad format handling. + +use crate::durandal::{bin::*, err::*, text::mac_roman_conv}; +use std::{collections::BTreeMap, fmt}; + +impl Wad<'_> +{ + pub fn new(b: &[u8]) -> ResultS + { + if b.len() < 128 {return Err(err_msg("not enough data for Wad header"));} + + let wadver = b.c_u16b( 0)?; + let dataver = b.c_u16b( 2)?; + let origname = mac_roman_conv(&b[4..68]); + // crc = b.c_u32b(68)?; + let dirofs = b.c_u32b(72)? as usize; + let numents = b.c_u16b(76)? as usize; + let appsize = b.c_u16b(78)? as usize; + let wcnksize = b.c_u16b(80)? as usize; + let wentsize = b.c_u16b(82)? as usize; + // parent = b.c_u32b(84)?; + let wadver = Ver::from_repr(wadver)?; + + let is_old = match wadver {Ver::Base => true, _ => false}; + let entsize = if !is_old {10} else {8 }; + let cnksize = if !is_old {16} else {12}; + + if entsize != wentsize {return Err(err_msg("invalid entry size"));} + if cnksize != wcnksize {return Err(err_msg("invalid chunk size"));} + + let mut entries = EntryMap::new(); + let mut p = dirofs; + + for i in 0..numents { + let offset = b.c_u32b(p )? as usize; + 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(err_msg("not enough data for entry"));} + + let chunks = get_chunks(&b[offset..offset+size], cnksize)?; + let appdata = &b[p..p+appsize]; + + entries.insert(index, Entry{chunks, appdata}); + + p += entsize + appsize; + } + + Ok(Wad{wadver, dataver, appsize, origname, entries}) + } +} + +fn get_chunks(b: &[u8], cnksize: usize) -> ResultS +{ + let mut chunks = ChunkMap::new(); + let mut p = 0; + + while p < b.len() { + let iden = b.c_iden(p )?; + // ofs = b.c_u32b(p+ 4)?; + let size = b.c_u32b(p+ 8)? as usize; + // pofs = b.c_u32b(p+12)?; + let beg = p + cnksize; + let end = beg + size; + chunks.insert(iden, &b[beg..end]); + p = end; + } + + Ok(chunks) +} + +type Chunk <'a> = &'a[u8]; +type ChunkMap<'a> = BTreeMap>; +type EntryMap<'a> = BTreeMap>; + +pub struct Entry<'a> +{ + pub chunks: ChunkMap<'a>, + pub appdata: &'a[u8], +} + +#[derive(Debug)] +pub struct Wad<'a> +{ + wadver: Ver, + dataver: u16, + origname: String, + appsize: usize, + pub entries: EntryMap<'a>, +} + +c_enum! { + #[derive(Debug)] + pub enum Ver: u16 + { + 0 => Base, + 1 => Dir, + 2 => Over, + 4 => Inf, + } +} + +impl fmt::Debug for Entry<'_> +{ + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result + { + write!(f, "Entry{{ ")?; + for (iden, _) in &self.chunks {write!(f, "{} ", mac_roman_conv(iden))?;} + if self.appdata.len() != 0 {write!(f, "\nappdata: {:?} ", self.appdata)?;} + write!(f, "}}") + } +} + +// EOF