OSDN Git Service

PR libgcj/14446:
[pf3gnuchains/gcc-fork.git] / libjava / java / util / zip / InflaterInputStream.java
index b045349..3676a2c 100644 (file)
@@ -1,5 +1,6 @@
 /* InflaterInputStream.java - Input stream filter for decompressing
-   Copyright (C) 1999, 2000, 2002, 2003 Free Software Foundation, Inc.
+   Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004
+   Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
 
@@ -42,67 +43,159 @@ import java.io.InputStream;
 import java.io.IOException;
 
 /**
+ * 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
- * @date May 17, 1999
+ * @since 1.1
  */
-
-/* Written using on-line Java Platform 1.2 API Specification
- * and JCL book.
- * Believed complete and correct.
- */
-
 public class InflaterInputStream extends FilterInputStream
 {
-  protected void fill () throws IOException
+  /**
+   * 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) 
   {
-    len = in.read(buf, 0, buf.length);
-    if (len != -1)
-      inf.setInput(buf, 0, len);
+    this(in, new Inflater(), 4096);
   }
 
-  public InflaterInputStream (InputStream in)
+  /**
+   * 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, new Inflater (), 512);
+    this(in, inf, 4096);
   }
 
-  public InflaterInputStream (InputStream in, Inflater infl)
+  /**
+   * 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) 
   {
-    this (in, infl, 512);
+    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;
   }
 
-  public InflaterInputStream (InputStream in, Inflater infl, int bufsize)
+  /**
+   * Closes the input stream
+   */
+  public synchronized void close() throws IOException
   {
-    super (in);
-    this.inf = infl;
-    this.buf = new byte[bufsize];
+    inf = null;
+    super.close();
   }
 
-  public int read () throws IOException
+  /**
+   * Fills the buffer with more data to decompress.
+   */
+  protected void fill() throws IOException
   {
-    byte[] buf = new byte[1];
-    int r = read (buf, 0, 1);
-    if (r != -1)
-      r = buf[0] & 0xff;
-    return r;
+    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);
   }
 
-  public int read (byte[] buf, int off, int len) throws IOException
+  /**
+   * 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");
+      throw new IOException("stream closed");
     if (len == 0)
       return 0;
     if (inf.finished())
       return -1;
 
     int count = 0;
-    while (count == 0)
+    for (;;)
       {
        if (inf.needsInput())
-         fill ();
+         fill();
+       
        try
          {
-           count = inf.inflate(buf, off, len); 
+           count = inf.inflate(b, off, len);
            if (count == 0)
              {
                if (this.len == -1)
@@ -111,63 +204,48 @@ public class InflaterInputStream extends FilterInputStream
                    return -1;
                  }
                if (inf.needsDictionary())
-                 throw new ZipException ("Inflater needs Dictionary");
+                 throw new ZipException("Inflater needs Dictionary");
              }
-         }
-       catch (DataFormatException dfe)
+         } 
+       catch (DataFormatException dfe) 
          {
-           throw new ZipException (dfe.getMessage());
+           throw new ZipException(dfe.getMessage());
          }
-      }
-    return count;
-  }
 
-  public void close () throws IOException
-  {
-    inf = null;
-    super.close ();
-  }
-
-  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;
+       if (count > 0)
+         return count;
+      }
   }
 
-  public long skip (long n) throws IOException
+  /**
+   * 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");
+      throw new IOException("stream closed");
+    if (n < 0)
+      throw new IllegalArgumentException();
 
     if (n == 0)
       return 0;
 
-    int min = (int) Math.min(n, 1024);
-    byte[] buf = new byte[min];
+    int buflen = (int) Math.min(n, 2048);
+    byte[] tmpbuf = new byte[buflen];
 
-    long s = 0;
-    while (n > 0)
+    long skipped = 0L;
+    while (n > 0L)
       {
-       int r = read (buf, 0, min);
-       if (r == -1)
+       int numread = read(tmpbuf, 0, buflen);
+       if (numread <= 0)
          break;
-       n -= r;
-       s += r;
-       min = (int) Math.min(n, 1024);
+       n -= numread;
+       skipped += numread;
+       buflen = (int) Math.min(n, 2048);
       }
 
-    return s;
-  }
-
-  // Buffer for delivering uncompressed data to inflater.
-  protected byte[] buf;
-
-  // Inflater used to decompress data.
-  protected Inflater inf;
-
-  // Number of read bytes in buf.
-  protected int len;
+    return skipped;
+ }
 }