still in progress but want to go to laptop

main
aprzn 9 months ago
parent d6fc597ffa
commit 3df54bfa52

@ -1,34 +1,81 @@
/// 5 bits
#[derive(Clone, Copy)]
struct ZChar(u8); struct ZChar(u8);
struct ZsciiChar(u8);
struct ZsciiString(Vec<ZsciiChar>); /// technically 10 bits, but top two unused so they are dropped
#[derive(PartialEq, Clone, Copy)]
pub struct ZsciiChar(u8);
pub type ZsciiString = Vec<ZsciiChar>;
/// Returns: /// Returns:
/// - a result that wraps a ZsciiString, erroring if the slice terminates before the string ends /// - a result that wraps a ZsciiString, erroring if the slice terminates before the string ends
/// - a usize indicating how many bytes were consumed /// - a usize indicating how many bytes were consumed
pub fn decode_zchars(
pub fn decode_zchars(zchars: &[u8]) -> Option<(ZsciiString, usize)> { zchars: &[u8],
alphabet_table: Option<&[u8]>,
abbreviations_table: &[u8],
) -> Option<(ZsciiString, usize)> {
fn cut_string(zchars: &[u8]) -> Option<Vec<u16>> { fn cut_string(zchars: &[u8]) -> Option<Vec<u16>> {
for (i, word) in zchars.chunks_exact(2).map(|c| u16::from_be_bytes([c[0], c[1]])).enumerate() { let mut out = Vec::new();
for word in zchars.chunks_exact(2).map(|c| u16::from_be_bytes([c[0], c[1]])) {
out.push(word);
if 0x8000 & word != 0 {
return Some(out);
}
}
None
}
/// requires: alphabet_num < 3, 5 < char_idx < 32, !(alphabet_num = 2 AND char_idx = 6)
fn index_alphabet(
alphabet_table: Option<&[u8]>,
alphabet_number: usize,
ZChar(char_idx): ZChar,
zchars: &mut impl Iterator<Item = ZChar>,
) -> Option<ZsciiChar> {
let default_alphabet: [[ZsciiChar; 26]; 3] = [
b"abcdefghijklmnopqrstuvwxyz".map(ZsciiChar),
b"ABCDEFGHIJKLMNOPQRSTUVWXYZ".map(ZsciiChar),
br#" 0123456789.,!?_#'"/\-:()"#.map(ZsciiChar)
];
if alphabet_number == 2 && char_idx == 7 {
Some(ZsciiChar(13))
} else if alphabet_number == 2 && char_idx == 6 {
todo!()
} else if let Some(alphabet_table) = alphabet_table {
todo!()
} else {
Some(default_alphabet[alphabet_number][char_idx as usize - 6])
}
}
let zwords = cut_string(zchars)?;
let consumed_length = zwords.len() * 2;
let mut zchars = zwords.iter()
.flat_map(|word| [
(word >> 10) & 0x1f,
(word >> 5) & 0x1f,
word & 0x1f
])
.map(|word| ZChar(word as u8))
.peekable();
let mut out = Vec::new();
let mut current_alphabet = 0;
while let Some(char) = zchars.next() {
match char {
ZChar(0) => out.push(ZsciiChar(32)),
ZChar(1..=3) => todo!("abbreviations"),
ZChar(4..=5) => if zchars.peek().is_some_and(|&ZChar(n)| n > 5) {
if let Some(zc) = index_alphabet(alphabet_table, char.0 as usize - 3, zchars.next().unwrap(), &mut zchars) { out.push(zc) }
},
ZChar(_) => if let Some(zc) = index_alphabet(alphabet_table, 0, char, &mut zchars) {
out.push(zc)
}
} }
} }
let zchars = slice_string(zchars); Some((out, consumed_length))
// let mut index: usize = 0;
// let mut out = Vec::new();
// loop {
// let word = u16::from_be_bytes([zchars[index], zchars[index + 1]]);
// let end_bit_set = word & 0x8000 != 0;
// let chars = [
// (word & (0b11111 << 10)) >> 10,
// (word & (0b11111 << 5)) >> 5,
// (word & (0b11111 << 0)) >> 0,
// ].map(|c| ZChar(c as u8));
// out.extend(chars);
// index += 2;
// if index >= zchars.len() - 1 { break (Err(out), index); }
// if end_bit_set { break (Ok(out), index); }
// // TODO: finish
// }
} }

Loading…
Cancel
Save