/* Inflater.java - Decompress a data stream
   Copyright (C) 1999, 2000, 2001, 2003, 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;

/* Written using on-line Java Platform 1.2 API Specification
 * and JCL book.
 * Believed complete and correct.
 */

/**
 * Inflater is used to decompress data that has been compressed according 
 * to the "deflate" standard described in rfc1950.
 *
 * The usage is as following.  First you have to set some input with
 * <code>setInput()</code>, then inflate() it.  If inflate doesn't
 * inflate any bytes there may be three reasons:
 * <ul>
 * <li>needsInput() returns true because the input buffer is empty.
 * You have to provide more input with <code>setInput()</code>.  
 * NOTE: needsInput() also returns true when, the stream is finished.
 * </li>
 * <li>needsDictionary() returns true, you have to provide a preset 
 *     dictionary with <code>setDictionary()</code>.</li>
 * <li>finished() returns true, the inflater has finished.</li>
 * </ul>
 * Once the first output byte is produced, a dictionary will not be
 * needed at a later stage.
 *
 * @author John Leuner, Jochen Hoenicke
 * @author Tom Tromey
 * @date May 17, 1999
 * @since JDK 1.1
 */
public class Inflater
{
  /* Copy lengths for literal codes 257..285 */
  private static final int CPLENS[] = 
  { 
    3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
    35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258
  };
  
  /* Extra bits for literal codes 257..285 */  
  private static final int CPLEXT[] = 
  { 
    0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2,
    3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0
  };

  /* Copy offsets for distance codes 0..29 */
  private static final int CPDIST[] = {
    1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
    257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
    8193, 12289, 16385, 24577
  };
  
  /* Extra bits for distance codes */
  private static final int CPDEXT[] = {
    0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
    7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 
    12, 12, 13, 13
  };

  /* This are the state in which the inflater can be.  */
  private static final int DECODE_HEADER           = 0;
  private static final int DECODE_DICT             = 1;
  private static final int DECODE_BLOCKS           = 2;
  private static final int DECODE_STORED_LEN1      = 3;
  private static final int DECODE_STORED_LEN2      = 4;
  private static final int DECODE_STORED           = 5;
  private static final int DECODE_DYN_HEADER       = 6;
  private static final int DECODE_HUFFMAN          = 7;
  private static final int DECODE_HUFFMAN_LENBITS  = 8;
  private static final int DECODE_HUFFMAN_DIST     = 9;
  private static final int DECODE_HUFFMAN_DISTBITS = 10;
  private static final int DECODE_CHKSUM           = 11;
  private static final int FINISHED                = 12;

  /** This variable contains the current state. */
  private int mode;

  /**
   * The adler checksum of the dictionary or of the decompressed
   * stream, as it is written in the header resp. footer of the
   * compressed stream.  <br>
   *
   * Only valid if mode is DECODE_DICT or DECODE_CHKSUM.
   */
  private int readAdler;
  /** 
   * The number of bits needed to complete the current state.  This
   * is valid, if mode is DECODE_DICT, DECODE_CHKSUM,
   * DECODE_HUFFMAN_LENBITS or DECODE_HUFFMAN_DISTBITS.  
   */
  private int neededBits;
  private int repLength, repDist;
  private int uncomprLen;
  /**
   * True, if the last block flag was set in the last block of the
   * inflated stream.  This means that the stream ends after the
   * current block.  
   */
  private boolean isLastBlock;

  /**
   * The total number of inflated bytes.
   */
  private long totalOut;
  /**
   * The total number of bytes set with setInput().  This is not the
   * value returned by getTotalIn(), since this also includes the 
   * unprocessed input.
   */
  private long totalIn;
  /**
   * This variable stores the nowrap flag that was given to the constructor.
   * True means, that the inflated stream doesn't contain a header nor the
   * checksum in the footer.
   */
  private boolean nowrap;

  private StreamManipulator input;
  private OutputWindow outputWindow;
  private InflaterDynHeader dynHeader;
  private InflaterHuffmanTree litlenTree, distTree;
  private Adler32 adler;

  /**
   * Creates a new inflater.
   */
  public Inflater ()
  {
    this (false);
  }

  /**
   * Creates a new inflater.
   * @param nowrap true if no header and checksum field appears in the
   * stream.  This is used for GZIPed input.  For compatibility with
   * Sun JDK you should provide one byte of input more than needed in
   * this case.
   */
  public Inflater (boolean nowrap)
  {
    this.nowrap = nowrap;
    this.adler = new Adler32();
    input = new StreamManipulator();
    outputWindow = new OutputWindow();
    mode = nowrap ? DECODE_BLOCKS : DECODE_HEADER;
  }

  /**
   * Finalizes this object.
   */
  protected void finalize ()
  {
    /* Exists only for compatibility */
  }

  /**
   * Frees all objects allocated by the inflater.  There's no reason
   * to call this, since you can just rely on garbage collection (even
   * for the Sun implementation).  Exists only for compatibility
   * with Sun's JDK, where the compressor allocates native memory.
   * If you call any method (even reset) afterwards the behaviour is
   * <i>undefined</i>.  
   */
  public void end ()
  {
    outputWindow = null;
    input = null;
    dynHeader = null;
    litlenTree = null;
    distTree = null;
    adler = null;
  }

  /**
   * Returns true, if the inflater has finished.  This means, that no
   * input is needed and no output can be produced.
   */
  public boolean finished() 
  {
    return mode == FINISHED && outputWindow.getAvailable() == 0;
  }

  /**
   * Gets the adler checksum.  This is either the checksum of all
   * uncompressed bytes returned by inflate(), or if needsDictionary()
   * returns true (and thus no output was yet produced) this is the
   * adler checksum of the expected dictionary.
   * @returns the adler checksum.
   */
  public int getAdler()
  {
    return needsDictionary() ? readAdler : (int) adler.getValue();
  }
  
  /**
   * Gets the number of unprocessed input.  Useful, if the end of the
   * stream is reached and you want to further process the bytes after
   * the deflate stream.  
   * @return the number of bytes of the input which were not processed.
   */
  public int getRemaining()
  {
    return input.getAvailableBytes();
  }
  
  /**
   * Gets the total number of processed compressed input bytes.
   * @return the total number of bytes of processed input bytes.
   */
  public int getTotalIn()
  {
    return (int) (totalIn - getRemaining());
  }

  /**
   * Gets the total number of processed compressed input bytes.
   * @return the total number of bytes of processed input bytes.
   * @since 1.5
   */
  public long getBytesRead()
  {
    return totalIn - getRemaining();
  }

  /**
   * Gets the total number of output bytes returned by inflate().
   * @return the total number of output bytes.
   */
  public int getTotalOut()
  {
    return (int) totalOut;
  }

  /**
   * Gets the total number of output bytes returned by inflate().
   * @return the total number of output bytes.
   * @since 1.5
   */
  public long getBytesWritten()
  {
    return totalOut;
  }

  /**
   * Inflates the compressed stream to the output buffer.  If this
   * returns 0, you should check, whether needsDictionary(),
   * needsInput() or finished() returns true, to determine why no 
   * further output is produced.
   * @param buf the output buffer.
   * @return the number of bytes written to the buffer, 0 if no further
   * output can be produced.  
   * @exception DataFormatException if deflated stream is invalid.
   * @exception IllegalArgumentException if buf has length 0.
   */
  public int inflate (byte[] buf) throws DataFormatException
  {
    return inflate (buf, 0, buf.length);
  }

  /**
   * Inflates the compressed stream to the output buffer.  If this
   * returns 0, you should check, whether needsDictionary(),
   * needsInput() or finished() returns true, to determine why no 
   * further output is produced.
   * @param buf the output buffer.
   * @param off the offset into buffer where the output should start.
   * @param len the maximum length of the output.
   * @return the number of bytes written to the buffer, 0 if no further
   * output can be produced.  
   * @exception DataFormatException if deflated stream is invalid.
   * @exception IndexOutOfBoundsException if the off and/or len are wrong.
   */
  public int inflate (byte[] buf, int off, int len) throws DataFormatException
  {
    /* Special case: len may be zero */
    if (len == 0)
      return 0;
    /* Check for correct buff, off, len triple */
    if (0 > off || off > off + len || off + len > buf.length)
      throw new ArrayIndexOutOfBoundsException();
    int count = 0;
    int more;
    do
      {
	if (mode != DECODE_CHKSUM)
	  {
	    /* Don't give away any output, if we are waiting for the
	     * checksum in the input stream.
	     *
	     * With this trick we have always:
	     *   needsInput() and not finished() 
	     *   implies more output can be produced.  
	     */
	    more = outputWindow.copyOutput(buf, off, len);
	    adler.update(buf, off, more);
	    off += more;
	    count += more;
	    totalOut += more;
	    len -= more;
	    if (len == 0)
	      return count;
	  }
      }
    while (decode() || (outputWindow.getAvailable() > 0
			&& mode != DECODE_CHKSUM));
    return count;
  }

  /**
   * Returns true, if a preset dictionary is needed to inflate the input.
   */
  public boolean needsDictionary ()
  {
    return mode == DECODE_DICT && neededBits == 0;
  }

  /**
   * Returns true, if the input buffer is empty.
   * You should then call setInput(). <br>
   *
   * <em>NOTE</em>: This method also returns true when the stream is finished.
   */
  public boolean needsInput () 
  {
    return input.needsInput ();
  }

  /**
   * Resets the inflater so that a new stream can be decompressed.  All
   * pending input and output will be discarded.
   */
  public void reset ()
  {
    mode = nowrap ? DECODE_BLOCKS : DECODE_HEADER;
    totalIn = totalOut = 0;
    input.reset();
    outputWindow.reset();
    dynHeader = null;
    litlenTree = null;
    distTree = null;
    isLastBlock = false;
    adler.reset();
  }

  /**
   * Sets the preset dictionary.  This should only be called, if
   * needsDictionary() returns true and it should set the same
   * dictionary, that was used for deflating.  The getAdler()
   * function returns the checksum of the dictionary needed.
   * @param buffer the dictionary.
   * @exception IllegalStateException if no dictionary is needed.
   * @exception IllegalArgumentException if the dictionary checksum is
   * wrong.  
   */
  public void setDictionary (byte[] buffer)
  {
    setDictionary(buffer, 0, buffer.length);
  }

  /**
   * Sets the preset dictionary.  This should only be called, if
   * needsDictionary() returns true and it should set the same
   * dictionary, that was used for deflating.  The getAdler()
   * function returns the checksum of the dictionary needed.
   * @param buffer the dictionary.
   * @param off the offset into buffer where the dictionary starts.
   * @param len the length of the dictionary.
   * @exception IllegalStateException if no dictionary is needed.
   * @exception IllegalArgumentException if the dictionary checksum is
   * wrong.  
   * @exception IndexOutOfBoundsException if the off and/or len are wrong.
   */
  public void setDictionary (byte[] buffer, int off, int len)
  {
    if (!needsDictionary())
      throw new IllegalStateException();

    adler.update(buffer, off, len);
    if ((int) adler.getValue() != readAdler)
      throw new IllegalArgumentException("Wrong adler checksum");
    adler.reset();
    outputWindow.copyDict(buffer, off, len);
    mode = DECODE_BLOCKS;
  }

  /**
   * Sets the input.  This should only be called, if needsInput()
   * returns true.
   * @param buf the input.
   * @exception IllegalStateException if no input is needed.
   */
  public void setInput (byte[] buf) 
  {
    setInput (buf, 0, buf.length);
  }

  /**
   * Sets the input.  This should only be called, if needsInput()
   * returns true.
   * @param buf the input.
   * @param off the offset into buffer where the input starts.
   * @param len the length of the input.  
   * @exception IllegalStateException if no input is needed.
   * @exception IndexOutOfBoundsException if the off and/or len are wrong.
   */
  public void setInput (byte[] buf, int off, int len) 
  {
    input.setInput (buf, off, len);
    totalIn += len;
  }

  /**
   * Decodes the deflate header.
   * @return false if more input is needed. 
   * @exception DataFormatException if header is invalid.
   */
  private boolean decodeHeader () throws DataFormatException
  {
    int header = input.peekBits(16);
    if (header < 0)
      return false;
    input.dropBits(16);
    
    /* The header is written in "wrong" byte order */
    header = ((header << 8) | (header >> 8)) & 0xffff;
    if (header % 31 != 0)
      throw new DataFormatException("Header checksum illegal");
    
    if ((header & 0x0f00) != (Deflater.DEFLATED << 8))
      throw new DataFormatException("Compression Method unknown");

    /* Maximum size of the backwards window in bits. 
     * We currently ignore this, but we could use it to make the
     * inflater window more space efficient. On the other hand the
     * full window (15 bits) is needed most times, anyway.
     int max_wbits = ((header & 0x7000) >> 12) + 8;
     */
    
    if ((header & 0x0020) == 0) // Dictionary flag?
      {
	mode = DECODE_BLOCKS;
      }
    else
      {
	mode = DECODE_DICT;
	neededBits = 32;      
      }
    return true;
  }
   
  /**
   * Decodes the dictionary checksum after the deflate header.
   * @return false if more input is needed. 
   */
  private boolean decodeDict ()
  {
    while (neededBits > 0)
      {
	int dictByte = input.peekBits(8);
	if (dictByte < 0)
	  return false;
	input.dropBits(8);
	readAdler = (readAdler << 8) | dictByte;
	neededBits -= 8;
      }
    return false;
  }

  /**
   * Decodes the huffman encoded symbols in the input stream.
   * @return false if more input is needed, true if output window is
   * full or the current block ends.
   * @exception DataFormatException if deflated stream is invalid.  
   */
  private boolean decodeHuffman () throws DataFormatException
  {
    int free = outputWindow.getFreeSpace();
    while (free >= 258)
      {
	int symbol;
	switch (mode)
	  {
	  case DECODE_HUFFMAN:
	    /* This is the inner loop so it is optimized a bit */
	    while (((symbol = litlenTree.getSymbol(input)) & ~0xff) == 0)
	      {
		outputWindow.write(symbol);
		if (--free < 258)
		  return true;
	      } 
	    if (symbol < 257)
	      {
		if (symbol < 0)
		  return false;
		else
		  {
		    /* symbol == 256: end of block */
		    distTree = null;
		    litlenTree = null;
		    mode = DECODE_BLOCKS;
		    return true;
		  }
	      }
		
	    try
	      {
		repLength = CPLENS[symbol - 257];
		neededBits = CPLEXT[symbol - 257];
	      }
	    catch (ArrayIndexOutOfBoundsException ex)
	      {
		throw new DataFormatException("Illegal rep length code");
	      }
	    /* fall through */
	  case DECODE_HUFFMAN_LENBITS:
	    if (neededBits > 0)
	      {
		mode = DECODE_HUFFMAN_LENBITS;
		int i = input.peekBits(neededBits);
		if (i < 0)
		  return false;
		input.dropBits(neededBits);
		repLength += i;
	      }
	    mode = DECODE_HUFFMAN_DIST;
	    /* fall through */
	  case DECODE_HUFFMAN_DIST:
	    symbol = distTree.getSymbol(input);
	    if (symbol < 0)
	      return false;
	    try 
	      {
		repDist = CPDIST[symbol];
		neededBits = CPDEXT[symbol];
	      }
	    catch (ArrayIndexOutOfBoundsException ex)
	      {
		throw new DataFormatException("Illegal rep dist code");
	      }
	    /* fall through */
	  case DECODE_HUFFMAN_DISTBITS:
	    if (neededBits > 0)
	      {
		mode = DECODE_HUFFMAN_DISTBITS;
		int i = input.peekBits(neededBits);
		if (i < 0)
		  return false;
		input.dropBits(neededBits);
		repDist += i;
	      }
	    outputWindow.repeat(repLength, repDist);
	    free -= repLength;
	    mode = DECODE_HUFFMAN;
	    break;
	  default:
	    throw new IllegalStateException();
	  }
      }
    return true;
  }

  /**
   * Decodes the adler checksum after the deflate stream.
   * @return false if more input is needed. 
   * @exception DataFormatException if checksum doesn't match.
   */
  private boolean decodeChksum () throws DataFormatException
  {
    while (neededBits > 0)
      {
	int chkByte = input.peekBits(8);
	if (chkByte < 0)
	  return false;
	input.dropBits(8);
	readAdler = (readAdler << 8) | chkByte;
	neededBits -= 8;
      }
    if ((int) adler.getValue() != readAdler)
      throw new DataFormatException("Adler chksum doesn't match: "
				    +Integer.toHexString((int)adler.getValue())
				    +" vs. "+Integer.toHexString(readAdler));
    mode = FINISHED;
    return false;
  }

  /**
   * Decodes the deflated stream.
   * @return false if more input is needed, or if finished. 
   * @exception DataFormatException if deflated stream is invalid.
   */
  private boolean decode () throws DataFormatException
  {
    switch (mode) 
      {
      case DECODE_HEADER:
	return decodeHeader();
      case DECODE_DICT:
	return decodeDict();
      case DECODE_CHKSUM:
	return decodeChksum();

      case DECODE_BLOCKS:
	if (isLastBlock)
	  {
	    if (nowrap)
	      {
		mode = FINISHED;
		return false;
	      }
	    else
	      {
		input.skipToByteBoundary();
		neededBits = 32;
		mode = DECODE_CHKSUM;
		return true;
	      }
	  }

	int type = input.peekBits(3);
	if (type < 0)
	  return false;
	input.dropBits(3);

	if ((type & 1) != 0)
	  isLastBlock = true;
	switch (type >> 1)
	  {
	  case DeflaterConstants.STORED_BLOCK:
	    input.skipToByteBoundary();
	    mode = DECODE_STORED_LEN1;
	    break;
	  case DeflaterConstants.STATIC_TREES:
	    litlenTree = InflaterHuffmanTree.defLitLenTree;
	    distTree = InflaterHuffmanTree.defDistTree;
	    mode = DECODE_HUFFMAN;
	    break;
	  case DeflaterConstants.DYN_TREES:
	    dynHeader = new InflaterDynHeader();
	    mode = DECODE_DYN_HEADER;
	    break;
	  default:
	    throw new DataFormatException("Unknown block type "+type);
	  }
	return true;

      case DECODE_STORED_LEN1:
	{
	  if ((uncomprLen = input.peekBits(16)) < 0)
	    return false;
	  input.dropBits(16);
	  mode = DECODE_STORED_LEN2;
	}
	/* fall through */
      case DECODE_STORED_LEN2:
	{
	  int nlen = input.peekBits(16);
	  if (nlen < 0)
	    return false;
	  input.dropBits(16);
	  if (nlen != (uncomprLen ^ 0xffff))
	    throw new DataFormatException("broken uncompressed block");
	  mode = DECODE_STORED;
	}
	/* fall through */
      case DECODE_STORED:
	{
	  int more = outputWindow.copyStored(input, uncomprLen);
	  uncomprLen -= more;
	  if (uncomprLen == 0)
	    {
	      mode = DECODE_BLOCKS;
	      return true;
	    }
	  return !input.needsInput();
	}

      case DECODE_DYN_HEADER:
	if (!dynHeader.decode(input))
	  return false;
	litlenTree = dynHeader.buildLitLenTree();
	distTree = dynHeader.buildDistTree();
	mode = DECODE_HUFFMAN;
	/* fall through */
      case DECODE_HUFFMAN:
      case DECODE_HUFFMAN_LENBITS:
      case DECODE_HUFFMAN_DIST:
      case DECODE_HUFFMAN_DISTBITS:
	return decodeHuffman();
      case FINISHED:
	return false;
      default:
	throw new IllegalStateException();
      }	
  }
}
