internal int longest_match(int cur_match)
{
int chain_length = max_chain_length; // max hash chain length
int scan = strstart; // current string
int match; // matched string
int len; // length of current match
int best_len = prev_length; // best match length so far
int limit = strstart > (w_size - MIN_LOOKAHEAD) ? strstart - (w_size - MIN_LOOKAHEAD) : 0;
int nice_match = this.nice_match;
// Stop when cur_match becomes <= limit. To simplify the code,
// we prevent matches with the string of window index 0.
int wmask = w_mask;
int strend = strstart + MAX_MATCH;
byte scan_end1 = window [scan + best_len - 1];
byte scan_end = window [scan + best_len];
// The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
// It is easy to get rid of this optimization if necessary.
// Do not waste too much time if we already have a good match:
if (prev_length >= good_match) {
chain_length >>= 2;
}
// Do not look for matches beyond the end of the input. This is necessary
// to make deflate deterministic.
if (nice_match > lookahead)
nice_match = lookahead;
do {
match = cur_match;
// Skip to next match if the match length cannot increase
// or if the match length is less than 2:
if (window [match + best_len] != scan_end || window [match + best_len - 1] != scan_end1 || window [match] != window [scan] || window [++match] != window [scan + 1])
continue;
// The check at best_len-1 can be removed because it will be made
// again later. (This heuristic is not always a win.)
// It is not necessary to compare scan[2] and match[2] since they
// are always equal when the other bytes match, given that
// the hash keys are equal and that HASH_BITS >= 8.
scan += 2;
match++;
// We check for insufficient lookahead only every 8th comparison;
// the 256th check will be made at strstart+258.
do {
} while (window[++scan] == window[++match] && window[++scan] == window[++match] && window[++scan] == window[++match] && window[++scan] == window[++match] && window[++scan] == window[++match] && window[++scan] == window[++match] && window[++scan] == window[++match] && window[++scan] == window[++match] && scan < strend);
len = MAX_MATCH - (int)(strend - scan);
scan = strend - MAX_MATCH;
if (len > best_len) {
match_start = cur_match;
best_len = len;
if (len >= nice_match)
break;
scan_end1 = window [scan + best_len - 1];
scan_end = window [scan + best_len];
}
} while ((cur_match = (prev[cur_match & wmask] & 0xffff)) > limit && --chain_length != 0);
if (best_len <= lookahead)
return best_len;
return lookahead;
}