normalize line endings

png-branch
an 2019-02-09 00:08:53 -05:00
parent 69063cc41a
commit dd5bf03252
4 changed files with 286 additions and 286 deletions

View File

@ -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

View File

@ -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

View File

@ -1,135 +1,135 @@
use crate::durandal::{bin::*, chunk::*, err::*, text::*};
use std::fmt;
fn read_group(b: &[u8], text: &[u8]) -> ResultS<Group>
{
// 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<Face>
{
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<Vec<Terminal>> for Terminal
{
fn chunk(b: &[u8]) -> ResultS<Vec<Terminal>>
{
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<Group>,
faces: Vec<Face>,
}
#[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<Group>
{
// 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<Face>
{
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<Vec<Terminal>> for Terminal
{
fn chunk(b: &[u8]) -> ResultS<Vec<Terminal>>
{
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<Group>,
faces: Vec<Face>,
}
#[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

View File

@ -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<Wad>
{
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<ChunkMap>
{
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<Ident, Chunk<'a>>;
type EntryMap<'a> = BTreeMap<u16 , Entry<'a>>;
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<Wad>
{
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<ChunkMap>
{
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<Ident, Chunk<'a>>;
type EntryMap<'a> = BTreeMap<u16 , Entry<'a>>;
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