/* InflaterInputStream.java - Input stream filter for decompressing
   Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2006
   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;

import java.io.FilterInputStream;
import java.io.IOException;
import java.io.InputStream;

/**
 * This filter stream is used to decompress data compressed in the "deflate"
 * format. The "deflate" format is described in RFC 1951.
 *
 * This stream may form the basis for other decompression filters, such
 * as the <code>GZIPInputStream</code>.
 *
 * @author John Leuner
 * @author Tom Tromey
 * @since 1.1
 */
public class InflaterInputStream extends FilterInputStream
{
  /**
   * Decompressor for this filter 
   */
  protected Inflater inf;

  /**
   * Byte array used as a buffer 
   */
  protected byte[] buf;

  /**
   * Size of buffer   
   */
  protected int len;

  // We just use this if we are decoding one byte at a time with the
  // read() call.
  private byte[] onebytebuffer = new byte[1];

  /**
   * Create an InflaterInputStream with the default decompresseor
   * and a default buffer size.
   *
   * @param in the InputStream to read bytes from
   */
  public InflaterInputStream(InputStream in) 
  {
    this(in, new Inflater(), 4096);
  }

  /**
   * Create an InflaterInputStream with the specified decompresseor
   * and a default buffer size.
   *
   * @param in the InputStream to read bytes from
   * @param inf the decompressor used to decompress data read from in
   */
  public InflaterInputStream(InputStream in, Inflater inf) 
  {
    this(in, inf, 4096);
  }

  /**
   * Create an InflaterInputStream with the specified decompresseor
   * and a specified buffer size.
   *
   * @param in the InputStream to read bytes from
   * @param inf the decompressor used to decompress data read from in
   * @param size size of the buffer to use
   */
  public InflaterInputStream(InputStream in, Inflater inf, int size) 
  {
    super(in);

    if (in == null)
      throw new NullPointerException("in may not be null");
    if (inf == null)
      throw new NullPointerException("inf may not be null");
    if (size < 0)
      throw new IllegalArgumentException("size may not be negative");
    
    this.inf = inf;
    this.buf = new byte [size];
  }

  /**
   * Returns 0 once the end of the stream (EOF) has been reached.
   * Otherwise returns 1.
   */
  public int available() throws IOException
  {
    // According to the JDK 1.2 docs, this should only ever return 0
    // or 1 and should not be relied upon by Java programs.
    if (inf == null)
      throw new IOException("stream closed");
    return inf.finished() ? 0 : 1;
  }

  /**
   * Closes the input stream
   */
  public synchronized void close() throws IOException
  {
    if (in != null)
      in.close();
    in = null;
  }

  /**
   * Fills the buffer with more data to decompress.
   */
  protected void fill() throws IOException
  {
    if (in == null)
      throw new ZipException ("InflaterInputStream is closed");
    
    len = in.read(buf, 0, buf.length);

    if (len < 0)
      throw new ZipException("Deflated stream ends early.");
    
    inf.setInput(buf, 0, len);
  }

  /**
   * Reads one byte of decompressed data.
   *
   * The byte is in the lower 8 bits of the int.
   */
  public int read() throws IOException
  { 
    int nread = read(onebytebuffer, 0, 1);
    if (nread > 0)
      return onebytebuffer[0] & 0xff;
    return -1;
  }

  /**
   * Decompresses data into the byte array
   *
   * @param b the array to read and decompress data into
   * @param off the offset indicating where the data should be placed
   * @param len the number of bytes to decompress
   */
  public int read(byte[] b, int off, int len) throws IOException
  {
    if (inf == null)
      throw new IOException("stream closed");
    if (len == 0)
      return 0;
    if (inf.finished())
      return -1;

    int count = 0;
    while (count == 0)
      {
	if (inf.needsInput())
	  fill();
	
	try
	  {
	    count = inf.inflate(b, off, len);
	    if (count == 0)
	      {
		if (this.len == -1)
		  {
		    // Couldn't get any more data to feed to the Inflater
		    return -1;
		  }
		if (inf.needsDictionary())
		  throw new ZipException("Inflater needs Dictionary");
	      }
	  } 
	catch (DataFormatException dfe) 
	  {
	    throw new ZipException(dfe.getMessage());
	  }
      }
    return count;
  }

  /**
   * Skip specified number of bytes of uncompressed data
   *
   * @param n number of bytes to skip
   */
  public long skip(long n) throws IOException
  {
    if (inf == null)
      throw new IOException("stream closed");
    if (n < 0)
      throw new IllegalArgumentException();

    if (n == 0)
      return 0;

    int buflen = (int) Math.min(n, 2048);
    byte[] tmpbuf = new byte[buflen];

    long skipped = 0L;
    while (n > 0L)
      {
	int numread = read(tmpbuf, 0, buflen);
	if (numread <= 0)
	  break;
	n -= numread;
	skipped += numread;
	buflen = (int) Math.min(n, 2048);
      }

    return skipped;
 }

  public boolean markSupported()
  {
    return false;
  }

  public void mark(int readLimit)
  {
  }

  public void reset() throws IOException
  {
    throw new IOException("reset not supported");
  }
}
