/* DeflaterEngine.java --
   Copyright (C) 2001, 2004, 2005  Free Software Foundation, Inc.

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */

package java.util.zip;

class DeflaterEngine implements DeflaterConstants
{
  private static final int TOO_FAR = 4096;

  private int ins_h;

  /**
   * Hashtable, hashing three characters to an index for window, so
   * that window[index]..window[index+2] have this hash code.  
   * Note that the array should really be unsigned short, so you need
   * to and the values with 0xffff.
   */
  private short[] head;

  /**
   * prev[index & WMASK] points to the previous index that has the
   * same hash code as the string starting at index.  This way 
   * entries with the same hash code are in a linked list.
   * Note that the array should really be unsigned short, so you need
   * to and the values with 0xffff.
   */
  private short[] prev;

  private int matchStart, matchLen;
  private boolean prevAvailable;
  private int blockStart;

  /**
   * strstart points to the current character in window.
   */
  private int strstart;

  /**
   * lookahead is the number of characters starting at strstart in
   * window that are valid.
   * So window[strstart] until window[strstart+lookahead-1] are valid
   * characters.
   */
  private int lookahead;

  /**
   * This array contains the part of the uncompressed stream that 
   * is of relevance.  The current character is indexed by strstart.
   */
  private byte[] window;

  private int strategy, max_chain, max_lazy, niceLength, goodLength;

  /** The current compression function. */
  private int comprFunc;

  /** The input data for compression. */
  private byte[] inputBuf;

  /** The total bytes of input read. */
  private long totalIn;

  /** The offset into inputBuf, where input data starts. */
  private int inputOff;

  /** The end offset of the input data. */
  private int inputEnd;

  private DeflaterPending pending;
  private DeflaterHuffman huffman;

  /** The adler checksum */
  private Adler32 adler;

  /* DEFLATE ALGORITHM:
   *
   * The uncompressed stream is inserted into the window array.  When
   * the window array is full the first half is thrown away and the
   * second half is copied to the beginning.
   *
   * The head array is a hash table.  Three characters build a hash value
   * and they the value points to the corresponding index in window of 
   * the last string with this hash.  The prev array implements a
   * linked list of matches with the same hash: prev[index & WMASK] points
   * to the previous index with the same hash.
   * 
   * 
   */


  DeflaterEngine(DeflaterPending pending) {
    this.pending = pending;
    huffman = new DeflaterHuffman(pending);
    adler = new Adler32();

    window = new byte[2*WSIZE];
    head   = new short[HASH_SIZE];
    prev   = new short[WSIZE];

    /* We start at index 1, to avoid a implementation deficiency, that
     * we cannot build a repeat pattern at index 0.
     */
    blockStart = strstart = 1;
  }

  public void reset()
  {
    huffman.reset();
    adler.reset();
    blockStart = strstart = 1;
    lookahead = 0;
    totalIn = 0;
    prevAvailable = false;
    matchLen = MIN_MATCH - 1;
    for (int i = 0; i < HASH_SIZE; i++)
      head[i] = 0;
    for (int i = 0; i < WSIZE; i++)
      prev[i] = 0;
  }

  public final void resetAdler()
  {
    adler.reset();
  }

  public final int getAdler()
  {
    int chksum = (int) adler.getValue();
    return chksum;
  }

  public final long getTotalIn()
  {
    return totalIn;
  }

  public final void setStrategy(int strat)
  {
    strategy = strat;
  }

  public void setLevel(int lvl)
  {
    goodLength = DeflaterConstants.GOOD_LENGTH[lvl];
    max_lazy    = DeflaterConstants.MAX_LAZY[lvl];
    niceLength = DeflaterConstants.NICE_LENGTH[lvl];
    max_chain   = DeflaterConstants.MAX_CHAIN[lvl];

    if (DeflaterConstants.COMPR_FUNC[lvl] != comprFunc) 
      {
	if (DeflaterConstants.DEBUGGING)
	  System.err.println("Change from "+comprFunc +" to "
			     + DeflaterConstants.COMPR_FUNC[lvl]);
	switch (comprFunc)
	  {
	  case DEFLATE_STORED:
	    if (strstart > blockStart)
	      {
		huffman.flushStoredBlock(window, blockStart, 
					 strstart - blockStart, false);
		blockStart = strstart;
	      }
	    updateHash();
	    break;
	  case DEFLATE_FAST:
	    if (strstart > blockStart)
	      {
		huffman.flushBlock(window, blockStart, strstart - blockStart,
				   false);
		blockStart = strstart;
	      }
	    break;
	  case DEFLATE_SLOW:
	    if (prevAvailable)
	      huffman.tallyLit(window[strstart-1] & 0xff);
	    if (strstart > blockStart)
	      {
		huffman.flushBlock(window, blockStart, strstart - blockStart,
				   false);
		blockStart = strstart;
	      }
	    prevAvailable = false;
	    matchLen = MIN_MATCH - 1;
	    break;
	  }
	comprFunc = COMPR_FUNC[lvl];
      }
  }

  private void updateHash() {
    if (DEBUGGING)
      System.err.println("updateHash: "+strstart);
    ins_h = (window[strstart] << HASH_SHIFT) ^ window[strstart + 1];
  }    

  /**
   * Inserts the current string in the head hash and returns the previous
   * value for this hash.
   */
  private int insertString() {
    short match;
    int hash = ((ins_h << HASH_SHIFT) ^ window[strstart + (MIN_MATCH -1)])
      & HASH_MASK;

    if (DEBUGGING)
      {
	if (hash != (((window[strstart] << (2*HASH_SHIFT))
		      ^ (window[strstart + 1] << HASH_SHIFT)
		      ^ (window[strstart + 2])) & HASH_MASK))
	  throw new InternalError("hash inconsistent: "+hash+"/"
				  +window[strstart]+","
				  +window[strstart+1]+","
				  +window[strstart+2]+","+HASH_SHIFT);
      }

    prev[strstart & WMASK] = match = head[hash];
    head[hash] = (short) strstart;
    ins_h = hash;
    return match & 0xffff;
  }

  private void slideWindow()
  {
    System.arraycopy(window, WSIZE, window, 0, WSIZE);
    matchStart -= WSIZE;
    strstart -= WSIZE;
    blockStart -= WSIZE;
    
    /* Slide the hash table (could be avoided with 32 bit values
     * at the expense of memory usage).
     */
    for (int i = 0; i < HASH_SIZE; i++) 
      {
	int m = head[i] & 0xffff;
	head[i] = m >= WSIZE ? (short) (m - WSIZE) : 0;
      }

    /* Slide the prev table.
     */
    for (int i = 0; i < WSIZE; i++) 
      {
	int m = prev[i] & 0xffff;
	prev[i] = m >= WSIZE ? (short) (m - WSIZE) : 0;
      }
  }

  /**
   * Fill the window when the lookahead becomes insufficient.
   * Updates strstart and lookahead.
   *
   * OUT assertions: strstart + lookahead <= 2*WSIZE
   *    lookahead >= MIN_LOOKAHEAD or inputOff == inputEnd
   */
  private void fillWindow()
  {
    /* If the window is almost full and there is insufficient lookahead,
     * move the upper half to the lower one to make room in the upper half.
     */
    if (strstart >= WSIZE + MAX_DIST)
      slideWindow();

    /* If there is not enough lookahead, but still some input left,
     * read in the input
     */
    while (lookahead < DeflaterConstants.MIN_LOOKAHEAD && inputOff < inputEnd)
      {
	int more = 2*WSIZE - lookahead - strstart;
	
	if (more > inputEnd - inputOff)
	  more = inputEnd - inputOff;

	System.arraycopy(inputBuf, inputOff, 
			 window, strstart + lookahead, more);
	adler.update(inputBuf, inputOff, more);
	inputOff += more;
	totalIn  += more;
	lookahead += more;
      }

    if (lookahead >= MIN_MATCH) 
      updateHash();
  }

  /**
   * Find the best (longest) string in the window matching the 
   * string starting at strstart.
   *
   * Preconditions:
   *    strstart + MAX_MATCH <= window.length.
   *    
   *
   * @param curMatch
   */
  private boolean findLongestMatch(int curMatch) {
    int chainLength = this.max_chain;
    int niceLength = this.niceLength;
    short[] prev = this.prev;
    int scan  = this.strstart;
    int match;
    int best_end = this.strstart + matchLen;
    int best_len = Math.max(matchLen, MIN_MATCH - 1);
    
    int limit = Math.max(strstart - MAX_DIST, 0);

    int strend = scan + MAX_MATCH - 1;
    byte scan_end1 = window[best_end - 1];
    byte scan_end  = window[best_end];

    /* Do not waste too much time if we already have a good match: */
    if (best_len >= this.goodLength)
      chainLength >>= 2;

    /* Do not look for matches beyond the end of the input. This is necessary
     * to make deflate deterministic.
     */
    if (niceLength > lookahead)
      niceLength = lookahead;

    if (DeflaterConstants.DEBUGGING 
	&& strstart > 2*WSIZE - MIN_LOOKAHEAD)
      throw new InternalError("need lookahead");
    
    do {
      if (DeflaterConstants.DEBUGGING && curMatch >= strstart)
	throw new InternalError("future match");
      if (window[curMatch + best_len] != scan_end
	  || window[curMatch + best_len - 1] != scan_end1
	  || window[curMatch] != window[scan]
	  || window[curMatch+1] != window[scan + 1])
	continue;

      match = curMatch + 2;      
      scan += 2;

      /* We check for insufficient lookahead only every 8th comparison;
       * the 256th check will be made at strstart+258.
       */
      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)
        ;

      if (scan > best_end) {
//  	if (DeflaterConstants.DEBUGGING && ins_h == 0)
//  	  System.err.println("Found match: "+curMatch+"-"+(scan-strstart));
	matchStart = curMatch;
	best_end = scan;
	best_len = scan - strstart;
	if (best_len >= niceLength)
	  break;

	scan_end1  = window[best_end-1];
	scan_end   = window[best_end];
      }
      scan = strstart;
    } while ((curMatch = (prev[curMatch & WMASK] & 0xffff)) > limit
	     && --chainLength != 0);

    matchLen = Math.min(best_len, lookahead);
    return matchLen >= MIN_MATCH;
  }

  void setDictionary(byte[] buffer, int offset, int length) {
    if (DeflaterConstants.DEBUGGING && strstart != 1)
      throw new IllegalStateException("strstart not 1");
    adler.update(buffer, offset, length);
    if (length < MIN_MATCH)
      return;
    if (length > MAX_DIST) {
      offset += length - MAX_DIST;
      length = MAX_DIST;
    }

    System.arraycopy(buffer, offset, window, strstart, length);

    updateHash();
    length--;
    while (--length > 0)
      {
	insertString();
	strstart++;
      }
    strstart += 2;
    blockStart = strstart;
  }    
    
  private boolean deflateStored(boolean flush, boolean finish)
  {
    if (!flush && lookahead == 0)
      return false;

    strstart += lookahead;
    lookahead = 0;

    int storedLen = strstart - blockStart;

    if ((storedLen >= DeflaterConstants.MAX_BLOCK_SIZE) 
	/* Block is full */
	|| (blockStart < WSIZE && storedLen >= MAX_DIST)
	/* Block may move out of window */
	|| flush)
      {
	boolean lastBlock = finish;
	if (storedLen > DeflaterConstants.MAX_BLOCK_SIZE)
	  {
	    storedLen = DeflaterConstants.MAX_BLOCK_SIZE;
	    lastBlock = false;
	  }

	if (DeflaterConstants.DEBUGGING)
	  System.err.println("storedBlock["+storedLen+","+lastBlock+"]");

	huffman.flushStoredBlock(window, blockStart, storedLen, lastBlock);
	blockStart += storedLen;
	return !lastBlock;
      }
    return true;
  }

  private boolean deflateFast(boolean flush, boolean 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 need this.
	     * This should only happen when flushing and the window
	     * is almost full.
	     */
	    slideWindow();
	  }

	int hashHead;
	if (lookahead >= MIN_MATCH 
	    && (hashHead = insertString()) != 0
	    && strategy != Deflater.HUFFMAN_ONLY
	    && strstart - hashHead <= MAX_DIST
	    && findLongestMatch(hashHead))
	  {
	    /* longestMatch sets matchStart and matchLen */
	    if (DeflaterConstants.DEBUGGING)
	      {
		for (int i = 0 ; i < matchLen; i++)
		  {
		    if (window[strstart+i] != window[matchStart + i])
		      throw new InternalError();
		  }
	      }
	    boolean 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())
	  {
	    boolean lastBlock = finish && lookahead == 0;
	    huffman.flushBlock(window, blockStart, strstart - blockStart,
			       lastBlock);
	    blockStart = strstart;
	    return !lastBlock;
	  }
      }
    return true;
  }

  private boolean deflateSlow(boolean flush, boolean finish)
  {
    if (lookahead < MIN_LOOKAHEAD && !flush)
      return false;

    while (lookahead >= MIN_LOOKAHEAD || flush)
      {
	if (lookahead == 0)
	  {
	    if (prevAvailable)
	      huffman.tallyLit(window[strstart-1] & 0xff);
	    prevAvailable = false;

	    /* We are flushing everything */
	    if (DeflaterConstants.DEBUGGING && !flush)
	      throw new InternalError("Not flushing, but no lookahead");
	    huffman.flushBlock(window, blockStart, strstart - blockStart,
			       finish);
	    blockStart = strstart;
	    return false;
	  }

	if (strstart >= 2 * WSIZE - MIN_LOOKAHEAD)
	  {
	    /* slide window, as findLongestMatch need this.
	     * This should only happen when flushing and the window
	     * is almost full.
	     */
	    slideWindow();
	  }

	int prevMatch = matchStart;
	int prevLen = matchLen;
	if (lookahead >= MIN_MATCH)
	  {
	    int hashHead = insertString();
	    if (strategy != Deflater.HUFFMAN_ONLY
		&& hashHead != 0 && strstart - hashHead <= MAX_DIST
		&& findLongestMatch(hashHead))
	      {
		/* longestMatch sets matchStart and matchLen */
		
		/* Discard match if too small and too far away */
		if (matchLen <= 5
		    && (strategy == Deflater.FILTERED
			|| (matchLen == MIN_MATCH
			    && strstart - matchStart > TOO_FAR))) {
		  matchLen = MIN_MATCH - 1;
		}
	      }
	  }
	
	/* previous match was better */
	if (prevLen >= MIN_MATCH && matchLen <= prevLen)
	  {
	    if (DeflaterConstants.DEBUGGING)
	      {
		for (int i = 0 ; i < matchLen; i++)
		  {
		    if (window[strstart-1+i] != window[prevMatch + i])
		      throw new InternalError();
		  }
	      }
	    huffman.tallyDist(strstart - 1 - prevMatch, prevLen);
	    prevLen -= 2;
	    do 
	      {
		strstart++;
		lookahead--;
		if (lookahead >= MIN_MATCH)
		  insertString();
	      }
	    while (--prevLen > 0);
	    strstart ++;
	    lookahead--;
	    prevAvailable = false;
	    matchLen = MIN_MATCH - 1;
	  }
	else
	  {
	    if (prevAvailable)
	      huffman.tallyLit(window[strstart-1] & 0xff);
	    prevAvailable = true;
	    strstart++;
	    lookahead--;
	  }

	if (huffman.isFull())
	  {
	    int len = strstart - blockStart;
	    if (prevAvailable)
	      len--;
	    boolean lastBlock = (finish && lookahead == 0 && !prevAvailable);
	    huffman.flushBlock(window, blockStart, len, lastBlock);
	    blockStart += len;
	    return !lastBlock;
	  }
      }
    return true;
  } 

  public boolean deflate(boolean flush, boolean finish) 
  {
    boolean progress;
    do
      {
	fillWindow();
	boolean canFlush = flush && inputOff == inputEnd;
	if (DeflaterConstants.DEBUGGING)
	  System.err.println("window: ["+blockStart+","+strstart+","
			     +lookahead+"], "+comprFunc+","+canFlush);
	switch (comprFunc)
	  {
	  case DEFLATE_STORED:
	    progress = deflateStored(canFlush, finish);
	    break;
	  case DEFLATE_FAST:
	    progress = deflateFast(canFlush, finish);
	    break;
	  case DEFLATE_SLOW:
	    progress = deflateSlow(canFlush, finish);
	    break;
	  default:
	    throw new InternalError();
	  }
      }
    while (pending.isFlushed()  /* repeat while we have no pending output */
	   && progress);        /* and progress was made */

    return progress;
  }

  public void setInput(byte[] buf, int off, int len)
  {
    if (inputOff < inputEnd)
      throw new IllegalStateException
	("Old input was not completely processed");

    int end = off + len;

    /* We want to throw an ArrayIndexOutOfBoundsException early.  The
     * check is very tricky: it also handles integer wrap around.  
     */
    if (0 > off || off > end || end > buf.length)
      throw new ArrayIndexOutOfBoundsException();

    inputBuf = buf;
    inputOff = off;
    inputEnd = end;
  }

  public final boolean needsInput()
  {
    return inputEnd == inputOff;
  }
}
