use crate::deflate::DeflateState;
use crate::trees::{MAX_MATCH, MIN_MATCH};
impl DeflateState<'_> {
#[inline]
pub(crate) fn update_hash(&mut self, c: u8) {
self.ins_h = ((self.ins_h << self.hash_shift) ^ (c as u32)) & self.hash_mask;
}
#[inline]
pub(crate) fn insert_string(&mut self, str: usize) -> usize {
self.update_hash(self.window[str + MIN_MATCH - 1]);
let h = self.ins_h as usize;
let match_head = self.head[h];
self.prev[str & self.w_mask] = match_head;
self.head[h] = str as u16;
match_head as usize
}
pub(crate) fn longest_match(&mut self, cur_match0: usize) -> usize {
let mut chain_length = self.max_chain_length; let strstart = self.strstart;
let mut best_len = self.prev_length; let mut nice_match = self.nice_match; let max_dist = self.max_dist();
let limit = strstart.saturating_sub(max_dist);
let w_mask = self.w_mask;
let strend = strstart + MAX_MATCH;
let mut cur_match = cur_match0;
let mut scan_end1 = self.window[strstart + best_len - 1];
let mut scan_end = self.window[strstart + best_len];
if self.prev_length >= self.good_match {
chain_length >>= 2;
}
if nice_match > self.lookahead {
nice_match = self.lookahead;
}
loop {
let m = cur_match;
if self.window[m + best_len] != scan_end
|| self.window[m + best_len - 1] != scan_end1
|| self.window[m] != self.window[strstart]
|| self.window[m + 1] != self.window[strstart + 1]
{
} else {
let mut scan_i = strstart + 2;
let mut match_i = m + 2;
'extend: loop {
let mut matched = true;
for _ in 0..8 {
scan_i += 1;
match_i += 1;
if self.window[scan_i] != self.window[match_i] {
matched = false;
break;
}
}
if !matched || scan_i >= strend {
break 'extend;
}
}
let len = MAX_MATCH - (strend - scan_i);
if len > best_len {
self.match_start = cur_match;
best_len = len;
if len >= nice_match {
break;
}
scan_end1 = self.window[strstart + best_len - 1];
scan_end = self.window[strstart + best_len];
}
}
cur_match = self.prev[cur_match & w_mask] as usize;
if cur_match <= limit {
break;
}
chain_length -= 1;
if chain_length == 0 {
break;
}
}
if best_len <= self.lookahead {
best_len
} else {
self.lookahead
}
}
}