* java/util/zip/ZipOutputStream.java (level): Initial value is
authortromey <tromey@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 18 May 1999 15:33:03 +0000 (15:33 +0000)
committertromey <tromey@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 18 May 1999 15:33:03 +0000 (15:33 +0000)
Deflater.DEFAULT_COMPRESSION.
(close): New method.
(closeEntry): Likewise.
(finish): Likewise.
(put_version): Likewise.
(write_entry): Likewise.
(put2, put4): Now return `int'.
(comment): Default to empty string.
(bytes_written): New instance variable.
(chain): Likewise.
* java/util/zip/ZipEntry.java (setComment): Limit length of
comment string.
(setCrc): Check CRC validity.
(setExtra): Check argument validity.
(setMethod): Likewise.
(setSize): Likewise.
(ZipEntry): Likewise.
* include/javaprims.h: Updated namespace declarations.
* Makefile.in: Rebuilt.
* Makefile.am (ordinary_java_source_files): Mention new files.
(nat_source_files): Likewise.
* java/util/zip/ZipFile.java (readu2): Throw ZipException, not
EOFException.
(read4): Likewise.
(getInputStream): Handle compressed entries.
* java/util/zip/GZIPOutputStream.java: New file.
* java/util/zip/GZIPInputStream.java: New file.
* java/util/zip/DataFormatException.java: New file.
* java/util/zip/CheckedInputStream.java: New file.
* java/util/zip/CheckedOutputStream.java: New file.
* java/util/zip/InflaterInputStream.java: Implemented.
* java/util/zip/natInflater.cc: New file.
* java/util/zip/Deflater.java: Implemented.
* java/util/zip/natDeflater.cc: New file.
* java/util/zip/DeflaterOutputStream.java: Implemented.
* java/util/zip/ZipInputStream.java (closeZipEntry): Throw
ZipException, not IOException.
* java/util/zip/ZipFile.java (readDirectory): Throw ZipException,
not IOException.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@26996 138bc75d-0d04-0410-961f-82ee72b054a4

19 files changed:
libjava/ChangeLog
libjava/Makefile.am
libjava/Makefile.in
libjava/include/javaprims.h
libjava/java/util/zip/CheckedInputStream.java [new file with mode: 0644]
libjava/java/util/zip/CheckedOutputStream.java [new file with mode: 0644]
libjava/java/util/zip/DataFormatException.java [new file with mode: 0644]
libjava/java/util/zip/Deflater.java
libjava/java/util/zip/DeflaterOutputStream.java
libjava/java/util/zip/GZIPInputStream.java [new file with mode: 0644]
libjava/java/util/zip/GZIPOutputStream.java [new file with mode: 0644]
libjava/java/util/zip/Inflater.java [new file with mode: 0644]
libjava/java/util/zip/InflaterInputStream.java
libjava/java/util/zip/ZipEntry.java
libjava/java/util/zip/ZipFile.java
libjava/java/util/zip/ZipInputStream.java
libjava/java/util/zip/ZipOutputStream.java
libjava/java/util/zip/natDeflater.cc [new file with mode: 0644]
libjava/java/util/zip/natInflater.cc [new file with mode: 0644]

index b554fb5..1e5b422 100644 (file)
@@ -1,3 +1,47 @@
+1999-05-18  Tom Tromey  <tromey@cygnus.com>
+
+       * java/util/zip/ZipOutputStream.java (level): Initial value is
+       Deflater.DEFAULT_COMPRESSION.
+       (close): New method.
+       (closeEntry): Likewise.
+       (finish): Likewise.
+       (put_version): Likewise.
+       (write_entry): Likewise.
+       (put2, put4): Now return `int'.
+       (comment): Default to empty string.
+       (bytes_written): New instance variable.
+       (chain): Likewise.
+       * java/util/zip/ZipEntry.java (setComment): Limit length of
+       comment string.
+       (setCrc): Check CRC validity.
+       (setExtra): Check argument validity.
+       (setMethod): Likewise.
+       (setSize): Likewise.
+       (ZipEntry): Likewise.
+       * include/javaprims.h: Updated namespace declarations.
+       * Makefile.in: Rebuilt.
+       * Makefile.am (ordinary_java_source_files): Mention new files.
+       (nat_source_files): Likewise.
+       * java/util/zip/ZipFile.java (readu2): Throw ZipException, not
+       EOFException.
+       (read4): Likewise.
+       (getInputStream): Handle compressed entries.
+       * java/util/zip/GZIPOutputStream.java: New file.
+       * java/util/zip/GZIPInputStream.java: New file.
+       * java/util/zip/DataFormatException.java: New file.
+       * java/util/zip/CheckedInputStream.java: New file.
+       * java/util/zip/CheckedOutputStream.java: New file.
+       * java/util/zip/InflaterInputStream.java: Implemented.
+       * java/util/zip/natInflater.cc: New file.
+       * java/util/zip/Deflater.java: Implemented.
+       * java/util/zip/natDeflater.cc: New file.
+       * java/util/zip/DeflaterOutputStream.java: Implemented.
+
+       * java/util/zip/ZipInputStream.java (closeZipEntry): Throw
+       ZipException, not IOException.
+       * java/util/zip/ZipFile.java (readDirectory): Throw ZipException,
+       not IOException.
+
 1999-05-17  Tom Tromey  <tromey@cygnus.com>
 
        * java/lang/natSystem.cc (init_properties): URL now points to
index 82665dd..48bf574 100644 (file)
@@ -654,9 +654,15 @@ java/util/TooManyListenersException.java \
 java/util/Vector.java \
 java/util/zip/Adler32.java \
 java/util/zip/CRC32.java \
+java/util/zip/CheckedInputStream.java \
+java/util/zip/CheckedOutputStream.java \
 java/util/zip/Checksum.java \
+java/util/zip/DataFormatException.java \
 java/util/zip/Deflater.java \
 java/util/zip/DeflaterOutputStream.java        \
+java/util/zip/GZIPInputStream.java \
+java/util/zip/GZIPOutputStream.java \
+java/util/zip/Inflater.java \
 java/util/zip/InflaterInputStream.java \
 java/util/zip/ZipConstants.java        \
 java/util/zip/ZipEntry.java \
@@ -715,7 +721,9 @@ java/net/natInetAddress.cc \
 java/net/natPlainSocketImpl.cc \
 java/text/natCollator.cc \
 java/util/natDate.cc \
-java/util/natGregorianCalendar.cc
+java/util/natGregorianCalendar.cc \
+java/util/zip/natDeflater.cc \
+java/util/zip/natInflater.cc
 
 ## ################################################################
 
index e45a5a9..8550997 100644 (file)
@@ -203,7 +203,7 @@ jv_convert_LINK = $(LIBTOOL) --mode=link $(GCJ) $(JC1FLAGS) $(LDFLAGS) \
        -o jv-convert
 
 jv_convert_LDADD = $(convert_source_files:.java=.lo) libgcj.la \
-       $(GCLIBS) $(THREADLIBS) $(ZLIBS)
+       $(GCLIBS) $(THREADLIBS) $(ZLIBS) -L$(here)/.libs
 
 jv_convert_DEPENDENCIES = $(convert_source_files:.java=.lo) \
        $(GCDEPS) $(THREADDEPS) $(ZDEPS) libgcj.la libgcj.spec
@@ -505,9 +505,15 @@ java/util/TooManyListenersException.java \
 java/util/Vector.java \
 java/util/zip/Adler32.java \
 java/util/zip/CRC32.java \
+java/util/zip/CheckedInputStream.java \
+java/util/zip/CheckedOutputStream.java \
 java/util/zip/Checksum.java \
+java/util/zip/DataFormatException.java \
 java/util/zip/Deflater.java \
 java/util/zip/DeflaterOutputStream.java        \
+java/util/zip/GZIPInputStream.java \
+java/util/zip/GZIPOutputStream.java \
+java/util/zip/Inflater.java \
 java/util/zip/InflaterInputStream.java \
 java/util/zip/ZipConstants.java        \
 java/util/zip/ZipEntry.java \
@@ -566,7 +572,9 @@ java/net/natInetAddress.cc \
 java/net/natPlainSocketImpl.cc \
 java/text/natCollator.cc \
 java/util/natDate.cc \
-java/util/natGregorianCalendar.cc
+java/util/natGregorianCalendar.cc \
+java/util/zip/natDeflater.cc \
+java/util/zip/natInflater.cc
 
 
 # Work around what appears to be a GNU make bug handling MAKEFLAGS
@@ -832,9 +840,14 @@ DEP_FILES =  .deps/$(srcdir)/$(CONVERT_DIR)/gen-from-JIS.P \
 .deps/java/util/Stack.P .deps/java/util/StringTokenizer.P \
 .deps/java/util/TimeZone.P .deps/java/util/TooManyListenersException.P \
 .deps/java/util/Vector.P .deps/java/util/zip/Adler32.P \
-.deps/java/util/zip/CRC32.P .deps/java/util/zip/Checksum.P \
+.deps/java/util/zip/CRC32.P .deps/java/util/zip/CheckedInputStream.P \
+.deps/java/util/zip/CheckedOutputStream.P \
+.deps/java/util/zip/Checksum.P \
+.deps/java/util/zip/DataFormatException.P \
 .deps/java/util/zip/Deflater.P \
 .deps/java/util/zip/DeflaterOutputStream.P \
+.deps/java/util/zip/GZIPInputStream.P \
+.deps/java/util/zip/GZIPOutputStream.P .deps/java/util/zip/Inflater.P \
 .deps/java/util/zip/InflaterInputStream.P \
 .deps/java/util/zip/ZipConstants.P .deps/java/util/zip/ZipEntry.P \
 .deps/java/util/zip/ZipException.P .deps/java/util/zip/ZipFile.P \
index 2f815d2..98781ad 100644 (file)
@@ -211,9 +211,15 @@ extern "Java"
       {
         class Adler32;
         class CRC32;
+        class CheckedInputStream;
+        class CheckedOutputStream;
         class Checksum;
+        class DataFormatException;
         class Deflater;
         class DeflaterOutputStream;
+        class GZIPInputStream;
+        class GZIPOutputStream;
+        class Inflater;
         class InflaterInputStream;
         class ZipConstants;
         class ZipEntry;
diff --git a/libjava/java/util/zip/CheckedInputStream.java b/libjava/java/util/zip/CheckedInputStream.java
new file mode 100644 (file)
index 0000000..a6a9058
--- /dev/null
@@ -0,0 +1,80 @@
+// CheckedInputStream.java - Compute checksum of data being read.
+
+/* Copyright (C) 1999  Cygnus Solutions
+
+   This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
+details.  */
+
+package java.util.zip;
+
+import java.io.FilterInputStream;
+import java.io.InputStream;
+import java.io.IOException;
+
+/**
+ * @author Tom Tromey
+ * @date May 17, 1999
+ */
+
+/* Written using on-line Java Platform 1.2 API Specification
+ * and JCL book.
+ * Believed complete and correct.
+ */
+
+public class CheckedInputStream extends FilterInputStream
+{
+  public CheckedInputStream (InputStream in, Checksum sum)
+  {
+    super (in);
+    this.sum = sum;
+  }
+
+  public Checksum getChecksum ()
+  {
+    return sum;
+  }
+
+  public int read () throws IOException
+  {
+    int x = in.read();
+    if (x != -1)
+      sum.update(x);
+    return x;
+  }
+
+  public int read (byte[] buf, int off, int len) throws IOException
+  {
+    int r = in.read(buf, off, len);
+    if (r != -1)
+      sum.update(buf, off, r);
+    return r;
+  }
+
+  public long skip (long n) throws IOException
+  {
+    if (n == 0)
+      return 0;
+
+    int min = (int) Math.min(n, 1024);
+    byte[] buf = new byte[min];
+
+    long s = 0;
+    while (n > 0)
+      {
+       int r = in.read(buf, 0, min);
+       if (r == -1)
+         break;
+       n -= r;
+       s += r;
+       sum.update(buf, 0, r);
+      }
+
+    return s;
+  }
+
+  // The checksum object.
+  private Checksum sum;
+}
diff --git a/libjava/java/util/zip/CheckedOutputStream.java b/libjava/java/util/zip/CheckedOutputStream.java
new file mode 100644 (file)
index 0000000..30dbc73
--- /dev/null
@@ -0,0 +1,54 @@
+// CheckedOutputStream.java - Compute checksum of data being written.
+
+/* Copyright (C) 1999  Cygnus Solutions
+
+   This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
+details.  */
+
+package java.util.zip;
+
+import java.io.FilterOutputStream;
+import java.io.OutputStream;
+import java.io.IOException;
+
+/**
+ * @author Tom Tromey
+ * @date May 17, 1999
+ */
+
+/* Written using on-line Java Platform 1.2 API Specification
+ * and JCL book.
+ * Believed complete and correct.
+ */
+
+public class CheckedOutputStream extends FilterOutputStream
+{
+  public CheckedOutputStream (OutputStream out, Checksum cksum)
+  {
+    super (out);
+    this.sum = cksum;
+  }
+
+  public Checksum getChecksum ()
+  {
+    return sum;
+  }
+
+  public void write (int bval) throws IOException
+  {
+    out.write(bval);
+    sum.update(bval);
+  }
+
+  public void write (byte[] buf, int off, int len) throws IOException
+  {
+    out.write(buf, off, len);
+    sum.update(buf, off, len);
+  }
+
+  // The checksum object.
+  private Checksum sum;
+}
diff --git a/libjava/java/util/zip/DataFormatException.java b/libjava/java/util/zip/DataFormatException.java
new file mode 100644 (file)
index 0000000..258f47f
--- /dev/null
@@ -0,0 +1,33 @@
+// DataFormatException.java
+
+/* Copyright (C) 1999  Cygnus Solutions
+
+   This file is part of libjava.
+
+This software is copyrighted work licensed under the terms of the
+Libjava License.  Please consult the file "LIBJAVA_LICENSE" for
+details.  */
+
+package java.util.zip;
+
+/**
+ * @author Tom Tromey
+ * @date May 17, 1999
+ */
+
+/* Written using on-line Java Platform 1.2 API Specification.
+ * Believed complete and correct.
+ */
+
+public class DataFormatException extends java.io.IOException
+{
+  public DataFormatException ()
+  {
+    super();
+  }
+
+  public DataFormatException (String msg)
+  {
+    super(msg);
+  }
+}
index 81312e2..70855c5 100644 (file)
@@ -1,3 +1,5 @@
+// Deflater.java - Compress a data stream.
+
 /* Copyright (C) 1999  Cygnus Solutions
 
    This file is part of libgcj.
@@ -8,6 +10,123 @@ details.  */
 
 package java.util.zip;
 
+import gnu.gcj.RawData;
+
+/**
+ * @author Tom Tromey
+ * @date May 17, 1999
+ */
+
+/* Written using on-line Java Platform 1.2 API Specification
+ * and JCL book.
+ * Believed complete and correct.
+ */
+
 public class Deflater
 {
+  public static final int BEST_COMPRESSION = 9;
+  public static final int BEST_SPEED = 1;
+  public static final int DEFAULT_COMPRESSION = -1;
+  public static final int NO_COMPRESSION = 0;
+
+  public static final int DEFAULT_STRATEGY = 0;
+  public static final int FILTERED = 1;
+  public static final int HUFFMAN_ONLY = 2;
+
+  public static final int DEFLATED = 8;
+
+  public int deflate (byte[] buf)
+  {
+    return deflate (buf, 0, buf.length);
+  }
+
+  public native int deflate (byte[] buf, int off, int len);
+  public native void init (int level, boolean noHeader);
+  public native void update ();
+
+  public Deflater ()
+  {
+    this (DEFAULT_COMPRESSION, false);
+  }
+
+  public Deflater (int lvl)
+  {
+    this (lvl, false);
+  }
+
+  public Deflater (int lvl, boolean noHeader)
+  {
+    this.strategy = DEFAULT_STRATEGY;
+    init (lvl, noHeader);
+    setLevel (lvl);
+  }
+
+  public native void end ();
+
+  public void finalize ()
+  {
+    end ();
+  }
+
+  public native void finish ();
+
+  public synchronized boolean finished ()
+  {
+    return is_finished;
+  }
+
+  public native int getAdler ();
+  public native int getTotalIn ();
+  public native int getTotalOut ();
+  public native boolean needsInput ();
+  public native void reset ();
+
+  public void setDictionary (byte[] buf)
+  {
+    setDictionary (buf, 0, buf.length);
+  }
+
+  public native void setDictionary (byte[] buf, int off, int len);
+
+  public void setInput (byte[] buf)
+  {
+    setInput (buf, 0, buf.length);
+  }
+
+  public native void setInput (byte[] buf, int off, int len);
+
+  public synchronized void setLevel (int lvl)
+  {
+    if (lvl != -1 && (lvl < 0 || lvl > 9))
+      throw new IllegalArgumentException ();
+    level = (lvl == -1) ? 6 : lvl;
+    update ();
+  }
+
+  public synchronized void setStrategy (int stgy)
+  {
+    if (stgy != DEFAULT_STRATEGY && stgy != FILTERED
+       && stgy != HUFFMAN_ONLY)
+      throw new IllegalArgumentException ();
+    strategy = stgy;
+    update ();
+  }
+
+  // Compression level.
+  private int level;
+
+  // Compression strategy.
+  private int strategy;
+
+  // The zlib stream.
+  private RawData zstream;
+
+  // True if finished.
+  private boolean is_finished;
+
+  // Total number of bytes made available at last setInput.
+  private int last_input_count;
+
+  // `Flush' flag to pass to next call to deflate.
+  private int flush_flag;
 }
index 4f0b8b4..ce5ae23 100644 (file)
@@ -1,3 +1,5 @@
+// DeflaterOutputStream.java - Output filter for compressing.
+
 /* Copyright (C) 1999  Cygnus Solutions
 
    This file is part of libgcj.
@@ -7,40 +9,79 @@ Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
 details.  */
 
 package java.util.zip;
-import java.io.*;
 
-/** JUST AN INCOMPLETE STUB! */
+import java.io.FilterOutputStream;
+import java.io.OutputStream;
+import java.io.IOException;
+
+/**
+ * @author Tom Tromey
+ * @date May 17, 1999
+ */
+
+/* Written using on-line Java Platform 1.2 API Specification
+ * and JCL book.
+ * Believed complete and correct.
+ */
 
 public class DeflaterOutputStream extends FilterOutputStream
 {
-  protected byte[] buf;
+  public void close () throws IOException
+  {
+    finish ();
+    out.close();
+  }
 
-  protected Deflater def;
+  protected void deflate () throws IOException
+  {
+    while (true)
+      {
+       int len = def.deflate(buf, 0, buf.length);
+       if (len == 0 || len == -1)
+         break;
+       out.write(buf, 0, len);
+      }
+  }
 
-  public DeflaterOutputStream(OutputStream out)
+  public DeflaterOutputStream (OutputStream out)
   {
-    this(out, null, 512);
+    this (out, new Deflater (), 512);
   }
 
-  public DeflaterOutputStream(OutputStream out, Deflater defl)
+  public DeflaterOutputStream (OutputStream out, Deflater defl)
   {
-    this(out, defl, 512);
+    this (out, defl, 512);
   }
 
   public DeflaterOutputStream(OutputStream out, Deflater defl, int bufsize)
   {
-    super(out);
+    super (out);
     buf = new byte[bufsize];
     def = defl;
   }
 
   public void finish () throws IOException
   {
+    def.finish();
+    deflate ();
   }
 
-  public void close () throws IOException
+  public void write (int bval) throws IOException
   {
-    finish();
-    out.close();
+    byte[] b = new byte[1];
+    b[0] = (byte) bval;
+    write (b, 0, 1);
+  }
+
+  public void write (byte[] buf, int off, int len) throws IOException
+  {
+    def.setInput (buf, off, len);
+    deflate ();
   }
+
+  // The retrieval buffer.
+  protected byte[] buf;
+
+  // Deflater used to compress data.
+  protected Deflater def;
 }
diff --git a/libjava/java/util/zip/GZIPInputStream.java b/libjava/java/util/zip/GZIPInputStream.java
new file mode 100644 (file)
index 0000000..109ee82
--- /dev/null
@@ -0,0 +1,154 @@
+// GZIPInputStream.java - Input tiler for reading gzip file.
+
+/* Copyright (C) 1999  Cygnus Solutions
+
+   This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
+details.  */
+
+package java.util.zip;
+
+import java.io.InputStream;
+import java.io.IOException;
+
+/**
+ * @author Tom Tromey
+ * @date May 17, 1999
+ */
+
+/* Written using on-line Java Platform 1.2 API Specification
+ * and JCL book.
+ * Believed complete and correct.
+ */
+
+public class GZIPInputStream extends InflaterInputStream
+{
+  public static final int GZIP_MAGIC = 0x8b1f;
+
+  public void close () throws IOException
+  {
+    // Nothing to do here.
+    super.close();
+  }
+
+  public GZIPInputStream (InputStream istream) throws IOException
+  {
+    this (istream, 512);
+  }
+
+  private final int eof_read () throws IOException
+  {
+    int r = in.read();
+    if (r == -1)
+      throw new ZipException ("gzip header corrupted");
+    return r & 0xff;
+  }
+
+  public GZIPInputStream (InputStream istream, int readsize)
+    throws IOException
+  {
+    super (istream, new Inflater (true), readsize);
+
+    // NOTE: header reading code taken from zlib's gzio.c.
+
+    // Read the magic number.
+    int magic = eof_read () | (eof_read () << 8);
+    if (magic != GZIP_MAGIC)
+      throw new ZipException ("gzip header corrupted");
+
+    int method = eof_read ();
+    int flags = eof_read ();
+    // Test from zlib.
+    if (method != Z_DEFLATED || (flags & RESERVED) != 0)
+      throw new ZipException ("gzip header corrupted");
+
+    // Discard time, xflags, OS code.
+    for (int i = 0; i < 6; ++i)
+      eof_read ();
+
+    // Skip the extra field.
+    if ((flags & EXTRA_FIELD) != 0)
+      {
+       int len = eof_read () | (eof_read () << 8);
+       while (len-- != 0)
+         eof_read ();
+      }
+
+    if ((flags & ORIG_NAME) != 0)
+      {
+       while (true)
+         {
+           int c = eof_read ();
+           if (c == 0)
+             break;
+         }
+      }
+
+    if ((flags & COMMENT) != 0)
+      {
+       while (true)
+         {
+           int c = eof_read ();
+           if (c == 0)
+             break;
+         }
+      }
+
+    if ((flags & HEAD_CRC) != 0)
+      {
+       // FIXME: consider checking CRC of the header.
+       eof_read ();
+       eof_read ();
+      }
+
+    crc = new CRC32 ();
+  }
+
+  public int read (byte[] buf, int off, int len) throws IOException
+  {
+    if (eos)
+      return -1;
+    int r = super.read(buf, off, len);
+    if (r == -1)
+      {
+       eos = true;
+       int header_crc = read4 ();
+       if (crc.getValue() != header_crc)
+         throw new ZipException ("corrupted gzip file");
+       // Read final `ISIZE' field.
+       // FIXME: should we check this length?
+       read4 ();
+       return -1;
+      }
+    crc.update(buf, off, r);
+    return r;
+  }
+
+  private final int read4 () throws IOException
+  {
+    int byte0 = in.read();
+    int byte1 = in.read();
+    int byte2 = in.read();
+    int byte3 = in.read();
+    if (byte3 < 0)
+      throw new ZipException (".zip archive ended prematurely");
+    return ((byte3 & 0xFF) << 24) + ((byte2 & 0xFF) << 16)
+      + ((byte1 & 0xFF) << 8) + (byte0 & 0xFF);
+  }
+
+  // Checksum used by this input stream.
+  protected CRC32 crc;
+
+  // Indicates whether end-of-stream has been reached.
+  protected boolean eos;
+
+  // Some constants from zlib.
+  static final int Z_DEFLATED = 8;
+  static final int HEAD_CRC    = 0x02;
+  static final int EXTRA_FIELD = 0x04;
+  static final int ORIG_NAME   = 0x08;
+  static final int COMMENT     = 0x10;
+  static final int RESERVED    = 0xe0;
+}
diff --git a/libjava/java/util/zip/GZIPOutputStream.java b/libjava/java/util/zip/GZIPOutputStream.java
new file mode 100644 (file)
index 0000000..1d93fd1
--- /dev/null
@@ -0,0 +1,88 @@
+// GZIPOutputStream.java - Create a file in gzip format.
+
+/* Copyright (C) 1999  Cygnus Solutions
+
+   This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
+details.  */
+
+package java.util.zip;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+/**
+ * @author Tom Tromey
+ * @date May 17, 1999
+ */
+
+/* Written using on-line Java Platform 1.2 API Specification
+ * and JCL book.
+ * Believed complete and correct.
+ */
+
+public class GZIPOutputStream extends DeflaterOutputStream
+{
+  public void close () throws IOException
+  {
+    finish ();
+    out.close ();
+  }
+
+  public void finish () throws IOException
+  {
+    super.finish();
+    put4 ((int) crc.getValue());
+    put4 (def.getTotalIn());
+  }
+
+  public GZIPOutputStream (OutputStream out) throws IOException
+  {
+    this (out, 512);
+  }
+
+  public GZIPOutputStream (OutputStream out, int readsize) throws IOException
+  {
+    super (out, new Deflater (Deflater.DEFAULT_COMPRESSION, true), readsize);
+
+    put2 (GZIPInputStream.GZIP_MAGIC);
+    out.write (GZIPInputStream.Z_DEFLATED);
+    // No flags for now.
+    out.write (0);
+    // No time either.
+    put2 (0);
+    put2 (0);
+    // No xflags either.
+    out.write (0);
+    // FIXME: unknown OS.
+    out.write (255);
+
+    crc = new CRC32 ();
+  }
+
+  public synchronized void write (byte[] buf, int off, int len)
+    throws IOException
+  {
+    super.write(buf, off, len);
+    crc.update(buf, off, len);
+  }
+
+  private final void put2 (int i) throws IOException
+  {
+    out.write (i);
+    out.write (i >> 8);
+  }
+
+  private final void put4 (int i) throws IOException
+  {
+    out.write (i);
+    out.write (i >> 8);
+    out.write (i >> 16);
+    out.write (i >> 24);
+  }
+
+  // Checksum used by this stream.
+  protected CRC32 crc;
+}
diff --git a/libjava/java/util/zip/Inflater.java b/libjava/java/util/zip/Inflater.java
new file mode 100644 (file)
index 0000000..724b5b4
--- /dev/null
@@ -0,0 +1,101 @@
+// Inflater.java - Decompress a data stream.
+
+/* Copyright (C) 1999  Cygnus Solutions
+
+   This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
+details.  */
+
+package java.util.zip;
+
+import gnu.gcj.RawData;
+
+/**
+ * @author Tom Tromey
+ * @date May 17, 1999
+ */
+
+/* Written using on-line Java Platform 1.2 API Specification
+ * and JCL book.
+ * Believed complete and correct.
+ */
+
+public class Inflater
+{
+  public native void end ();
+
+  protected void finalize ()
+  {
+    end ();
+  }
+
+  public synchronized boolean finished ()
+  {
+    return is_finished;
+  }
+
+  public native int getAdler ();
+  public native int getRemaining ();
+  public native int getTotalIn ();
+  public native int getTotalOut ();
+
+  public int inflate (byte[] buf) throws DataFormatException
+  {
+    return inflate (buf, 0, buf.length);
+  }
+
+  public native int inflate (byte[] buf, int off, int len)
+    throws DataFormatException;
+
+  private native void init (boolean noHeader);
+
+  public Inflater ()
+  {
+    this (false);
+  }
+
+  public Inflater (boolean noHeader)
+  {
+    init (noHeader);
+  }
+
+  public synchronized boolean needsDictionary ()
+  {
+    return dict_needed;
+  }
+
+  public synchronized boolean needsInput ()
+  {
+    return getRemaining () == 0;
+  }
+
+  public native void reset ();
+
+  public void setDictionary (byte[] buf)
+  {
+    setDictionary (buf, 0, buf.length);
+  }
+
+  public native void setDictionary (byte[] buf, int off, int len);
+
+  public void setInput (byte[] buf)
+  {
+    setInput (buf, 0, buf.length);
+  }
+
+  public native void setInput (byte[] buf, int off, int len);
+
+  // The zlib stream.
+  private RawData zstream;
+
+  // True if finished.
+  private boolean is_finished;
+
+  // True if dictionary needed.
+  private boolean dict_needed;
+
+  // Total number of bytes made available at last setInput.
+  private int last_input_count;
+}
index 1b6290a..7ee4455 100644 (file)
@@ -1,3 +1,5 @@
+// InflaterInputStream.java - Input stream filter for decompressing.
+
 /* Copyright (C) 1999  Cygnus Solutions
 
    This file is part of libgcj.
@@ -7,14 +9,94 @@ Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
 details.  */
 
 package java.util.zip;
-import java.io.*;
 
-/** Placefolder - very incomplete. */
+import java.io.FilterInputStream;
+import java.io.InputStream;
+import java.io.IOException;
+
+/**
+ * @author Tom Tromey
+ * @date May 17, 1999
+ */
+
+/* Written using on-line Java Platform 1.2 API Specification
+ * and JCL book.
+ * Believed complete and correct.
+ */
 
 public class InflaterInputStream extends FilterInputStream
 {
-  public InflaterInputStream(InputStream in)
+  protected void fill () throws IOException
+  {
+    len = in.read(buf, 0, buf.length);
+    if (len != -1)
+      inf.setInput(buf, 0, len);
+  }
+
+  public InflaterInputStream (InputStream in)
+  {
+    this (in, new Inflater (), 512);
+  }
+
+  public InflaterInputStream (InputStream in, Inflater infl)
   {
-    super(in);
+    this (in, infl, 512);
   }
+
+  public InflaterInputStream (InputStream in, Inflater infl, int bufsize)
+  {
+    super (in);
+    this.inf = infl;
+    this.buf = new byte[bufsize];
+  }
+
+  public int read () throws IOException
+  {
+    byte[] buf = new byte[1];
+    int r = read (buf, 0, 1);
+    if (r != -1)
+      r = buf[0] & 0xff;
+    return r;
+  }
+
+  public int read (byte[] buf, int off, int len) throws IOException
+  {
+    if (inf.finished())
+      return -1;
+    if (inf.needsInput())
+      fill ();
+    if (inf.needsDictionary())
+      return -1;
+    return inf.inflate(buf, off, len);
+  }
+
+  public long skip (long n) throws IOException
+  {
+    if (n == 0)
+      return 0;
+
+    int min = (int) Math.min(n, 1024);
+    byte[] buf = new byte[min];
+
+    long s = 0;
+    while (n > 0)
+      {
+       int r = read (buf, 0, min);
+       if (r == -1)
+         break;
+       n -= r;
+       s += r;
+      }
+
+    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;
 }
index 9eb34ba..7035ab5 100644 (file)
@@ -39,6 +39,10 @@ public class ZipEntry
 
   public ZipEntry (String name)
   {
+    if (name == null)
+      throw new NullPointerException ();
+    if (name.length() > 65535)
+      throw new IllegalArgumentException ();
     this.name = name;
   }
 
@@ -69,17 +73,45 @@ public class ZipEntry
     return false;
   }
 
-  public void setComment (String comment) { this.comment = comment; }
+  public void setComment (String comment)
+  {
+    if (comment != null && comment.length() > 65535)
+      throw new IllegalArgumentException ();
+    this.comment = comment;
+  }
 
-  public void setCrc (long crc) { this.crc = crc; }
+  public void setCrc (long crc) 
+  {
+    if (crc < 0 || crc > 0xffffffff)
+      throw new IllegalArgumentException ();
+    this.crc = crc;
+  }
 
-  public void setExtra (byte[] extra) { this.extra = extra; }
+  public void setExtra (byte[] extra)
+  {
+    if (extra != null && extra.length > 65535)
+      throw new IllegalArgumentException ();
+    this.extra = extra;
+  }
 
-  public void setMethod(int method) { this.method = method; }
+  public void setMethod (int method)
+  {
+    if (method != DEFLATED && method != STORED)
+      throw new IllegalArgumentException ();
+    this.method = method;
+  }
 
-  public void setSize (long size) { this.size = size; }
+  public void setSize (long size)
+  {
+    if (size < 0 || size > 0xffffffff)
+      throw new IllegalArgumentException ();
+    this.size = size;
+  }
 
-  public void setTime (long time) { this.time = time; }
+  public void setTime (long time)
+  {
+    this.time = time;
+  }
 
   private final static short[] daysToMonthStart = {
     //Jan Feb Mar    Apr      May         Jun         Jul
index 9085ec9..bfb077d 100644 (file)
@@ -1,3 +1,5 @@
+// ZipFile.java - Read contents of a ZIP file.
+
 /* Copyright (C) 1999  Cygnus Solutions
 
    This file is part of libgcj.
@@ -9,16 +11,13 @@ details.  */
 package java.util.zip;
 import java.io.*;
 
-/** UNFINISHED, but can read non-comrepssed .zip archives. */
+/* Written using on-line Java Platform 1.2 API Specification
+ * and JCL book.
+ * Believed complete and correct.
+ */
 
 public class ZipFile implements ZipConstants
 {
-
-  ZipEntry entries;
-  int numEntries;
-  RandomAccessFile file;
-  String name;
-
   public ZipFile (String fname) throws IOException
   {
     file = new RandomAccessFile(fname, "r");
@@ -35,7 +34,7 @@ public class ZipFile implements ZipConstants
   {
     long size = file.length ();
     if (size < ZipConstants.END_CENTRAL_DIR_SIZE)
-      throw new IOException ("zipfile too short");
+      throw new ZipException ("zipfile too short");
     // We do not handle a "zipfile comment", which the appnote says can
     // be at the end of a .zip file.  We could handle this by seeking
     // to the beginning and reading forwards.
@@ -44,7 +43,7 @@ public class ZipFile implements ZipConstants
        || file.read() != 'K'
        || file.read() != '\005'
        || file.read() != '\006')
-      throw new IOException("not a valid zipfile");
+      throw new ZipException("not a valid zipfile");
     file.skipBytes(6);
     numEntries = readu2();
     int dir_size = read4 ();  // Read "size of the central directory".
@@ -103,7 +102,6 @@ public class ZipFile implements ZipConstants
 
   public void close() throws IOException
   {
-    //  FIXME - check this
     file.close();
     entries = null;
     numEntries = 0;
@@ -121,14 +119,17 @@ public class ZipFile implements ZipConstants
 
   public InputStream getInputStream(ZipEntry ze)  throws IOException
   {
-    // FIXME - does not handle compression!
     byte[] buffer = new byte[(int) ze.getSize()];
     int data_offset = ZipConstants.LOCAL_FILE_HEADER_SIZE + name.length();
     if (ze.extra != null)
       data_offset += ze.extra.length;
     file.seek(ze.relativeOffset + data_offset);
     file.readFully(buffer);
-    return new ByteArrayInputStream(buffer);
+
+    InputStream is = new ByteArrayInputStream (buffer);
+    if (ze.getMethod() == ZipEntry.DEFLATED)
+      is = new InflaterInputStream (is);
+    return is;
   }
 
   public String getName () { return name; }
@@ -138,7 +139,7 @@ public class ZipFile implements ZipConstants
     int byte0 = file.read();
     int byte1 = file.read();
     if (byte0 < 0 || byte1 < 0)
-      throw new EOFException(".zip archive ended prematurely");
+      throw new ZipException (".zip archive ended prematurely");
     return ((byte1 & 0xFF) << 8) | (byte0 & 0xFF);
   }
 
@@ -149,10 +150,15 @@ public class ZipFile implements ZipConstants
     int byte2 = file.read();
     int byte3 = file.read();
     if (byte3 < 0)
-      throw new EOFException(".zip archive ended prematurely");
+      throw new ZipException (".zip archive ended prematurely");
     return ((byte3 & 0xFF) << 24) + ((byte2 & 0xFF) << 16)
       + ((byte1 & 0xFF) << 8) + (byte0 & 0xFF);
   }
+
+  ZipEntry entries;
+  int numEntries;
+  RandomAccessFile file;
+  String name;
 }
 
 class ZipEnumeration implements java.util.Enumeration
index 8512896..f2e042b 100644 (file)
@@ -168,14 +168,14 @@ public class ZipInputStream extends InflaterInputStream
          {
            int sig = read4();
            if (sig != 0x04034b50)
-             throw new IOException("bad/missing magic number at end of .zip entry");
+             throw new ZipException("bad/missing magic number at end of .zip entry");
            int crc = read4();
            int compressedSize = read4();
            int uncompressedSize = read4();
            if (current.compressedSize != compressedSize
                || current.size != uncompressedSize
                || current.crc != crc)
-             throw new IOException("bad data descriptor at end of .zip entry");
+             throw new ZipException("bad data descriptor at end of .zip entry");
          }
        current = null;
        avail = 0;
index 18f4d38..f4ce7ac 100644 (file)
@@ -9,65 +9,268 @@ details.  */
 package java.util.zip;
 import java.io.*;
 
-/** JUST AN INCOMPLETE STUB! */
+/* Written using on-line Java Platform 1.2 API Specification
+ * and JCL book.
+ * Believed complete and correct.
+ */
 
 public class ZipOutputStream extends DeflaterOutputStream
   implements ZipConstants
 {
-  ZipEntry current;
-  int method = DEFLATED;
-  int level = 3;  // FIXME - should be DEFAULT_COMPRESSION
-  String comment;
-
   public static final int STORED = 0;
   public static final int DEFLATED = 8;
 
-  public ZipOutputStream (OutputStream out)
+  public void close () throws IOException
   {
-    super(out);
+    finish ();
+    out.close();
+  }
+
+  public void closeEntry ()  throws IOException
+  {
+    int uncompressed_size = def.getTotalIn();
+    int compressed_size = def.getTotalOut();
+    int crc = (int) (filter.getChecksum().getValue());
+
+    bytes_written += compressed_size;
+
+    bytes_written += put4 (0x08074b50);
+    if (current.getCrc() == -1 || current.getCompressedSize() == -1
+       || current.getSize() == -1)
+      {
+       current.setCrc(crc);
+       current.compressedSize = compressed_size;
+       current.setSize(uncompressed_size);
+      }
+    else
+      {
+       if (current.getCrc() != crc
+           || current.getCompressedSize() != compressed_size
+           || current.getSize() != uncompressed_size)
+         throw new ZipException ("zip entry field incorrect");
+      }
+    bytes_written += put4 ((int) (current.getCrc()));
+    bytes_written += put4 ((int) (current.getCompressedSize()));
+    bytes_written += put4 ((int) (current.getSize()));
+
+    current.next = chain;
+    chain = current;
+    current = null;
+    filter = null;
+  }
+
+  public void finish () throws IOException
+  {
+    if (current != null)
+      closeEntry ();
+
+    // Write the central directory.
+    long offset = bytes_written;
+    int count = 0;
+    int bytes = 0;
+    while (chain != null)
+      {
+       bytes += write_entry (chain, false);
+       ++count;
+       chain = chain.next;
+      }
+
+    // Write the end of the central directory record.
+    put4 (0x06054b50);
+    // Disk number.
+    put2 (0);
+    // Another disk number.
+    put2 (0);
+    put2 (count);
+    put4 (bytes);
+    put4 ((int) offset);
+
+    byte[] c = comment.getBytes("8859_1");
+    put2 (c.length);
+    out.write(c);
+    out.write((byte) 0);
   }
 
-  public void setLevel (int level) { this.level = level; }
-  public void setMethod (int method) { this.method = method; }
-  public void setComment(String comment) { this.comment = comment; }
+  // Helper for finish and putNextEntry.
+  private int write_entry (ZipEntry entry, boolean is_local)
+    throws IOException
+  {
+    long offset = bytes_written;
+
+    int bytes = put4 (is_local ? 0x04034b50 : 0x02014b50);
+    if (! is_local)
+      bytes += put_version ();
+    bytes += put_version ();
+
+    boolean crc_after = false;
+    if (is_local
+       && (current.getCrc() == -1 || current.getCompressedSize() == -1
+           || current.getSize() == -1))
+      crc_after = true;
+    // For the bits field we always indicate `normal' compression,
+    // even if that isn't true.
+    bytes += put2 (crc_after ? (1 << 3) : 0);
+    bytes += put2 (entry.method);
+
+    bytes += put2(0);  // time - FIXME
+    bytes += put2(0);  // date - FIXME
+
+    if (crc_after)
+      {
+       // CRC, compressedSize, and Size are always 0 in this header.
+       // The actual values are given after the entry.
+       bytes += put4 (0);
+       bytes += put4 (0);
+       bytes += put4 (0);
+      }
+    else
+      {
+       bytes += put4 ((int) (entry.getCrc()));
+       bytes += put4 ((int) (entry.getCompressedSize()));
+       bytes += put4 ((int) (entry.getSize()));
+      }
+
+    byte[] name = entry.name.getBytes("8859_1");
+    bytes += put2 (name.length);
+    bytes += put2 (entry.extra == null ? 0 : entry.extra.length);
+
+    byte[] comment = null;
+    if (! is_local)
+      {
+       if (entry.getComment() == null)
+         bytes += put2 (0);
+       else
+         {
+           comment = entry.getComment().getBytes("8859_1");
+           bytes += put2 (comment.length);
+         }
+
+       // Disk number start.
+       bytes += put2 (0);
+       // Internal file attributes.
+       bytes += put2 (0);
+       // External file attributes.
+       bytes += put2 (0);
+       // Relative offset of local header.
+       bytes += put2 ((int) offset);
+      }
+
+    out.write (name);
+    out.write ((byte) 0);
+    bytes += name.length + 1;
+    if (entry.extra != null)
+      {
+       out.write(entry.extra);
+       out.write((byte) 0);
+       bytes += entry.extra.length + 1;
+      }
+    if (comment != null)
+      {
+       out.write(comment);
+       out.write((byte) 0);
+       bytes += comment.length + 1;
+      }
+
+    bytes_written += bytes;
+    return bytes;
+  }
 
   public void putNextEntry (ZipEntry entry) throws IOException
   {
-    put4(0x04034b50);
-    put2(0);  // version - FIXME
-    put2(0);  // bits - FIXME
+    if (current != null)
+      closeEntry ();
+
     if (entry.method < 0 )
       entry.method = method;
-    put2(entry.method);
-    put2(0);  // time - FIXME
-    put2(0);  // date - FIXME
-    put4((int) entry.crc);
-    put4((int) entry.compressedSize); // FIXME
-    put4((int) entry.size); // FIXME
-    put2(entry.name.length());
-    put2(entry.extra == null ? 0 : entry.extra.length);
-    byte[] name = entry.name.getBytes("8859_1");
-    out.write(name);
-    if (entry.extra != null)
-      out.write(entry.extra);
-    throw new Error ("java.util.zip.ZipOutputStream.putNextEntry:  not implemented");
+    if (entry.method == STORED)
+      {
+       if (entry.getSize() == -1 || entry.getCrc() == -1)
+         throw new ZipException ("required entry not set");
+       // Just in case.
+       entry.compressedSize = entry.getSize();
+      }
+    write_entry (entry, true);
+    current = entry;
+    int compr = (method == STORED) ? Deflater.NO_COMPRESSION : level;
+    def.reset();
+    def.setLevel(compr);
+    filter = new CheckedOutputStream (new DeflaterOutputStream (out, def),
+                                     new CRC32 ());
   }
 
-  public void closeEntry ()  throws IOException
+  public void setLevel (int level)
   {
+    if (level != Deflater.DEFAULT_COMPRESSION
+       && (level < Deflater.NO_COMPRESSION
+           || level > Deflater.BEST_COMPRESSION))
+      throw new IllegalArgumentException ();
+    this.level = level;
   }
 
-  private void put2 (int i)  throws IOException
+  public void setMethod (int method)
+  {
+    if (method != DEFLATED && method != STORED)
+      throw new IllegalArgumentException ();
+    this.method = method;
+  }
+
+  public void setComment (String comment)
+  {
+    if (comment.length() > 65535)
+      throw new IllegalArgumentException ();
+    this.comment = comment;
+  }
+
+  public synchronized void write (byte[] buf, int off, int len)
+    throws IOException
+  {
+    if (filter == null)
+      throw new ZipException ("no open zip entry");
+    filter.write(buf, off, len);
+  }
+
+  public ZipOutputStream (OutputStream out)
+  {
+    super (out);
+    def = new Deflater (level, true);
+  }
+
+  private int put2 (int i) throws IOException
   {
     out.write (i);
     out.write (i >> 8);
+    return 2;
   }
 
-  private void put4 (int i)  throws IOException
+  private int put4 (int i) throws IOException
   {
     out.write (i);
     out.write (i >> 8);
     out.write (i >> 16);
     out.write (i >> 24);
+    return 4;
   }
+
+  private int put_version () throws IOException
+  {
+    // FIXME: for now we assume Unix, and we ignore the version
+    // number.
+    return put2 (3 << 8);
+  }
+
+  // The entry we are currently writing, or null if we've called
+  // closeEntry.
+  private ZipEntry current;
+  // The chain of entries which have been written to this file.
+  private ZipEntry chain;
+  // The output stream to which data should be sent.
+  private CheckedOutputStream filter;
+
+  private int method = DEFLATED;
+  private int level = Deflater.DEFAULT_COMPRESSION;
+  private String comment = "";
+  private long bytes_written;
+
+  // The Deflater we use.
+  private Deflater def;
 }
diff --git a/libjava/java/util/zip/natDeflater.cc b/libjava/java/util/zip/natDeflater.cc
new file mode 100644 (file)
index 0000000..07cf009
--- /dev/null
@@ -0,0 +1,209 @@
+// natDeflater.cc - Implementation of Deflater native methods.
+
+/* Copyright (C) 1999  Cygnus Solutions
+
+   This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
+details.  */
+
+// Written by Tom Tromey <tromey@cygnus.com>
+
+#include <config.h>
+
+#include <zlib.h>
+
+#include <cni.h>
+#include <jvm.h>
+
+#include <java/util/zip/Deflater.h>
+#include <java/util/zip/DataFormatException.h>
+
+#include <java/lang/InternalError.h>
+#include <java/lang/NullPointerException.h>
+#include <java/lang/ArrayIndexOutOfBoundsException.h>
+
+extern void *_Jv_ZMalloc (void *, uInt nitems, uInt size);
+extern void _Jv_ZFree (void *, void *addr);
+
+\f
+
+jint
+java::util::zip::Deflater::deflate (jbyteArray buf, jint off, jint len)
+{
+  JvSynchronize sync (this);
+  z_streamp s = (z_streamp) zstream;
+
+  if (! buf)
+    _Jv_Throw (new java::lang::NullPointerException);
+  if (off < 0 || len < 0 || off + len > buf->length)
+    _Jv_Throw (new java::lang::ArrayIndexOutOfBoundsException);
+
+  s->next_out = (Bytef *) (elements (buf) + off);
+  s->avail_out = len;
+
+  switch (::deflate (s, flush_flag))
+    {
+    case Z_STREAM_END:
+      is_finished = true;
+      if (s->avail_out == len)
+       return -1;
+      break;
+
+    case Z_STREAM_ERROR:
+    case Z_BUF_ERROR:
+      // FIXME?
+      _Jv_Throw (new java::lang::InternalError);
+      break;
+
+    case Z_OK:
+      break;
+    }
+
+  return len - s->avail_out;
+}
+
+void
+java::util::zip::Deflater::end ()
+{
+  JvSynchronize sync (this);
+  // Just ignore errors.
+  deflateEnd ((z_streamp) zstream);
+  _Jv_Free (zstream);
+  zstream = NULL;
+}
+
+void
+java::util::zip::Deflater::finish ()
+{
+  JvSynchronize sync (this);
+  flush_flag = Z_FINISH;
+}
+
+jint
+java::util::zip::Deflater::getAdler ()
+{
+  JvSynchronize sync (this);
+  z_streamp s = (z_streamp) zstream;
+  return s->adler;
+}
+
+jint
+java::util::zip::Deflater::getTotalIn ()
+{
+  JvSynchronize sync (this);
+  z_streamp s = (z_streamp) zstream;
+  return s->total_in;
+}
+
+jint
+java::util::zip::Deflater::getTotalOut ()
+{
+  JvSynchronize sync (this);
+  z_streamp s = (z_streamp) zstream;
+  return s->total_out;
+}
+
+jboolean
+java::util::zip::Deflater::needsInput ()
+{
+  JvSynchronize sync (this);
+  z_streamp s = (z_streamp) zstream;
+  return s->avail_in - last_input_count == 0;
+}
+
+void
+java::util::zip::Deflater::reset ()
+{
+  JvSynchronize sync (this);
+  z_streamp s = (z_streamp) zstream;
+  // Just ignore errors.
+  deflateReset (s);
+  flush_flag = 0;
+}
+
+void
+java::util::zip::Deflater::setDictionary (jbyteArray buf, jint off, jint len)
+{
+  JvSynchronize sync (this);
+  z_streamp s = (z_streamp) zstream;
+
+  if (! buf)
+    _Jv_Throw (new java::lang::NullPointerException);
+  if (off < 0 || len < 0 || off + len > buf->length)
+    _Jv_Throw (new java::lang::ArrayIndexOutOfBoundsException);
+
+  // Ignore errors.
+  deflateSetDictionary (s, (Bytef *) (elements (buf) + off), len);
+}
+
+void
+java::util::zip::Deflater::setInput (jbyteArray buf, jint off, jint len)
+{
+  JvSynchronize sync (this);
+  z_streamp s = (z_streamp) zstream;
+
+  if (! buf)
+    _Jv_Throw (new java::lang::NullPointerException);
+  if (off < 0 || len < 0 || off + len > buf->length)
+    _Jv_Throw (new java::lang::ArrayIndexOutOfBoundsException);
+
+  last_input_count = len;
+  s->next_in = (Bytef *) (elements (buf) + off);
+  s->avail_in = len;
+}
+
+void
+java::util::zip::Deflater::update ()
+{
+  JvSynchronize sync (this);
+  z_streamp s = (z_streamp) zstream;
+
+  int strat;
+  switch (strategy)
+    {
+    case DEFAULT_STRATEGY:
+      strat = Z_DEFAULT_STRATEGY;
+      break;
+    case FILTERED:
+      strat = Z_FILTERED;
+      break;
+    case HUFFMAN_ONLY:
+      strat = Z_HUFFMAN_ONLY;
+      break;
+    }
+
+  // Ignore errors.
+  deflateParams (s, level, strat);
+}
+
+void
+java::util::zip::Deflater::init (jint level, jboolean no_header)
+{
+  z_stream_s *stream = (z_stream_s *) _Jv_Malloc (sizeof (z_stream_s));
+  stream->next_in = Z_NULL;
+  stream->avail_in = 0;
+  stream->zalloc = _Jv_ZMalloc;
+  stream->zfree = _Jv_ZFree;
+  stream->opaque = NULL;
+
+  // Handle NO_HEADER using undocumented zlib feature.
+  int wbits = MAX_WBITS;
+  if (no_header)
+    wbits = - wbits;
+
+#define DEFAULT_MEM_LEVEL 8
+  if (deflateInit2 (stream, level, Z_DEFLATED, wbits,
+                   DEFAULT_MEM_LEVEL, Z_DEFAULT_STRATEGY) != Z_OK)
+    {
+      jstring msg = NULL;
+      if (stream->msg != NULL)
+       msg = JvNewStringLatin1 (stream->msg);
+      _Jv_Throw (new java::lang::InternalError (msg));
+    }
+
+  zstream = reinterpret_cast<gnu::gcj::RawData *> (stream);
+  is_finished = false;
+  flush_flag = 0;
+}
diff --git a/libjava/java/util/zip/natInflater.cc b/libjava/java/util/zip/natInflater.cc
new file mode 100644 (file)
index 0000000..b33ab50
--- /dev/null
@@ -0,0 +1,202 @@
+// natInflater.cc - Implementation of Inflater native methods.
+
+/* Copyright (C) 1999  Cygnus Solutions
+
+   This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
+details.  */
+
+// Written by Tom Tromey <tromey@cygnus.com>
+
+#include <config.h>
+
+#include <zlib.h>
+
+#include <cni.h>
+#include <jvm.h>
+
+#include <java/util/zip/Inflater.h>
+#include <java/util/zip/DataFormatException.h>
+
+#include <java/lang/InternalError.h>
+#include <java/lang/NullPointerException.h>
+#include <java/lang/ArrayIndexOutOfBoundsException.h>
+#include <java/lang/OutOfMemoryError.h>
+
+\f
+
+// A couple of helper functions used to interface with zlib's
+// allocation.
+
+void *
+_Jv_ZMalloc (void *, uInt nitems, uInt size)
+{
+  return _Jv_Malloc (nitems * size);
+}
+
+void
+_Jv_ZFree (void *, void *addr)
+{
+  _Jv_Free (addr);
+}
+
+\f
+
+void
+java::util::zip::Inflater::end ()
+{
+  JvSynchronize sync (this);
+  // Just ignore errors.
+  inflateEnd ((z_streamp) zstream);
+  _Jv_Free (zstream);
+  zstream = NULL;
+}
+
+jint
+java::util::zip::Inflater::getAdler ()
+{
+  JvSynchronize sync (this);
+  z_streamp s = (z_streamp) zstream;
+  return s->adler;
+}
+
+jint
+java::util::zip::Inflater::getRemaining ()
+{
+  JvSynchronize sync (this);
+  z_streamp s = (z_streamp) zstream;
+  return s->avail_in - last_input_count;
+}
+
+jint
+java::util::zip::Inflater::getTotalIn ()
+{
+  JvSynchronize sync (this);
+  z_streamp s = (z_streamp) zstream;
+  return s->total_in;
+}
+
+jint
+java::util::zip::Inflater::getTotalOut ()
+{
+  JvSynchronize sync (this);
+  z_streamp s = (z_streamp) zstream;
+  return s->total_out;
+}
+
+jint
+java::util::zip::Inflater::inflate (jbyteArray buf, jint off, jint len)
+{
+  JvSynchronize sync (this);
+  z_streamp s = (z_streamp) zstream;
+
+  if (! buf)
+    _Jv_Throw (new java::lang::NullPointerException);
+  if (off < 0 || len < 0 || off + len > buf->length)
+    _Jv_Throw (new java::lang::ArrayIndexOutOfBoundsException);
+
+  s->next_out = (Bytef *) (elements (buf) + off);
+  s->avail_out = len;
+
+  switch (::inflate (s, Z_SYNC_FLUSH))
+    {
+    case Z_STREAM_END:
+      is_finished = true;
+      if (s->avail_out == len)
+       return -1;
+      break;
+
+    case Z_NEED_DICT:
+      dict_needed = true;
+      break;
+
+    case Z_DATA_ERROR:
+      _Jv_Throw (new java::util::zip::DataFormatException);
+      break;
+
+    case Z_MEM_ERROR:
+      _Jv_Throw (new java::lang::OutOfMemoryError);
+      break;
+
+    case Z_BUF_ERROR:
+      // FIXME?
+      _Jv_Throw (new java::lang::InternalError);
+      break;
+
+    case Z_OK:
+      break;
+    }
+
+  return len - s->avail_out;
+}
+
+void
+java::util::zip::Inflater::reset ()
+{
+  JvSynchronize sync (this);
+  z_streamp s = (z_streamp) zstream;
+  // Just ignore errors.
+  inflateReset (s);
+}
+
+void
+java::util::zip::Inflater::setDictionary (jbyteArray buf, jint off, jint len)
+{
+  JvSynchronize sync (this);
+  z_streamp s = (z_streamp) zstream;
+
+  if (! buf)
+    _Jv_Throw (new java::lang::NullPointerException);
+  if (off < 0 || len < 0 || off + len > buf->length)
+    _Jv_Throw (new java::lang::ArrayIndexOutOfBoundsException);
+
+  // Ignore errors.
+  inflateSetDictionary (s, (Bytef *) (elements (buf) + off), len);
+  dict_needed = false;
+}
+
+void
+java::util::zip::Inflater::setInput (jbyteArray buf, jint off, jint len)
+{
+  JvSynchronize sync (this);
+  z_streamp s = (z_streamp) zstream;
+
+  if (! buf)
+    _Jv_Throw (new java::lang::NullPointerException);
+  if (off < 0 || len < 0 || off + len > buf->length)
+    _Jv_Throw (new java::lang::ArrayIndexOutOfBoundsException);
+
+  last_input_count = len;
+  s->next_in = (Bytef *) (elements (buf) + off);
+  s->avail_in = len;
+}
+
+void
+java::util::zip::Inflater::init (jboolean no_header)
+{
+  z_stream_s *stream = (z_stream_s *) _Jv_Malloc (sizeof (z_stream_s));
+  stream->next_in = Z_NULL;
+  stream->avail_in = 0;
+  stream->zalloc = _Jv_ZMalloc;
+  stream->zfree = _Jv_ZFree;
+  stream->opaque = NULL;
+
+  // Handle NO_HEADER using undocumented zlib feature.
+  int wbits = MAX_WBITS;
+  if (no_header)
+    wbits = - wbits;
+
+  if (inflateInit2 (stream, wbits) != Z_OK)
+    {
+      jstring msg = NULL;
+      if (stream->msg != NULL)
+       msg = JvNewStringLatin1 (stream->msg);
+      _Jv_Throw (new java::lang::InternalError (msg));
+    }
+
+  zstream = reinterpret_cast<gnu::gcj::RawData *> (stream);
+  is_finished = false;
+  dict_needed = false;
+}