bool DeflateFast(bool flush, bool finish)
{
if (lookahead < MIN_LOOKAHEAD && !flush)
{
return(false);
}
while (lookahead >= MIN_LOOKAHEAD || flush)
{
if (lookahead == 0)
{
// We are flushing everything
huffman.FlushBlock(window, blockStart, strstart - blockStart, finish);
blockStart = strstart;
return(false);
}
if (strstart > 2 * WSIZE - MIN_LOOKAHEAD)
{
/* slide window, as FindLongestMatch needs this.
* This should only happen when flushing and the window
* is almost full.
*/
SlideWindow();
}
int hashHead;
if (lookahead >= MIN_MATCH &&
(hashHead = InsertString()) != 0 &&
strategy != DeflateStrategy.HuffmanOnly &&
strstart - hashHead <= MAX_DIST &&
FindLongestMatch(hashHead))
{
// longestMatch sets matchStart and matchLen
#if DebugDeflation
if (DeflaterConstants.DEBUGGING)
{
for (int i = 0; i < matchLen; i++)
{
if (window[strstart + i] != window[matchStart + i])
{
throw new SharpZipBaseException("Match failure");
}
}
}
#endif
bool full = huffman.TallyDist(strstart - matchStart, matchLen);
lookahead -= matchLen;
if (matchLen <= max_lazy && lookahead >= MIN_MATCH)
{
while (--matchLen > 0)
{
++strstart;
InsertString();
}
++strstart;
}
else
{
strstart += matchLen;
if (lookahead >= MIN_MATCH - 1)
{
UpdateHash();
}
}
matchLen = MIN_MATCH - 1;
if (!full)
{
continue;
}
}
else
{
// No match found
huffman.TallyLit(window[strstart] & 0xff);
++strstart;
--lookahead;
}
if (huffman.IsFull())
{
bool lastBlock = finish && (lookahead == 0);
huffman.FlushBlock(window, blockStart, strstart - blockStart, lastBlock);
blockStart = strstart;
return(!lastBlock);
}
}
return(true);
}