/* 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;
  }
}
