Maraiah/source/marathon/defl.rs

88 lines
1.5 KiB
Rust

//! DEFLATE loader.
use crate::durandal::err::*;
/// Loads a ZLIB file header.
pub fn load_zlib_header(b: &[u8]) -> ResultS<usize>
{
const CM: u8 = 0b00001111;
const CINFO: u8 = 0b11110000;
const FDICT: u8 = 0b00100000;
read_data! {
2, BE in b =>
fcheck = u16[0];
cmf = u8[0];
flg = u8[1];
}
let cm = cmf & CM;
let cinfo = cmf & CINFO >> 4;
if cm != 8 || fcheck % 31 != 0 || cinfo > 7 {
bail!("not zlib format");
}
if flg & FDICT != 0 {
bail!("dictionary not supported");
}
Ok(2)
}
/// Loads a GZIP file header.
pub fn load_gzip_header(b: &[u8]) -> ResultS<usize>
{
const FHCRC: u8 = 1 << 1;
const FEXTRA: u8 = 1 << 2;
const FNAME: u8 = 1 << 3;
const FCOMMENT: u8 = 1 << 4;
read_data! {
10, LE in b =>
id = u16[0];
cm = u8[2];
fl = u8[3];
}
if id != 0x8B1F || cm != 8 {
bail!("not gzip format");
}
let mut p = 10;
if fl & FEXTRA != 0 {
read_data!(p + 2, LE in b => xlen = u16[p] usize;);
check_data!(p + 2 + xlen, b);
p += xlen;
}
if fl & FNAME != 0 {
p = skip_zero_terminated_item(&b[p..])?;
}
if fl & FCOMMENT != 0 {
p = skip_zero_terminated_item(&b[p..])?;
}
if fl & FHCRC != 0 {
check_data!(p + 2, b);
p += 2;
}
Ok(p)
}
fn skip_zero_terminated_item(b: &[u8]) -> ResultS<usize>
{
if let Some(i) = b.iter().position(|&n| n == 0) {
Ok(i)
} else {
bail!("no end of zero terminated item");
}
}
// EOF