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;
}
/**