You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by hi...@apache.org on 2009/10/12 00:00:56 UTC

svn commit: r824184 [3/34] - in /harmony/enhanced/classlib/branches/java6: ./ depends/build/ doc/ doc/security/ make/ modules/accessibility/src/main/java/javax/accessibility/ modules/accessibility/src/test/api/java/common/javax/accessibility/ modules/a...

Modified: harmony/enhanced/classlib/branches/java6/modules/archive/src/main/java/java/util/zip/CheckedInputStream.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/archive/src/main/java/java/util/zip/CheckedInputStream.java?rev=824184&r1=824183&r2=824184&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/archive/src/main/java/java/util/zip/CheckedInputStream.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/archive/src/main/java/java/util/zip/CheckedInputStream.java Sun Oct 11 21:59:47 2009
@@ -1,13 +1,13 @@
-/* 
+/*
  * Licensed to the Apache Software Foundation (ASF) under one or more
  * contributor license agreements.  See the NOTICE file distributed with
  * this work for additional information regarding copyright ownership.
  * The ASF licenses this file to You under the Apache License, Version 2.0
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
- * 
+ *
  *     http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -34,7 +34,7 @@
      * Constructs a new {@code CheckedInputStream} on {@code InputStream}
      * {@code is}. The checksum will be calculated using the algorithm
      * implemented by {@code csum}.
-     * 
+     *
      * @param is
      *            the input stream to calculate checksum from.
      * @param csum
@@ -48,7 +48,7 @@
     /**
      * Reads one byte of data from the underlying input stream and updates the
      * checksum with the byte data.
-     * 
+     *
      * @return {@code -1} at the end of the stream, a single byte value
      *         otherwise.
      * @throws IOException
@@ -67,7 +67,7 @@
      * Reads up to n bytes of data from the underlying input stream, storing it
      * into {@code buf}, starting at offset {@code off}. The checksum is
      * updated with the bytes read.
-     * 
+     *
      * @param buf
      *            the byte array in which to store the bytes read.
      * @param off
@@ -91,7 +91,7 @@
 
     /**
      * Returns the checksum calculated on the stream read so far.
-     * 
+     *
      * @return the updated checksum.
      */
     public Checksum getChecksum() {
@@ -101,7 +101,7 @@
     /**
      * Skip up to n bytes of data on the underlying input stream. Any skipped
      * bytes are added to the running checksum value.
-     * 
+     *
      * @param nbytes
      *            the number of bytes to skip.
      * @throws IOException
@@ -114,7 +114,7 @@
             return 0;
         }
         long skipped = 0;
-        byte[] b = new byte[2048];
+        byte[] b = new byte[(int)Math.min(nbytes, 2048L)];
         int x, v;
         while (skipped != nbytes) {
             x = in.read(b, 0,

Modified: harmony/enhanced/classlib/branches/java6/modules/archive/src/main/java/java/util/zip/CheckedOutputStream.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/archive/src/main/java/java/util/zip/CheckedOutputStream.java?rev=824184&r1=824183&r2=824184&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/archive/src/main/java/java/util/zip/CheckedOutputStream.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/archive/src/main/java/java/util/zip/CheckedOutputStream.java Sun Oct 11 21:59:47 2009
@@ -1,13 +1,13 @@
-/* 
+/*
  * Licensed to the Apache Software Foundation (ASF) under one or more
  * contributor license agreements.  See the NOTICE file distributed with
  * this work for additional information regarding copyright ownership.
  * The ASF licenses this file to You under the Apache License, Version 2.0
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
- * 
+ *
  *     http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -34,7 +34,7 @@
      * Constructs a new {@code CheckedOutputStream} on {@code OutputStream}
      * {@code os}. The checksum is calculated using the algorithm implemented
      * by {@code csum}.
-     * 
+     *
      * @param os
      *            the output stream to calculate checksum for.
      * @param cs
@@ -47,7 +47,7 @@
 
     /**
      * Returns the checksum calculated on the stream read so far.
-     * 
+     *
      * @return the updated checksum.
      */
     public Checksum getChecksum() {
@@ -57,7 +57,7 @@
     /**
      * Writes the specified byte to the underlying stream. The checksum is
      * updated with {@code val}.
-     * 
+     *
      * @param val
      *            the data value to written to the output stream.
      * @throws IOException
@@ -72,7 +72,7 @@
     /**
      * Writes n bytes of data from {@code buf} starting at offset {@code off} to
      * the underlying stream. The checksum is updated with the bytes written.
-     * 
+     *
      * @param buf
      *            data written to the output stream.
      * @param off

Modified: harmony/enhanced/classlib/branches/java6/modules/archive/src/main/java/java/util/zip/Checksum.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/archive/src/main/java/java/util/zip/Checksum.java?rev=824184&r1=824183&r2=824184&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/archive/src/main/java/java/util/zip/Checksum.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/archive/src/main/java/java/util/zip/Checksum.java Sun Oct 11 21:59:47 2009
@@ -1,13 +1,13 @@
-/* 
+/*
  * Licensed to the Apache Software Foundation (ASF) under one or more
  * contributor license agreements.  See the NOTICE file distributed with
  * this work for additional information regarding copyright ownership.
  * The ASF licenses this file to You under the Apache License, Version 2.0
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
- * 
+ *
  *     http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -25,7 +25,7 @@
 
     /**
      * Returns the current calculated checksum value.
-     * 
+     *
      * @return the checksum.
      */
     public long getValue();
@@ -50,7 +50,7 @@
 
     /**
      * Updates the checksum value with the given byte.
-     * 
+     *
      * @param val
      *            the byte to update the checksum with.
      */

Modified: harmony/enhanced/classlib/branches/java6/modules/archive/src/main/java/java/util/zip/DataFormatException.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/archive/src/main/java/java/util/zip/DataFormatException.java?rev=824184&r1=824183&r2=824184&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/archive/src/main/java/java/util/zip/DataFormatException.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/archive/src/main/java/java/util/zip/DataFormatException.java Sun Oct 11 21:59:47 2009
@@ -1,13 +1,13 @@
-/* 
+/*
  * Licensed to the Apache Software Foundation (ASF) under one or more
  * contributor license agreements.  See the NOTICE file distributed with
  * this work for additional information regarding copyright ownership.
  * The ASF licenses this file to You under the Apache License, Version 2.0
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
- * 
+ *
  *     http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

Modified: harmony/enhanced/classlib/branches/java6/modules/archive/src/main/java/java/util/zip/Deflater.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/archive/src/main/java/java/util/zip/Deflater.java?rev=824184&r1=824183&r2=824184&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/archive/src/main/java/java/util/zip/Deflater.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/archive/src/main/java/java/util/zip/Deflater.java Sun Oct 11 21:59:47 2009
@@ -1,13 +1,13 @@
-/* 
+/*
  * Licensed to the Apache Software Foundation (ASF) under one or more
  * contributor license agreements.  See the NOTICE file distributed with
  * this work for additional information regarding copyright ownership.
  * The ASF licenses this file to You under the Apache License, Version 2.0
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
- * 
+ *
  *     http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -121,7 +121,7 @@
      * level. The strategy can be specified with {@code setStrategy}, only. A
      * header is added to the output by default; use
      * {@code Deflater(level, boolean)} if you need to omit the header.
-     * 
+     *
      * @param level
      *            the compression level in the range between 0 and 9.
      */
@@ -134,7 +134,7 @@
      * level. If noHeader is passed as true no ZLib header is added to the
      * output. In a ZIP archive every entry (compressed file) comes with such a
      * header. The strategy can be specified with the setStrategy method, only.
-     * 
+     *
      * @param level
      *            the compression level in the range between 0 and 9.
      * @param noHeader
@@ -152,7 +152,7 @@
     /**
      * Deflates the data (previously passed to {@code setInput}) into the
      * supplied buffer.
-     * 
+     *
      * @param buf
      *            buffer to write compressed data to.
      * @return number of bytes of compressed data written to {@code buf}.
@@ -165,7 +165,7 @@
     /**
      * Deflates data (previously passed to {@code setInput}) into a specific
      * region within the supplied buffer.
-     * 
+     *
      * @param buf
      *            the buffer to write compressed data to.
      * @param off
@@ -218,7 +218,7 @@
     /**
      * Indicates to the {@code Deflater} that all uncompressed input has been provided
      * to it.
-     * 
+     *
      * @see #finished
      */
     public synchronized void finish() {
@@ -228,7 +228,7 @@
     /**
      * Returns whether or not all provided data has been successfully
      * compressed.
-     * 
+     *
      * @return true if all data has been compressed, false otherwise.
      */
     public synchronized boolean finished() {
@@ -239,7 +239,7 @@
      * Returns the Adler32 checksum of uncompressed data currently read. If a
      * preset dictionary is used getAdler() will return the Adler32 checksum of
      * the dictionary used.
-     * 
+     *
      * @return the Adler32 checksum of uncompressed data or preset dictionary if
      *         used.
      * @see #setDictionary(byte[])
@@ -257,7 +257,7 @@
 
     /**
      * Returns the total number of bytes of input consumed by the {@code Deflater}.
-     * 
+     *
      * @return number of bytes of input read.
      */
     public synchronized int getTotalIn() {
@@ -272,7 +272,7 @@
 
     /**
      * Returns the total number of compressed bytes output by this {@code Deflater}.
-     * 
+     *
      * @return number of compressed bytes output.
      */
     public synchronized int getTotalOut() {
@@ -291,7 +291,7 @@
      * returns true setInput() must be called before deflation can continue. If
      * all bytes of uncompressed data have been provided to the {@code Deflater}
      * finish() must be called to ensure the compressed data is output.
-     * 
+     *
      * @return {@code true} if input is required for deflation to continue,
      *         {@code false} otherwise.
      * @see #finished()
@@ -310,7 +310,7 @@
      * previously made settings for the compression strategy or level. This
      * operation <i>must</i> be called after {@code finished()} returns
      * {@code true} if the {@code Deflater} is to be reused.
-     * 
+     *
      * @see #finished
      */
     public synchronized void reset() {
@@ -331,7 +331,7 @@
      * setDictionary() can only be called if this {@code Deflater} supports the writing
      * of ZLIB headers. This is the default behaviour but can be overridden
      * using {@code Deflater(int, boolean)}.
-     * 
+     *
      * @param buf
      *            the buffer containing the dictionary data bytes.
      * @see Deflater#Deflater(int, boolean)
@@ -373,7 +373,7 @@
     /**
      * Sets the input buffer the {@code Deflater} will use to extract uncompressed bytes
      * for later compression.
-     * 
+     *
      * @param buf
      *            the buffer.
      */
@@ -385,7 +385,7 @@
      * Sets the input buffer the {@code Deflater} will use to extract uncompressed bytes
      * for later compression. Input will be taken from the buffer region
      * starting at off and ending at nbytes - 1.
-     * 
+     *
      * @param buf
      *            the buffer containing the input data bytes.
      * @param off
@@ -422,7 +422,7 @@
      * Sets the compression level to be used when compressing data. The
      * compression level must be a value between 0 and 9. This value must be set
      * prior to calling setInput().
-     * 
+     *
      * @param level
      *            compression level to use
      * @exception IllegalArgumentException
@@ -442,7 +442,7 @@
      * Sets the compression strategy to be used. The strategy must be one of
      * FILTERED, HUFFMAN_ONLY or DEFAULT_STRATEGY.This value must be set prior
      * to calling setInput().
-     * 
+     *
      * @param strategy
      *            compression strategy to use
      * @exception IllegalArgumentException
@@ -463,7 +463,7 @@
      * Returns a long int of total number of bytes read by the {@code Deflater}. This
      * method performs the same as {@code getTotalIn} except it returns a long value
      * instead of an integer
-     * 
+     *
      * @see #getTotalIn()
      * @return total number of bytes read by {@code Deflater}.
      */
@@ -479,7 +479,7 @@
      * Returns a long int of total number of bytes of read by the {@code Deflater}. This
      * method performs the same as {@code getTotalOut} except it returns a long
      * value instead of an integer
-     * 
+     *
      * @see #getTotalOut()
      * @return bytes exactly write by {@code Deflater}
      */

Modified: harmony/enhanced/classlib/branches/java6/modules/archive/src/main/java/java/util/zip/DeflaterOutputStream.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/archive/src/main/java/java/util/zip/DeflaterOutputStream.java?rev=824184&r1=824183&r2=824184&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/archive/src/main/java/java/util/zip/DeflaterOutputStream.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/archive/src/main/java/java/util/zip/DeflaterOutputStream.java Sun Oct 11 21:59:47 2009
@@ -1,13 +1,13 @@
-/* 
+/*
  * Licensed to the Apache Software Foundation (ASF) under one or more
  * contributor license agreements.  See the NOTICE file distributed with
  * this work for additional information regarding copyright ownership.
  * The ASF licenses this file to You under the Apache License, Version 2.0
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
- * 
+ *
  *     http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -48,7 +48,7 @@
     /**
      * This constructor lets you pass the {@code Deflater} specifying the
      * compression algorithm.
-     * 
+     *
      * @param os
      *            is the {@code OutputStream} where to write the compressed data
      *            to.
@@ -66,7 +66,7 @@
      * default settings for the {@code Deflater} and internal buffer are used.
      * In particular the {@code Deflater} produces a ZLIB header in the output
      * stream.
-     * 
+     *
      * @param os
      *            is the OutputStream where to write the compressed data to.
      */
@@ -77,7 +77,7 @@
     /**
      * This constructor lets you specify both the compression algorithm as well
      * as the internal buffer size to be used.
-     * 
+     *
      * @param os
      *            is the {@code OutputStream} where to write the compressed data
      *            to.
@@ -102,7 +102,7 @@
     /**
      * Compress the data in the input buffer and write it to the underlying
      * stream.
-     * 
+     *
      * @throws IOException
      *             If an error occurs during deflation.
      */
@@ -118,7 +118,7 @@
      * Writes any unwritten compressed data to the underlying stream, the closes
      * all underlying streams. This stream can no longer be used after close()
      * has been called.
-     * 
+     *
      * @throws IOException
      *             If an error occurs while closing the data compression
      *             process.
@@ -135,7 +135,7 @@
     /**
      * Writes any unwritten data to the underlying stream. Does not close the
      * stream.
-     * 
+     *
      * @throws IOException
      *             If an error occurs.
      */
@@ -165,7 +165,7 @@
     /**
      * Compresses {@code nbytes} of data from {@code buf} starting at
      * {@code off} and writes it to the underlying stream.
-     * 
+     *
      * @param buffer
      *            the buffer of data to compress.
      * @param off

Modified: harmony/enhanced/classlib/branches/java6/modules/archive/src/main/java/java/util/zip/GZIPInputStream.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/archive/src/main/java/java/util/zip/GZIPInputStream.java?rev=824184&r1=824183&r2=824184&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/archive/src/main/java/java/util/zip/GZIPInputStream.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/archive/src/main/java/java/util/zip/GZIPInputStream.java Sun Oct 11 21:59:47 2009
@@ -1,13 +1,13 @@
-/* 
+/*
  * Licensed to the Apache Software Foundation (ASF) under one or more
  * contributor license agreements.  See the NOTICE file distributed with
  * this work for additional information regarding copyright ownership.
  * The ASF licenses this file to You under the Apache License, Version 2.0
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
- * 
+ *
  *     http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -69,7 +69,7 @@
     /**
      * Construct a {@code GZIPInputStream} to read from GZIP data from the
      * underlying stream. Set the internal buffer size to {@code size}.
-     * 
+     *
      * @param is
      *            the {@code InputStream} to read data from.
      * @param size
@@ -148,7 +148,7 @@
     /**
      * Reads and decompresses GZIP data from the underlying stream into the
      * given buffer.
-     * 
+     *
      * @param buffer
      *            Buffer to receive data
      * @param off
@@ -161,37 +161,49 @@
         if (closed) {
             throw new IOException(Messages.getString("archive.1E")); //$NON-NLS-1$
         }
-        if (eof) {
+        if (eos) {
             return -1;
         }
         // avoid int overflow, check null buffer
-        if (off <= buffer.length && nbytes >= 0 && off >= 0
-                && buffer.length - off >= nbytes) {
-            int val = super.read(buffer, off, nbytes);
-            if (val != -1) {
-                crc.update(buffer, off, val);
-            } else if (!eos) {
-                eos = true;
-                // Get non-compressed bytes read by fill
-                int size = inf.getRemaining();
-                final int trailerSize = 8; // crc (4 bytes) + total out (4
-                // bytes)
-                byte[] b = new byte[trailerSize];
-                int copySize = (size > trailerSize) ? trailerSize : size;
+        if (off > buffer.length || nbytes < 0 || off < 0
+                || buffer.length - off < nbytes) {
+            throw new ArrayIndexOutOfBoundsException();
+        }
 
-                System.arraycopy(buf, len - size, b, 0, copySize);
-                readFully(b, copySize, trailerSize - copySize);
+        int bytesRead;
+        try {
+            bytesRead = super.read(buffer, off, nbytes);
+        } finally {
+            eos = eof; // update eos after every read(), even when it throws
+        }
 
-                if (getLong(b, 0) != crc.getValue()) {
-                    throw new IOException(Messages.getString("archive.20")); //$NON-NLS-1$
-                }
-                if ((int) getLong(b, 4) != inf.getTotalOut()) {
-                    throw new IOException(Messages.getString("archive.21")); //$NON-NLS-1$
-                }
-            }
-            return val;
+        if (bytesRead != -1) {
+            crc.update(buffer, off, bytesRead);
+        }
+
+        if (eos) {
+            verifyCrc();
+        }
+
+        return bytesRead;
+    }
+
+    private void verifyCrc() throws IOException {
+        // Get non-compressed bytes read by fill
+        int size = inf.getRemaining();
+        final int trailerSize = 8; // crc (4 bytes) + total out (4 bytes)
+        byte[] b = new byte[trailerSize];
+        int copySize = (size > trailerSize) ? trailerSize : size;
+
+        System.arraycopy(buf, len - size, b, 0, copySize);
+        readFully(b, copySize, trailerSize - copySize);
+
+        if (getLong(b, 0) != crc.getValue()) {
+            throw new IOException(Messages.getString("archive.20")); //$NON-NLS-1$
+        }
+        if ((int) getLong(b, 4) != inf.getTotalOut()) {
+            throw new IOException(Messages.getString("archive.21")); //$NON-NLS-1$
         }
-        throw new ArrayIndexOutOfBoundsException();
     }
 
     private void readFully(byte[] buffer, int offset, int length)

Modified: harmony/enhanced/classlib/branches/java6/modules/archive/src/main/java/java/util/zip/GZIPOutputStream.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/archive/src/main/java/java/util/zip/GZIPOutputStream.java?rev=824184&r1=824183&r2=824184&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/archive/src/main/java/java/util/zip/GZIPOutputStream.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/archive/src/main/java/java/util/zip/GZIPOutputStream.java Sun Oct 11 21:59:47 2009
@@ -1,13 +1,13 @@
-/* 
+/*
  * Licensed to the Apache Software Foundation (ASF) under one or more
  * contributor license agreements.  See the NOTICE file distributed with
  * this work for additional information regarding copyright ownership.
  * The ASF licenses this file to You under the Apache License, Version 2.0
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
- * 
+ *
  *     http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -34,7 +34,7 @@
     /**
      * Construct a new {@code GZIPOutputStream} to write data in GZIP format to
      * the underlying stream.
-     * 
+     *
      * @param os
      *            the {@code OutputStream} to write data to.
      * @throws IOException
@@ -48,7 +48,7 @@
      * Construct a new {@code GZIPOutputStream} to write data in GZIP format to
      * the underlying stream. Set the internal compression buffer to size
      * {@code size}.
-     * 
+     *
      * @param os
      *            the {@code OutputStream} to write to.
      * @param size
@@ -92,10 +92,11 @@
 
     private long writeLong(long i) throws IOException {
         // Write out the long value as an unsigned int
-        out.write((int) (i & 0xFF));
-        out.write((int) (i >> 8) & 0xFF);
-        out.write((int) (i >> 16) & 0xFF);
-        out.write((int) (i >> 24) & 0xFF);
+        int unsigned = (int) i;
+        out.write(unsigned & 0xFF);
+        out.write((unsigned >> 8) & 0xFF);
+        out.write((unsigned >> 16) & 0xFF);
+        out.write((unsigned >> 24) & 0xFF);
         return i;
     }
 

Modified: harmony/enhanced/classlib/branches/java6/modules/archive/src/main/java/java/util/zip/Inflater.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/archive/src/main/java/java/util/zip/Inflater.java?rev=824184&r1=824183&r2=824184&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/archive/src/main/java/java/util/zip/Inflater.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/archive/src/main/java/java/util/zip/Inflater.java Sun Oct 11 21:59:47 2009
@@ -1,13 +1,13 @@
-/* 
+/*
  * Licensed to the Apache Software Foundation (ASF) under one or more
  * contributor license agreements.  See the NOTICE file distributed with
  * this work for additional information regarding copyright ownership.
  * The ASF licenses this file to You under the Apache License, Version 2.0
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
- * 
+ *
  *     http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -30,14 +30,12 @@
  * The typical usage of a {@code Inflater} outside this package consists of a
  * specific call to one of its constructors before being passed to an instance
  * of {@code InflaterInputStream}.
- * 
+ *
  * @see InflaterInputStream
  * @see Deflater
  */
 public class Inflater {
 
-    private static final byte MAGIC_NUMBER = 120;
-
     static {
         oneTimeInitialization();
     }
@@ -47,16 +45,12 @@
 
     private boolean finished; // Set by the inflateImpl native
 
-    private boolean gotFirstHeaderByte;
-
     int inLength;
 
     int inRead;
 
     private boolean needsDictionary; // Set by the inflateImpl native
 
-    private boolean pass_magic_number_check = true;
-
     private long streamHandle = -1;
 
     /**
@@ -78,13 +72,12 @@
      */
     public Inflater(boolean noHeader) {
         streamHandle = createStream(noHeader);
-        gotFirstHeaderByte = noHeader;
     }
 
     private native long createStream(boolean noHeader1);
 
     /**
-     * Release any resources associated with this Inflater. Any unused
+     * Release any resources associated with this {@code Inflater}. Any unused
      * input/output is discarded. This is also called by the finalize method.
      */
     public synchronized void end() {
@@ -108,7 +101,7 @@
      * stream. If deflated bytes remain and {@code needsInput()} returns {@code
      * true} this method will return {@code false}. This method should be
      * called after all deflated input is supplied to the {@code Inflater}.
-     * 
+     *
      * @return {@code true} if all input has been inflated, {@code false}
      *         otherwise.
      */
@@ -119,7 +112,7 @@
     /**
      * Returns the <i>Adler32</i> checksum of either all bytes inflated, or the
      * checksum of the preset dictionary if one has been supplied.
-     * 
+     *
      * @return The <i>Adler32</i> checksum associated with this
      *         {@code Inflater}.
      */
@@ -164,9 +157,9 @@
 
     /**
      * Returns the number of bytes of current input remaining to be read by the
-     * inflater
-     * 
-     * @return Number of bytes of unread input.
+     * inflater.
+     *
+     * @return the number of bytes of unread input.
      */
     public synchronized int getRemaining() {
         return inLength - inRead;
@@ -175,7 +168,7 @@
     /**
      * Returns total number of bytes of input read by the {@code Inflater}. The
      * result value is limited by {@code Integer.MAX_VALUE}.
-     * 
+     *
      * @return the total number of bytes read.
      */
     public synchronized int getTotalIn() {
@@ -192,7 +185,7 @@
     /**
      * Returns total number of bytes written to the output buffer by the {@code
      * Inflater}. The result value is limited by {@code Integer.MAX_VALUE}.
-     * 
+     *
      * @return the total bytes of output data written.
      */
     public synchronized int getTotalOut() {
@@ -208,7 +201,7 @@
 
     /**
      * Inflates bytes from current input and stores them in {@code buf}.
-     * 
+     *
      * @param buf
      *            the buffer where decompressed data bytes are written.
      * @return the number of bytes inflated.
@@ -223,7 +216,7 @@
     /**
      * Inflates up to n bytes from the current input and stores them in {@code
      * buf} starting at {@code off}.
-     * 
+     *
      * @param buf
      *            the buffer to write inflated bytes to.
      * @param off
@@ -238,32 +231,32 @@
     public synchronized int inflate(byte[] buf, int off, int nbytes)
             throws DataFormatException {
         // avoid int overflow, check null buf
-        if (off <= buf.length && nbytes >= 0 && off >= 0
-                && buf.length - off >= nbytes) {
-            if (nbytes == 0)
-                return 0;
+        if (off > buf.length || nbytes < 0 || off < 0
+                || buf.length - off < nbytes) {
+            throw new ArrayIndexOutOfBoundsException();
+        }
+
+        if (nbytes == 0) {
+            return 0;
+        }
 
-            if (streamHandle == -1) {
-                throw new IllegalStateException();
-            }
-
-            if (!pass_magic_number_check) {
-                throw new DataFormatException();
-            }
-
-            if (needsInput()) {
-                return 0;
-            }
-
-            boolean neededDict = needsDictionary;
-            needsDictionary = false;
-            int result = inflateImpl(buf, off, nbytes, streamHandle);
-            if (needsDictionary && neededDict) {
-                throw new DataFormatException(Messages.getString("archive.27")); //$NON-NLS-1$
-            }
-            return result;
+        if (streamHandle == -1) {
+            throw new IllegalStateException();
+        }
+
+        if (needsInput()) {
+            return 0;
         }
-        throw new ArrayIndexOutOfBoundsException();
+
+        boolean neededDict = needsDictionary;
+        needsDictionary = false;
+        int result = inflateImpl(buf, off, nbytes, streamHandle);
+        if (needsDictionary && neededDict) {
+            throw new DataFormatException(
+                    Messages.getString("archive.27")); //$NON-NLS-1$
+        }
+
+        return result;
     }
 
     private native synchronized int inflateImpl(byte[] buf, int off,
@@ -275,7 +268,7 @@
      * determine whether a dictionary is required. If so {@code setDictionary()}
      * should be called with the appropriate dictionary prior to calling {@code
      * inflate()}.
-     * 
+     *
      * @return {@code true} if a preset dictionary is required for inflation.
      * @see #setDictionary(byte[])
      * @see #setDictionary(byte[], int, int)
@@ -286,7 +279,7 @@
 
     /**
      * Indicates that input has to be passed to the inflater.
-     * 
+     *
      * @return {@code true} if {@code setInput} has to be called before
      *         inflation can proceed.
      * @see #setInput(byte[])
@@ -315,7 +308,7 @@
      * Sets the preset dictionary to be used for inflation to {@code buf}.
      * {@code needsDictionary()} can be called to determine whether the current
      * input was deflated using a preset dictionary.
-     * 
+     *
      * @param buf
      *            The buffer containing the dictionary bytes.
      * @see #needsDictionary
@@ -331,7 +324,7 @@
      * The dictionary should be set if the {@link #inflate(byte[])} returned
      * zero bytes inflated and {@link #needsDictionary()} returns
      * <code>true</code>.
-     * 
+     *
      * @param buf
      *            the buffer containing the dictionary data bytes.
      * @param off
@@ -359,7 +352,7 @@
     /**
      * Sets the current input to to be decrompressed. This method should only be
      * called if {@code needsInput()} returns {@code true}.
-     * 
+     *
      * @param buf
      *            the input buffer.
      * @see #needsInput
@@ -373,7 +366,7 @@
      * {@code off} and ending at {@code nbytes - 1} where data is written after
      * decompression. This method should only be called if {@code needsInput()}
      * returns {@code true}.
-     * 
+     *
      * @param buf
      *            the input buffer.
      * @param off
@@ -395,11 +388,6 @@
         } else {
             throw new ArrayIndexOutOfBoundsException();
         }
-
-        if (!gotFirstHeaderByte && nbytes > 0) {
-            pass_magic_number_check = (buf[off] == MAGIC_NUMBER);
-            gotFirstHeaderByte = true;
-        }
     }
 
     private native synchronized void setInputImpl(byte[] buf, int off,

Modified: harmony/enhanced/classlib/branches/java6/modules/archive/src/main/java/java/util/zip/InflaterInputStream.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/archive/src/main/java/java/util/zip/InflaterInputStream.java?rev=824184&r1=824183&r2=824184&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/archive/src/main/java/java/util/zip/InflaterInputStream.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/archive/src/main/java/java/util/zip/InflaterInputStream.java Sun Oct 11 21:59:47 2009
@@ -1,13 +1,13 @@
-/* 
+/*
  * Licensed to the Apache Software Foundation (ASF) under one or more
  * contributor license agreements.  See the NOTICE file distributed with
  * this work for additional information regarding copyright ownership.
  * The ASF licenses this file to You under the Apache License, Version 2.0
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
- * 
+ *
  *     http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -30,7 +30,7 @@
  * (see <a href="http://www.gzip.org/algorithm.txt">specification</a>).
  * Basically it wraps the {@code Inflater} class and takes care of the
  * buffering.
- * 
+ *
  * @see Inflater
  * @see DeflaterOutputStream
  */
@@ -53,6 +53,11 @@
 
     boolean closed;
 
+    /**
+     * True if this stream's last byte has been returned to the user. This
+     * could be because the underlying stream has been exhausted, or if errors
+     * were encountered while inflating that stream.
+     */
     boolean eof;
 
     static final int BUF_SIZE = 512;
@@ -62,7 +67,7 @@
      * InputStream} from which the compressed data is to be read from. Default
      * settings for the {@code Inflater} and internal buffer are be used. In
      * particular the Inflater expects a ZLIB header from the input stream.
-     * 
+     *
      * @param is
      *            the {@code InputStream} to read data from.
      */
@@ -73,7 +78,7 @@
     /**
      * This constructor lets you pass a specifically initialized Inflater,
      * for example one that expects no ZLIB header.
-     * 
+     *
      * @param is
      *            the {@code InputStream} to read data from.
      * @param inf
@@ -86,7 +91,7 @@
     /**
      * This constructor lets you specify both the {@code Inflater} as well as
      * the internal buffer size to be used.
-     * 
+     *
      * @param is
      *            the {@code InputStream} to read data from.
      * @param inf
@@ -108,7 +113,7 @@
 
     /**
      * Reads a single byte of decompressed data.
-     * 
+     *
      * @return the byte read.
      * @throws IOException
      *             if an error occurs reading the byte.
@@ -125,7 +130,7 @@
     /**
      * Reads up to {@code nbytes} of decompressed data and stores it in
      * {@code buffer} starting at {@code off}.
-     * 
+     *
      * @param buffer
      *            the buffer to write data to.
      * @param off
@@ -155,41 +160,45 @@
             return 0;
         }
 
-        if (inf.finished()) {
-            eof = true;
+        if (eof) {
             return -1;
         }
 
         // avoid int overflow, check null buffer
-        if (off <= buffer.length && nbytes >= 0 && off >= 0
-                && buffer.length - off >= nbytes) {
-            do {
-                if (inf.needsInput()) {
-                    fill();
-                }
-                int result;
-                try {
-                    result = inf.inflate(buffer, off, nbytes);
-                } catch (DataFormatException e) {
-                    if (len == -1) {
-                        throw new EOFException();
-                    }
-                    throw (IOException) (new IOException().initCause(e));
-                }
+        if (off > buffer.length || nbytes < 0 || off < 0
+                || buffer.length - off < nbytes) {
+            throw new ArrayIndexOutOfBoundsException();
+        }
+
+        do {
+            if (inf.needsInput()) {
+                fill();
+            }
+            // Invariant: if reading returns -1 or throws, eof must be true.
+            // It may also be true if the next read() should return -1.
+            try {
+                int result = inf.inflate(buffer, off, nbytes);
+                eof = inf.finished();
                 if (result > 0) {
                     return result;
-                } else if (inf.finished()) {
-                    eof = true;
+                } else if (eof) {
                     return -1;
                 } else if (inf.needsDictionary()) {
+                    eof = true;
                     return -1;
                 } else if (len == -1) {
+                    eof = true;
                     throw new EOFException();
                     // If result == 0, fill() and try again
                 }
-            } while (true);
-        }
-        throw new ArrayIndexOutOfBoundsException();
+            } catch (DataFormatException e) {
+                eof = true;
+                if (len == -1) {
+                    throw new EOFException();
+                }
+                throw (IOException) (new IOException().initCause(e));
+            }
+        } while (true);
     }
 
     /**
@@ -209,7 +218,7 @@
 
     /**
      * Skips up to n bytes of uncompressed data.
-     * 
+     *
      * @param nbytes
      *            the number of bytes to skip.
      * @return the number of uncompressed bytes skipped.
@@ -219,13 +228,15 @@
     @Override
     public long skip(long nbytes) throws IOException {
         if (nbytes >= 0) {
+            if (buf == null) {
+                buf = new byte[(int)Math.min(nbytes, BUF_SIZE)];
+            }
             long count = 0, rem = 0;
             while (count < nbytes) {
                 int x = read(buf, 0,
                         (rem = nbytes - count) > buf.length ? buf.length
                                 : (int) rem);
                 if (x == -1) {
-                    eof = true;
                     return count;
                 }
                 count += x;
@@ -236,9 +247,18 @@
     }
 
     /**
-     * Returns whether data can be read from this stream.
-     * 
-     * @return 0 if this stream has been closed, 1 otherwise.
+     * Returns 0 when when this stream has exhausted its input; and 1 otherwise.
+     * A result of 1 does not guarantee that further bytes can be returned,
+     * with or without blocking.
+     *
+     * <p>Although consistent with the RI, this behavior is inconsistent with
+     * {@link InputStream#available()}, and violates the <a
+     * href="http://en.wikipedia.org/wiki/Liskov_substitution_principle">Liskov
+     * Substitution Principle</a>. This method should not be used.
+     *
+     * @return 0 if no further bytes are available. Otherwise returns 1,
+     *         which suggests (but does not guarantee) that additional bytes are
+     *         available.
      * @throws IOException
      *             If an error occurs.
      */
@@ -256,7 +276,7 @@
 
     /**
      * Closes the input stream.
-     * 
+     *
      * @throws IOException
      *             If an error occurs closing the input stream.
      */
@@ -273,7 +293,7 @@
     /**
      * Marks the current position in the stream. This implementation overrides
      * the super type implementation to do nothing at all.
-     * 
+     *
      * @param readlimit
      *            of no use.
      */
@@ -298,7 +318,7 @@
     /**
      * Returns whether the receiver implements {@code mark} semantics. This type
      * does not support {@code mark()}, so always responds {@code false}.
-     * 
+     *
      * @return false, always
      */
     @Override

Modified: harmony/enhanced/classlib/branches/java6/modules/archive/src/main/java/java/util/zip/ZipConstants.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/archive/src/main/java/java/util/zip/ZipConstants.java?rev=824184&r1=824183&r2=824184&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/archive/src/main/java/java/util/zip/ZipConstants.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/archive/src/main/java/java/util/zip/ZipConstants.java Sun Oct 11 21:59:47 2009
@@ -1,13 +1,13 @@
-/* 
+/*
  * Licensed to the Apache Software Foundation (ASF) under one or more
  * contributor license agreements.  See the NOTICE file distributed with
  * this work for additional information regarding copyright ownership.
  * The ASF licenses this file to You under the Apache License, Version 2.0
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
- * 
+ *
  *     http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

Modified: harmony/enhanced/classlib/branches/java6/modules/archive/src/main/java/java/util/zip/ZipEntry.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/archive/src/main/java/java/util/zip/ZipEntry.java?rev=824184&r1=824183&r2=824184&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/archive/src/main/java/java/util/zip/ZipEntry.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/archive/src/main/java/java/util/zip/ZipEntry.java Sun Oct 11 21:59:47 2009
@@ -1,13 +1,13 @@
-/* 
+/*
  * Licensed to the Apache Software Foundation (ASF) under one or more
  * contributor license agreements.  See the NOTICE file distributed with
  * this work for additional information regarding copyright ownership.
  * The ASF licenses this file to You under the Apache License, Version 2.0
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
- * 
+ *
  *     http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -17,6 +17,11 @@
 
 package java.util.zip;
 
+import java.io.EOFException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.RandomAccessFile;
+import java.io.UnsupportedEncodingException;
 import java.util.Calendar;
 import java.util.Date;
 import java.util.GregorianCalendar;
@@ -28,19 +33,22 @@
  * itself. For example when reading a <i>ZIP-file</i> you will first retrieve
  * all its entries in a collection and then read the data for a specific entry
  * through an input stream.
- * 
+ *
  * @see ZipFile
  * @see ZipOutputStream
  */
 public class ZipEntry implements ZipConstants, Cloneable {
     String name, comment;
 
-    long compressedSize = -1, crc = -1, size = -1, dataOffset = -1;
+    long compressedSize = -1, crc = -1, size = -1;
 
     int compressionMethod = -1, time = -1, modDate = -1;
 
     byte[] extra;
 
+    int nameLen = -1;
+    long mLocalHeaderRelOffset = -1;
+
     /**
      * Zip entry state: Deflated.
      */
@@ -53,7 +61,7 @@
 
     /**
      * Constructs a new {@code ZipEntry} with the specified name.
-     * 
+     *
      * @param name
      *            the name of the ZIP entry.
      * @throws IllegalArgumentException
@@ -71,7 +79,7 @@
 
     /**
      * Gets the comment for this {@code ZipEntry}.
-     * 
+     *
      * @return the comment for this {@code ZipEntry}, or {@code null} if there
      *         is no comment. If we're reading an archive with
      *         {@code ZipInputStream} the comment is not available.
@@ -82,7 +90,7 @@
 
     /**
      * Gets the compressed size of this {@code ZipEntry}.
-     * 
+     *
      * @return the compressed size, or -1 if the compressed size has not been
      *         set.
      */
@@ -92,7 +100,7 @@
 
     /**
      * Gets the checksum for this {@code ZipEntry}.
-     * 
+     *
      * @return the checksum, or -1 if the checksum has not been set.
      */
     public long getCrc() {
@@ -101,7 +109,7 @@
 
     /**
      * Gets the extra information for this {@code ZipEntry}.
-     * 
+     *
      * @return a byte array containing the extra information, or {@code null} if
      *         there is none.
      */
@@ -111,7 +119,7 @@
 
     /**
      * Gets the compression method for this {@code ZipEntry}.
-     * 
+     *
      * @return the compression method, either {@code DEFLATED}, {@code STORED}
      *         or -1 if the compression method has not been set.
      */
@@ -121,7 +129,7 @@
 
     /**
      * Gets the name of this {@code ZipEntry}.
-     * 
+     *
      * @return the entry name.
      */
     public String getName() {
@@ -130,7 +138,7 @@
 
     /**
      * Gets the uncompressed size of this {@code ZipEntry}.
-     * 
+     *
      * @return the uncompressed size, or {@code -1} if the size has not been
      *         set.
      */
@@ -140,7 +148,7 @@
 
     /**
      * Gets the last modification time of this {@code ZipEntry}.
-     * 
+     *
      * @return the last modification time as the number of milliseconds since
      *         Jan. 1, 1970.
      */
@@ -158,7 +166,7 @@
 
     /**
      * Determine whether or not this {@code ZipEntry} is a directory.
-     * 
+     *
      * @return {@code true} when this {@code ZipEntry} is a directory, {@code
      *         false} otherwise.
      */
@@ -168,7 +176,7 @@
 
     /**
      * Sets the comment for this {@code ZipEntry}.
-     * 
+     *
      * @param string
      *            the comment for this entry.
      */
@@ -182,7 +190,7 @@
 
     /**
      * Sets the compressed size for this {@code ZipEntry}.
-     * 
+     *
      * @param value
      *            the compressed size (in bytes).
      */
@@ -192,7 +200,7 @@
 
     /**
      * Sets the checksum for this {@code ZipEntry}.
-     * 
+     *
      * @param value
      *            the checksum for this entry.
      * @throws IllegalArgumentException
@@ -208,7 +216,7 @@
 
     /**
      * Sets the extra information for this {@code ZipEntry}.
-     * 
+     *
      * @param data
      *            a byte array containing the extra information.
      * @throws IllegalArgumentException
@@ -224,7 +232,7 @@
 
     /**
      * Sets the compression method for this {@code ZipEntry}.
-     * 
+     *
      * @param value
      *            the compression method, either {@code DEFLATED} or {@code
      *            STORED}.
@@ -240,7 +248,7 @@
 
     /**
      * Sets the uncompressed size of this {@code ZipEntry}.
-     * 
+     *
      * @param value
      *            the uncompressed size for this entry.
      * @throws IllegalArgumentException
@@ -256,7 +264,7 @@
 
     /**
      * Sets the modification time of this {@code ZipEntry}.
-     * 
+     *
      * @param value
      *            the modification time as the number of milliseconds since Jan.
      *            1, 1970.
@@ -280,7 +288,7 @@
 
     /**
      * Returns the string representation of this {@code ZipEntry}.
-     * 
+     *
      * @return the string representation of this {@code ZipEntry}.
      */
     @Override
@@ -288,25 +296,10 @@
         return name;
     }
 
-    ZipEntry(String name, String comment, byte[] extra, long modTime,
-            long size, long compressedSize, long crc, int compressionMethod,
-            long modDate, long offset) {
-        this.name = name;
-        this.comment = comment;
-        this.extra = extra;
-        time = (int) modTime;
-        this.size = size;
-        this.compressedSize = compressedSize;
-        this.crc = crc;
-        this.compressionMethod = compressionMethod;
-        this.modDate = (int) modDate;
-        dataOffset = offset;
-    }
-
     /**
      * Constructs a new {@code ZipEntry} using the values obtained from {@code
      * ze}.
-     * 
+     *
      * @param ze
      *            the {@code ZipEntry} from which to obtain values.
      */
@@ -320,12 +313,13 @@
         compressionMethod = ze.compressionMethod;
         modDate = ze.modDate;
         extra = ze.extra;
-        dataOffset = ze.dataOffset;
+        nameLen = ze.nameLen;
+        mLocalHeaderRelOffset = ze.mLocalHeaderRelOffset;
     }
 
     /**
      * Returns a shallow copy of this entry.
-     * 
+     *
      * @return a copy of this entry.
      */
     @Override
@@ -335,11 +329,153 @@
 
     /**
      * Returns the hash code for this {@code ZipEntry}.
-     * 
+     *
      * @return the hash code of the entry.
      */
     @Override
     public int hashCode() {
         return name.hashCode();
     }
+
+    /*
+     * Internal constructor.  Creates a new ZipEntry by reading the
+     * Central Directory Entry from "in", which must be positioned at
+     * the CDE signature.
+     *
+     * On exit, "in" will be positioned at the start of the next entry.
+     */
+    ZipEntry(LittleEndianReader ler, InputStream in) throws IOException {
+
+        /*
+         * We're seeing performance issues when we call readShortLE and
+         * readIntLE, so we're going to read the entire header at once
+         * and then parse the results out without using any function calls.
+         * Uglier, but should be much faster.
+         *
+         * Note that some lines look a bit different, because the corresponding
+         * fields or locals are long and so we need to do & 0xffffffffl to avoid
+         * problems induced by sign extension.
+         */
+
+        byte[] hdrBuf = ler.hdrBuf;
+        myReadFully(in, hdrBuf);
+
+        long sig = (hdrBuf[0] & 0xff) | ((hdrBuf[1] & 0xff) << 8) |
+            ((hdrBuf[2] & 0xff) << 16) | ((hdrBuf[3] << 24) & 0xffffffffL);
+        if (sig != CENSIG) {
+             throw new ZipException("Central Directory Entry not found");
+        }
+
+        compressionMethod = (hdrBuf[10] & 0xff) | ((hdrBuf[11] & 0xff) << 8);
+        time = (hdrBuf[12] & 0xff) | ((hdrBuf[13] & 0xff) << 8);
+        modDate = (hdrBuf[14] & 0xff) | ((hdrBuf[15] & 0xff) << 8);
+        crc = (hdrBuf[16] & 0xff) | ((hdrBuf[17] & 0xff) << 8)
+                | ((hdrBuf[18] & 0xff) << 16)
+                | ((hdrBuf[19] << 24) & 0xffffffffL);
+        compressedSize = (hdrBuf[20] & 0xff) | ((hdrBuf[21] & 0xff) << 8)
+                | ((hdrBuf[22] & 0xff) << 16)
+                | ((hdrBuf[23] << 24) & 0xffffffffL);
+        size = (hdrBuf[24] & 0xff) | ((hdrBuf[25] & 0xff) << 8)
+                | ((hdrBuf[26] & 0xff) << 16)
+                | ((hdrBuf[27] << 24) & 0xffffffffL);
+        nameLen = (hdrBuf[28] & 0xff) | ((hdrBuf[29] & 0xff) << 8);
+        int extraLen = (hdrBuf[30] & 0xff) | ((hdrBuf[31] & 0xff) << 8);
+        int commentLen = (hdrBuf[32] & 0xff) | ((hdrBuf[33] & 0xff) << 8);
+        mLocalHeaderRelOffset = (hdrBuf[42] & 0xff) | ((hdrBuf[43] & 0xff) << 8)
+                | ((hdrBuf[44] & 0xff) << 16)
+                | ((hdrBuf[45] << 24) & 0xffffffffL);
+
+        byte[] nameBytes = new byte[nameLen];
+        myReadFully(in, nameBytes);
+
+        byte[] commentBytes = null;
+        if (commentLen > 0) {
+            commentBytes = new byte[commentLen];
+            myReadFully(in, commentBytes);
+        }
+
+        if (extraLen > 0) {
+            extra = new byte[extraLen];
+            myReadFully(in, extra);
+        }
+
+        try {
+            /*
+             * The actual character set is "IBM Code Page 437".  As of
+             * Sep 2006, the Zip spec (APPNOTE.TXT) supports UTF-8.  When
+             * bit 11 of the GP flags field is set, the file name and
+             * comment fields are UTF-8.
+             *
+             * TODO: add correct UTF-8 support.
+             */
+            name = new String(nameBytes, "ISO-8859-1");
+            if (commentBytes != null) {
+                comment = new String(commentBytes, "ISO-8859-1");
+            } else {
+                comment = null;
+            }
+        } catch (UnsupportedEncodingException uee) {
+            throw new InternalError(uee.getMessage());
+        }
+    }
+
+    private void myReadFully(InputStream in, byte[] b) throws IOException {
+        int len = b.length;
+        int off = 0;
+
+        while (len > 0) {
+            int count = in.read(b, off, len);
+            if (count <= 0) {
+                throw new EOFException();
+            }
+            off += count;
+            len -= count;
+        }
+    }
+
+    /*
+     * Read a four-byte int in little-endian order.
+     */
+    static long readIntLE(RandomAccessFile raf) throws IOException {
+        int b0 = raf.read();
+        int b1 = raf.read();
+        int b2 = raf.read();
+        int b3 = raf.read();
+
+        if (b3 < 0) {
+            throw new EOFException("in ZipEntry.readIntLE(RandomAccessFile)");
+        }
+        return b0 | (b1 << 8) | (b2 << 16) | (b3 << 24); // ATTENTION: DOES SIGN EXTENSION: IS THIS WANTED?
+    }
+
+    static class LittleEndianReader {
+        private byte[] b = new byte[4];
+        byte[] hdrBuf = new byte[CENHDR];
+
+        /*
+         * Read a two-byte short in little-endian order.
+         */
+        int readShortLE(InputStream in) throws IOException {
+            if (in.read(b, 0, 2) == 2) {
+                return (b[0] & 0XFF) | ((b[1] & 0XFF) << 8);
+            } else {
+                throw new EOFException("in ZipEntry.readShortLE(InputStream)");
+            }
+        }
+
+        /*
+         * Read a four-byte int in little-endian order.
+         */
+        long readIntLE(InputStream in) throws IOException {
+            if (in.read(b, 0, 4) == 4) {
+                return (   ((b[0] & 0XFF))
+                         | ((b[1] & 0XFF) << 8)
+                         | ((b[2] & 0XFF) << 16)
+                         | ((b[3] & 0XFF) << 24))
+                       & 0XFFFFFFFFL; // Here for sure NO sign extension is wanted.
+            } else {
+                throw new EOFException("in ZipEntry.readIntLE(InputStream)");
+            }
+        }
+    }
 }

Modified: harmony/enhanced/classlib/branches/java6/modules/archive/src/main/java/java/util/zip/ZipException.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/archive/src/main/java/java/util/zip/ZipException.java?rev=824184&r1=824183&r2=824184&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/archive/src/main/java/java/util/zip/ZipException.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/archive/src/main/java/java/util/zip/ZipException.java Sun Oct 11 21:59:47 2009
@@ -1,13 +1,13 @@
-/* 
+/*
  * Licensed to the Apache Software Foundation (ASF) under one or more
  * contributor license agreements.  See the NOTICE file distributed with
  * this work for additional information regarding copyright ownership.
  * The ASF licenses this file to You under the Apache License, Version 2.0
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
- * 
+ *
  *     http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -22,7 +22,7 @@
 /**
  * This runtime exception is thrown by {@code ZipFile} and {@code
  * ZipInputStream} when the file or stream is not a valid ZIP file.
- * 
+ *
  * @see ZipFile
  * @see ZipInputStream
  */

Modified: harmony/enhanced/classlib/branches/java6/modules/archive/src/main/java/java/util/zip/ZipFile.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/archive/src/main/java/java/util/zip/ZipFile.java?rev=824184&r1=824183&r2=824184&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/archive/src/main/java/java/util/zip/ZipFile.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/archive/src/main/java/java/util/zip/ZipFile.java Sun Oct 11 21:59:47 2009
@@ -1,13 +1,13 @@
-/* 
+/*
  * Licensed to the Apache Software Foundation (ASF) under one or more
  * contributor license agreements.  See the NOTICE file distributed with
  * this work for additional information regarding copyright ownership.
  * The ASF licenses this file to You under the Apache License, Version 2.0
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
- * 
+ *
  *     http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -17,17 +17,16 @@
 
 package java.util.zip;
 
-import java.io.ByteArrayInputStream;
+import java.io.BufferedInputStream;
 import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
+import java.io.RandomAccessFile;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
 import java.util.Enumeration;
-import java.util.NoSuchElementException;
-
-import org.apache.harmony.archive.internal.nls.Messages;
-import org.apache.harmony.luni.util.Util;
+import java.util.LinkedHashMap;
+import java.util.Iterator;
 
 /**
  * This class provides random read access to a <i>ZIP-archive</i> file.
@@ -39,37 +38,36 @@
  * Use {@code ZipOutputStream} if you want to create an archive.
  * <p>
  * A temporary ZIP file can be marked for automatic deletion upon closing it.
- * 
+ *
  * @see ZipEntry
  * @see ZipOutputStream
  */
 public class ZipFile implements ZipConstants {
 
-    String fileName;
-
-    long descriptor = -1;
-
-    private int size = -1;
-
-    private int mode;
-    static {
-        System.loadLibrary("hyarchive"); //$NON-NLS-1$
-        ntvinit();
-    }
-
     /**
-     * Open zip file for read.
+     * Open ZIP file for read.
      */
     public static final int OPEN_READ = 1;
 
     /**
-     * Delete zip file when closed.
+     * Delete ZIP file when closed.
      */
     public static final int OPEN_DELETE = 4;
 
+    private final String fileName;
+
+    private File fileToDeleteOnClose;
+
+    private RandomAccessFile mRaf;
+
+    private final ZipEntry.LittleEndianReader ler = new ZipEntry.LittleEndianReader();
+
+    private final LinkedHashMap<String, ZipEntry> mEntries
+            = new LinkedHashMap<String, ZipEntry>();
+
     /**
      * Constructs a new {@code ZipFile} with the specified file.
-     * 
+     *
      * @param file
      *            the file to read from.
      * @throws ZipException
@@ -78,14 +76,14 @@
      *             if an {@code IOException} occurs.
      */
     public ZipFile(File file) throws ZipException, IOException {
-        this(file.getPath());
+        this(file, OPEN_READ);
     }
 
     /**
      * Opens a file as <i>ZIP-archive</i>. "mode" must be {@code OPEN_READ} or
      * {@code OPEN_DELETE} . The latter sets the "delete on exit" flag through a
      * file.
-     * 
+     *
      * @param file
      *            the ZIP file to read.
      * @param mode
@@ -94,54 +92,39 @@
      *             if an {@code IOException} occurs.
      */
     public ZipFile(File file, int mode) throws IOException {
-        if (mode == OPEN_READ || mode == (OPEN_READ | OPEN_DELETE)) {
-            fileName = file.getPath();
-            SecurityManager security = System.getSecurityManager();
+        fileName = file.getPath();
+        if (mode != OPEN_READ && mode != (OPEN_READ | OPEN_DELETE)) {
+            throw new IllegalArgumentException();
+        }
+
+        SecurityManager security = System.getSecurityManager();
+        if (security != null) {
+            security.checkRead(fileName);
+        }
+        if ((mode & OPEN_DELETE) != 0) {
             if (security != null) {
-                security.checkRead(fileName);
-                if ((mode & OPEN_DELETE) != 0) {
-                    security.checkDelete(fileName);
-                }
+                security.checkDelete(fileName);
             }
-            this.mode = mode;
-            openZip();
+            fileToDeleteOnClose = file; // file.deleteOnExit();
         } else {
-            throw new IllegalArgumentException();
+            fileToDeleteOnClose = null;
         }
+
+        mRaf = new RandomAccessFile(fileName, "r");
+
+        readCentralDir();
     }
 
     /**
      * Opens a ZIP archived file.
-     * 
+     *
      * @param name
      *            the name of the ZIP file.
      * @throws IOException
      *             if an IOException occurs.
      */
     public ZipFile(String name) throws IOException {
-        SecurityManager security = System.getSecurityManager();
-        if (security != null) {
-            security.checkRead(name);
-        }
-        fileName = name;
-        openZip();
-    }
-
-    private void openZip() throws IOException {
-        int result = openZipImpl(Util.getUTF8Bytes(fileName));
-
-        if (result != 0) {
-            switch (result) {
-            case 1:
-                throw new ZipException(Messages.getString(
-                        "archive.24", fileName)); //$NON-NLS-1$
-            case 2:
-                throw new ZipException(Messages.getString(
-                        "archive.25", fileName)); //$NON-NLS-1$
-            default:
-                throw new OutOfMemoryError();
-            }
-        }
+        this(new File(name), OPEN_READ);
     }
 
     @Override
@@ -150,148 +133,286 @@
     }
 
     /**
-     * Closes this ZIP file.
-     * 
+     * Closes this ZIP file. This method is idempotent.
+     *
      * @throws IOException
      *             if an IOException occurs.
      */
-    public synchronized void close() throws IOException {
-        if (descriptor != -1 && fileName != null) {
-            // Only close initialized instances
-            closeZipImpl(descriptor);
-            if ((mode & OPEN_DELETE) != 0) {
+    public void close() throws IOException {
+        RandomAccessFile raf = mRaf;
+
+        if (raf != null) { // Only close initialized instances
+            synchronized(raf) {
+                mRaf = null;
+                raf.close();
+            }
+            if (fileToDeleteOnClose != null) {
                 AccessController.doPrivileged(new PrivilegedAction<Object>() {
                     public Object run() {
                         new File(fileName).delete();
                         return null;
                     }
                 });
+                // fileToDeleteOnClose.delete();
+                fileToDeleteOnClose = null;
             }
         }
     }
 
+    private void checkNotClosed() {
+        if (mRaf == null) {
+            throw new IllegalStateException("Zip File closed.");
+        }
+    }
+
     /**
      * Returns an enumeration of the entries. The entries are listed in the
      * order in which they appear in the ZIP archive.
-     * 
+     *
      * @return the enumeration of the entries.
+     * @throws IllegalStateException if this ZIP file has been closed.
      */
     public Enumeration<? extends ZipEntry> entries() {
-        return new ZFEnum<ZipEntry>();
+        checkNotClosed();
+        final Iterator<ZipEntry> iterator = mEntries.values().iterator();
+
+        return new Enumeration<ZipEntry>() {
+            public boolean hasMoreElements() {
+                checkNotClosed();
+                return iterator.hasNext();
+            }
+
+            public ZipEntry nextElement() {
+                checkNotClosed();
+                return iterator.next();
+            }
+        };
     }
 
     /**
      * Gets the ZIP entry with the specified name from this {@code ZipFile}.
-     * 
+     *
      * @param entryName
      *            the name of the entry in the ZIP file.
      * @return a {@code ZipEntry} or {@code null} if the entry name does not
      *         exist in the ZIP file.
+     * @throws IllegalStateException if this ZIP file has been closed.
      */
     public ZipEntry getEntry(String entryName) {
-        if (entryName != null) {
-            ZipEntry entry = getEntryImpl(descriptor, entryName);
-            return entry;
+        checkNotClosed();
+        if (entryName == null) {
+            throw new NullPointerException();
+        }
+
+        ZipEntry ze = mEntries.get(entryName);
+        if (ze == null) {
+            ze = mEntries.get(entryName + "/");
         }
-        throw new NullPointerException();
+        return ze;
     }
 
     /**
      * Returns an input stream on the data of the specified {@code ZipEntry}.
-     * 
+     *
      * @param entry
      *            the ZipEntry.
      * @return an input stream of the data contained in the {@code ZipEntry}.
      * @throws IOException
      *             if an {@code IOException} occurs.
+     * @throws IllegalStateException if this ZIP file has been closed.
      */
     public InputStream getInputStream(ZipEntry entry) throws IOException {
-        if (descriptor == -1) {
-            /*
-             * the descriptor is set to -1 by native code to indicate the zip
-             * was closed
-             */
-            throw new IllegalStateException();
-        }
-        byte[] buf = inflateEntryImpl2(descriptor, entry.getName());
-        if (buf == null) {
+        /*
+         * Make sure this ZipEntry is in this Zip file.  We run it through
+         * the name lookup.
+         */
+        entry = getEntry(entry.getName());
+        if (entry == null) {
             return null;
         }
-        return new ByteArrayInputStream(buf);
+
+        /*
+         * Create a ZipInputStream at the right part of the file.
+         */
+        RandomAccessFile raf = mRaf;
+        synchronized (raf) {
+            // We don't know the entry data's start position. All we have is the
+            // position of the entry's local header. At position 28 we find the
+            // length of the extra data. In some cases this length differs from
+            // the one coming in the central header.
+            RAFStream rafstrm = new RAFStream(raf,
+                    entry.mLocalHeaderRelOffset + 28);
+            int localExtraLenOrWhatever = ler.readShortLE(rafstrm);
+            // Skip the name and this "extra" data or whatever it is:
+            rafstrm.skip(entry.nameLen + localExtraLenOrWhatever);
+            rafstrm.mLength = rafstrm.mOffset + entry.compressedSize;
+            if (entry.compressionMethod == ZipEntry.DEFLATED) {
+                return new InflaterInputStream(rafstrm, new Inflater(true));
+            } else {
+                return rafstrm;
+            }
+        }
     }
 
     /**
      * Gets the file name of this {@code ZipFile}.
-     * 
+     *
      * @return the file name of this {@code ZipFile}.
      */
     public String getName() {
         return fileName;
     }
 
-    private synchronized native int openZipImpl(byte[] fileName1);
-
-    private native void closeZipImpl(long descriptor1) throws IOException;
-
-    private native ZipEntry getEntryImpl(long descriptor1, String entryName);
-
-    private native byte[] inflateEntryImpl2(long descriptor1, String entryName)
-            throws ZipException;
-
     /**
      * Returns the number of {@code ZipEntries} in this {@code ZipFile}.
-     * 
+     *
      * @return the number of entries in this file.
+     * @throws IllegalStateException if this ZIP file has been closed.
      */
     public int size() {
-        if (size != -1) {
-            return size;
-        }
-
-        size = 0;
-        Enumeration<?> e = entries();
-        while (e.hasMoreElements()) {
-            size++;
-            e.nextElement();
-        }
-        return size;
-
+        checkNotClosed();
+        return mEntries.size();
     }
 
-    private static native void ntvinit();
-
-    class ZFEnum<T extends ZipEntry> implements Enumeration<T> {
-        private final long nextEntryPointer;
-
-        private T current;
+    /**
+     * Find the central directory and read the contents.
+     *
+     * <p>The central directory can be followed by a variable-length comment
+     * field, so we have to scan through it backwards.  The comment is at
+     * most 64K, plus we have 18 bytes for the end-of-central-dir stuff
+     * itself, plus apparently sometimes people throw random junk on the end
+     * just for the fun of it.
+     *
+     * <p>This is all a little wobbly.  If the wrong value ends up in the EOCD
+     * area, we're hosed. This appears to be the way that everybody handles
+     * it though, so we're in good company if this fails.
+     */
+    private void readCentralDir() throws IOException {
+        /*
+         * Scan back, looking for the End Of Central Directory field.  If
+         * the archive doesn't have a comment, we'll hit it on the first
+         * try.
+         *
+         * No need to synchronize mRaf here -- we only do this when we
+         * first open the Zip file.
+         */
+        long scanOffset = mRaf.length() - ENDHDR;
+        if (scanOffset < 0) {
+            throw new ZipException("too short to be Zip");
+        }
+
+        long stopOffset = scanOffset - 65536;
+        if (stopOffset < 0) {
+            stopOffset = 0;
+        }
+
+        while (true) {
+            mRaf.seek(scanOffset);
+            if (ZipEntry.readIntLE(mRaf) == 101010256L) {
+                break;
+            }
 
-        ZFEnum() {
-            nextEntryPointer = resetZip(descriptor);
-            current = getNextEntry(descriptor, nextEntryPointer);
+            scanOffset--;
+            if (scanOffset < stopOffset) {
+                throw new ZipException("EOCD not found; not a Zip archive?");
+            }
         }
 
-        private native long resetZip(long descriptor1);
-
-        private native T getNextEntry(long descriptor1, long nextEntryPointer1);
+        /*
+         * Found it, read the EOCD.
+         *
+         * For performance we want to use buffered I/O when reading the
+         * file.  We wrap a buffered stream around the random-access file
+         * object.  If we just read from the RandomAccessFile we'll be
+         * doing a read() system call every time.
+         */
+        RAFStream rafs = new RAFStream(mRaf, mRaf.getFilePointer());
+        BufferedInputStream bin = new BufferedInputStream(rafs, ENDHDR);
+
+        int diskNumber = ler.readShortLE(bin);
+        int diskWithCentralDir = ler.readShortLE(bin);
+        int numEntries = ler.readShortLE(bin);
+        int totalNumEntries = ler.readShortLE(bin);
+        /*centralDirSize =*/ ler.readIntLE(bin);
+        long centralDirOffset = ler.readIntLE(bin);
+        /*commentLen =*/ ler.readShortLE(bin);
+
+        if (numEntries != totalNumEntries ||
+            diskNumber != 0 ||
+            diskWithCentralDir != 0) {
+            throw new ZipException("spanned archives not supported");
+        }
+
+        /*
+         * Seek to the first CDE and read all entries.
+         */
+        rafs = new RAFStream(mRaf, centralDirOffset);
+        bin = new BufferedInputStream(rafs, 4096);
+        for (int i = 0; i < numEntries; i++) {
+            ZipEntry newEntry = new ZipEntry(ler, bin);
+            mEntries.put(newEntry.getName(), newEntry);
+        }
+    }
+
+    /**
+     * Wrap a stream around a RandomAccessFile.  The RandomAccessFile is shared
+     * among all streams returned by getInputStream(), so we have to synchronize
+     * access to it.  (We can optimize this by adding buffering here to reduce
+     * collisions.)
+     *
+     * <p>We could support mark/reset, but we don't currently need them.
+     */
+    static class RAFStream extends InputStream {
+
+        RandomAccessFile mSharedRaf;
+        long mOffset;
+        long mLength;
+        private byte[] singleByteBuf = new byte[1];
+
+        public RAFStream(RandomAccessFile raf, long pos) throws IOException {
+            mSharedRaf = raf;
+            mOffset = pos;
+            mLength = raf.length();
+        }
+
+        @Override
+        public int available() throws IOException {
+            return (mOffset < mLength ? 1 : 0);
+        }
+
+        @Override
+        public int read() throws IOException {
+            if (read(singleByteBuf, 0, 1) == 1) {
+                return singleByteBuf[0] & 0XFF;
+            } else {
+                return -1;
+            }
+        }
 
-        public boolean hasMoreElements() {
-            if (descriptor == -1) {
-                /*
-                 * the descriptor is set to -1 by native code to indicate the
-                 * zip was closed
-                 */
-                throw new IllegalStateException();
+        @Override
+        public int read(byte[] b, int off, int len) throws IOException {
+            synchronized (mSharedRaf) {
+                mSharedRaf.seek(mOffset);
+                if (len > mLength - mOffset) {
+                    len = (int) (mLength - mOffset);
+                }
+                int count = mSharedRaf.read(b, off, len);
+                if (count > 0) {
+                    mOffset += count;
+                    return count;
+                } else {
+                    return -1;
+                }
             }
-            return current != null;
         }
 
-        public T nextElement() {
-            if (current == null) {
-                throw new NoSuchElementException();
+        @Override
+        public long skip(long n) throws IOException {
+            if (n > mLength - mOffset) {
+                n = mLength - mOffset;
             }
-            T ze = current;
-            current = getNextEntry(descriptor, nextEntryPointer);
-            return ze;
+            mOffset += n;
+            return n;
         }
     }
 }

Modified: harmony/enhanced/classlib/branches/java6/modules/archive/src/main/java/java/util/zip/ZipInputStream.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/archive/src/main/java/java/util/zip/ZipInputStream.java?rev=824184&r1=824183&r2=824184&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/archive/src/main/java/java/util/zip/ZipInputStream.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/archive/src/main/java/java/util/zip/ZipInputStream.java Sun Oct 11 21:59:47 2009
@@ -1,13 +1,13 @@
-/* 
+/*
  * Licensed to the Apache Software Foundation (ASF) under one or more
  * contributor license agreements.  See the NOTICE file distributed with
  * this work for additional information regarding copyright ownership.
  * The ASF licenses this file to You under the Apache License, Version 2.0
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
- * 
+ *
  *     http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -53,8 +53,6 @@
 
     static final int ZIPLocalHeaderVersionNeeded = 20;
 
-    private boolean zipClosed = false;
-
     private boolean entriesEnd = false;
 
     private boolean hasDD = false;
@@ -75,7 +73,7 @@
 
     /**
      * Constructs a new {@code ZipInputStream} from the specified input stream.
-     * 
+     *
      * @param stream
      *            the input stream to representing a ZIP archive.
      */
@@ -94,21 +92,20 @@
      */
     @Override
     public void close() throws IOException {
-        if (zipClosed != true) {
+        if (!closed) {
             closeEntry(); // Close the current entry
-            zipClosed = true;
             super.close();
         }
     }
 
     /**
      * Closes the current ZIP entry and positions to read the next entry.
-     * 
+     *
      * @throws IOException
      *             if an {@code IOException} occurs.
      */
     public void closeEntry() throws IOException {
-        if (zipClosed) {
+        if (closed) {
             throw new IOException(Messages.getString("archive.1E")); //$NON-NLS-1$
         }
         if (currentEntry == null) {
@@ -198,7 +195,7 @@
     /**
      * Reads the next entry from this {@code ZipInputStream} or {@code null} if
      * no more entries are present.
-     * 
+     *
      * @return the next {@code ZipEntry} contained in the input stream.
      * @throws IOException
      *             if an {@code IOException} occurs.
@@ -295,7 +292,7 @@
     /**
      * Reads up to the specified number of uncompressed bytes into the buffer
      * starting at the offset.
-     * 
+     *
      * @param buffer
      *            a byte array
      * @param start
@@ -306,61 +303,63 @@
      */
     @Override
     public int read(byte[] buffer, int start, int length) throws IOException {
-        if (zipClosed) {
+        if (closed) {
             throw new IOException(Messages.getString("archive.1E")); //$NON-NLS-1$
         }
         if (inf.finished() || currentEntry == null) {
             return -1;
         }
         // avoid int overflow, check null buffer
-        if (start <= buffer.length && length >= 0 && start >= 0
-                && buffer.length - start >= length) {
-            if (currentEntry.compressionMethod == STORED) {
-                int csize = (int) currentEntry.size;
-                if (inRead >= csize) {
+        if (start > buffer.length || length < 0 || start < 0
+                || buffer.length - start < length) {
+            throw new ArrayIndexOutOfBoundsException();
+        }
+
+        if (currentEntry.compressionMethod == STORED) {
+            int csize = (int) currentEntry.size;
+            if (inRead >= csize) {
+                return -1;
+            }
+            if (lastRead >= len) {
+                lastRead = 0;
+                if ((len = in.read(buf)) == -1) {
+                    eof = true;
                     return -1;
                 }
-                if (lastRead >= len) {
-                    lastRead = 0;
-                    if ((len = in.read(buf)) == -1) {
-                        return -1;
-                    }
-                    entryIn += len;
-                }
-                int toRead = length > len ? len - lastRead : length;
-                if ((csize - inRead) < toRead) {
-                    toRead = csize - inRead;
-                }
-                System.arraycopy(buf, lastRead, buffer, start, toRead);
-                lastRead += toRead;
-                inRead += toRead;
-                crc.update(buffer, start, toRead);
-                return toRead;
-            }
-            if (inf.needsInput()) {
-                fill();
-                if (len > 0) {
-                    entryIn += len;
-                }
+                entryIn += len;
             }
-            int read = 0;
-            try {
-                read = inf.inflate(buffer, start, length);
-            } catch (DataFormatException e) {
-                throw new ZipException(e.getMessage());
+            int toRead = length > (len - lastRead) ? len - lastRead : length;
+            if ((csize - inRead) < toRead) {
+                toRead = csize - inRead;
             }
-            if (read == 0 && inf.finished()) {
-                return -1;
+            System.arraycopy(buf, lastRead, buffer, start, toRead);
+            lastRead += toRead;
+            inRead += toRead;
+            crc.update(buffer, start, toRead);
+            return toRead;
+        }
+        if (inf.needsInput()) {
+            fill();
+            if (len > 0) {
+                entryIn += len;
             }
-            crc.update(buffer, start, read);
-            return read;
         }
-        throw new ArrayIndexOutOfBoundsException();
+        int read;
+        try {
+            read = inf.inflate(buffer, start, length);
+        } catch (DataFormatException e) {
+            throw new ZipException(e.getMessage());
+        }
+        if (read == 0 && inf.finished()) {
+            return -1;
+        }
+        crc.update(buffer, start, read);
+        return read;
     }
 
     /**
      * Skips up to the specified number of bytes in the current ZIP entry.
-     * 
+     *
      * @param value
      *            the number of bytes to skip.
      * @return the number of bytes skipped.
@@ -369,47 +368,36 @@
      */
     @Override
     public long skip(long value) throws IOException {
-        if (value >= 0) {
-            long skipped = 0;
-            byte[] b = new byte[1024];
-            while (skipped != value) {
-                long rem = value - skipped;
-                int x = read(b, 0, (int) (b.length > rem ? rem : b.length));
-                if (x == -1) {
-                    return skipped;
-                }
-                skipped += x;
+        if (value < 0) {
+            throw new IllegalArgumentException();
+        }
+
+        long skipped = 0;
+        byte[] b = new byte[(int)Math.min(value, 2048L)];
+        while (skipped != value) {
+            long rem = value - skipped;
+            int x = read(b, 0, (int) (b.length > rem ? rem : b.length));
+            if (x == -1) {
+                return skipped;
             }
-            return skipped;
+            skipped += x;
         }
-        throw new IllegalArgumentException();
+        return skipped;
     }
 
     /**
      * Returns 0 if the {@code EOF} has been reached, otherwise returns 1.
-     * 
+     *
      * @return 0 after {@code EOF} of current entry, 1 otherwise.
      * @throws IOException
      *             if an IOException occurs.
      */
     @Override
     public int available() throws IOException {
-        if (zipClosed) {
+        if (closed) {
             throw new IOException(Messages.getString("archive.1E")); //$NON-NLS-1$
         }
-        if (currentEntry == null) {
-            return 1;
-        }
-        if (currentEntry.compressionMethod == STORED) {
-            if (inRead >= currentEntry.size) {
-                return 0;
-            }
-        } else {
-            if (inf.finished()) {
-                return 0;
-            }
-        }
-        return 1;
+        return (currentEntry == null || inRead < currentEntry.size) ? 1 : 0;
     }
 
     /**