From 36e11b95e89c55f8c7995bc8a0b3bc7bd6d35f3e Mon Sep 17 00:00:00 2001 From: Marrub Date: Sun, 31 Mar 2019 22:20:56 -0400 Subject: [PATCH] actually add the utilities for the write functions --- source/marathon/map.rs | 6 ++-- source/marathon/text.rs | 73 ++++++++++++++++++++++++++++++++++++++--- 2 files changed, 71 insertions(+), 8 deletions(-) diff --git a/source/marathon/map.rs b/source/marathon/map.rs index 997e99b..9a70c6b 100644 --- a/source/marathon/map.rs +++ b/source/marathon/map.rs @@ -49,7 +49,7 @@ pub fn read_sidetex(b: &[u8]) -> ResultS pub fn write_sidetex(v: &SideTex) -> Vec { let mut o = Vec::with_capacity(6); - o.extend(write_point(&v.offs)); + o.extend(write_point(v.offs)); o.extend(&v.tex_id.to_be_bytes()); o } @@ -68,7 +68,7 @@ pub fn read_point(b: &[u8]) -> ResultS } /// Writes a `Point` object. -pub fn write_point(v: &Point) -> Vec +pub fn write_point(v: Point) -> Vec { let mut o = Vec::with_capacity(4); o.extend(&v.x.to_be_bytes()); @@ -104,7 +104,7 @@ pub fn write_minf(v: &Minf) -> Vec o.extend(&v.skypict_id.to_be_bytes()); o.extend(&v.miss_flags.bits().to_be_bytes()); o.extend(&v.envi_flags.bits().to_be_bytes()); - o.extend(&pad_0(to_mac_roman(v.level_name), 66)); + o.extend(&pad_zero(to_mac_roman(&v.level_name), 66)); o.extend(&v.entr_flags.bits().to_be_bytes()); o } diff --git a/source/marathon/text.rs b/source/marathon/text.rs index fc41163..2b537e1 100644 --- a/source/marathon/text.rs +++ b/source/marathon/text.rs @@ -84,11 +84,13 @@ pub fn mac_roman_conv(s: &[u8]) -> String let mut v = String::with_capacity(s.len()); for &c in s.iter() { - v.push(match c { - c if c & 0x80 != 0 => TR[usize::from(c) & 0x7F], - b'\r' => '\n', - c => char::from(c), - }); + let c = match c { + 0x80..=0xFF => TR[usize::from(c) & 0x7F], + b'\r' => '\n', + c => char::from(c), + }; + + v.push(c); } v @@ -115,6 +117,67 @@ pub fn mac_roman_cstr(s: &[u8]) -> String } } +/// Converts input from a Unicode string to Mac Roman. +/// +/// # Examples +/// +/// ``` +/// use maraiah::marathon::text::to_mac_roman; +/// +/// assert_eq!(to_mac_roman("påth"), b"p\x8cth".to_vec()); +/// assert_eq!(to_mac_roman("I’ve\n"), b"I\xd5ve\r".to_vec()); +/// ``` +pub fn to_mac_roman(s: &str) -> Vec +{ + let mut v = Vec::with_capacity(s.len()); + + for c in s.chars() { + let c = match c { + '\n' => { + b'\r' + } + '\0'..='\x7f' => { + c as u8 + } + c => { + if let Some(c) = TR.iter().position(|&o| o == c) { + c as u8 + 0x80 + } else { + 0x7f + } + } + }; + + v.push(c); + } + + v +} + +/// Pads the output with zeroes. +/// +/// # Examples +/// +/// ``` +/// use maraiah::marathon::text::{pad_zero, to_mac_roman}; +/// +/// let s = to_mac_roman("påth"); +/// +/// assert_eq!(pad_zero(s.clone(), 8), b"p\x8cth\0\0\0\0".to_vec()); +/// assert_eq!(pad_zero(s.clone(), 6), b"p\x8cth\0\0".to_vec()); +/// assert_eq!(pad_zero(s.clone(), 4), b"p\x8cth".to_vec()); +/// assert_eq!(pad_zero(s.clone(), 2), b"p\x8cth".to_vec()); +/// assert_eq!(pad_zero(s.clone(), 0), b"p\x8cth".to_vec()); +/// ``` +pub fn pad_zero(mut v: Vec, n: usize) -> Vec +{ + for _ in v.len()..n { + v.push(0); + } + + v +} + const TR: [char; 128] = ['\u{00c4}', '\u{00c5}', '\u{00c7}', '\u{00c9}', '\u{00d1}', '\u{00d6}', '\u{00dc}', '\u{00e1}', '\u{00e0}', '\u{00e2}', '\u{00e4}', '\u{00e3}',