use crate::encode::Backend;
use crate::lmd::{self, Lmd, LmdMax, MatchDistance};
use std::io;
pub fn check_lmds<T: LmdMax>(bytes: &[u8], mut literals: &[u8], lmds: &[Lmd<T>]) -> bool {
let mut i = 0;
for &Lmd(literal_len, match_len, match_distance) in lmds {
let literal_len = literal_len.get() as usize;
let match_len = match_len.get() as usize;
let match_distance = match_distance.get() as usize;
if literals.len() < literal_len || bytes.len() < i + literal_len {
return false;
}
if literals[..literal_len] != bytes[i..i + literal_len] {
return false;
}
i += literal_len;
literals = &literals[literal_len..];
if bytes.len() < i + match_len {
return false;
}
if bytes[i - match_distance..i - match_distance + match_len] != bytes[i..i + match_len] {
return false;
}
i += match_len;
}
literals.is_empty() && i == bytes.len()
}
pub fn encode_lmds<B: Backend, T: LmdMax>(
dst: &mut Vec<u8>,
backend: &mut B,
mut literals: &[u8],
lmds: &[Lmd<T>],
) -> io::Result<(u32, u32)> {
let len = lmd::n_raw_bytes(lmds);
dst.clear();
dst.reserve(len as usize);
backend.init(dst, Some(len as usize))?;
for &Lmd(literal_len, match_len, match_distance) in lmds {
let literal_len = literal_len.get() as usize;
let match_len = match_len.get();
let match_distance = match_distance.get();
if match_len == 0 {
backend.push_literals(dst, &literals[..literal_len])?;
} else {
let match_distance = MatchDistance::new(match_distance);
backend.push_match(dst, &literals[..literal_len], match_len, match_distance)?;
}
literals = &literals[literal_len..];
}
backend.finalize(dst)?;
assert_eq!(literals.len(), 0);
Ok((len, dst.len() as u32))
}