aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/java_tools/singlejar/java/com/google/devtools/build
diff options
context:
space:
mode:
authorGravatar Andrew Pellegrini <apell@google.com>2015-06-09 16:39:59 +0000
committerGravatar Philipp Wollermann <philwo@google.com>2015-06-10 16:02:22 +0000
commit1cad714e2157dd940cc75428e8bb4d682b1bef28 (patch)
treebf62a5e34762160cbefa096f95364666f840e445 /src/java_tools/singlejar/java/com/google/devtools/build
parent6b2766dd0e97e37fd56c1c538bc029f22e68dfcd (diff)
Removed deprecated API features from ZipCombiner and improves slow read testing and support.
RELNOTES: Elements of ZipCombiner's API previously marked deprecated are removed. -- MOS_MIGRATED_REVID=95543357
Diffstat (limited to 'src/java_tools/singlejar/java/com/google/devtools/build')
-rw-r--r--src/java_tools/singlejar/java/com/google/devtools/build/singlejar/ZipCombiner.java101
-rw-r--r--src/java_tools/singlejar/java/com/google/devtools/build/zip/ZipReader.java38
-rw-r--r--src/java_tools/singlejar/java/com/google/devtools/build/zip/ZipUtil.java39
3 files changed, 50 insertions, 128 deletions
diff --git a/src/java_tools/singlejar/java/com/google/devtools/build/singlejar/ZipCombiner.java b/src/java_tools/singlejar/java/com/google/devtools/build/singlejar/ZipCombiner.java
index 64e9695e07..c9d5d2c7e6 100644
--- a/src/java_tools/singlejar/java/com/google/devtools/build/singlejar/ZipCombiner.java
+++ b/src/java_tools/singlejar/java/com/google/devtools/build/singlejar/ZipCombiner.java
@@ -33,8 +33,6 @@ import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
-import java.nio.file.Files;
-import java.nio.file.StandardCopyOption;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
@@ -121,53 +119,6 @@ public class ZipCombiner implements AutoCloseable {
}
/**
- * The directory entry info used for files whose extra directory entry info is not given
- * explicitly. It uses {@code -1} for {@link DirectoryEntryInfo#withMadeByVersion(short)}, which
- * indicates it will be set to the same version as "needed to extract."
- *
- * <p>The {@link DirectoryEntryInfo#withExternalFileAttribute(int)} value is set to {@code 0},
- * whose meaning depends on the value of {@code madeByVersion}, but is usually a reasonable
- * default.
- */
- @Deprecated
- public static final DirectoryEntryInfo DEFAULT_DIRECTORY_ENTRY_INFO =
- new DirectoryEntryInfo((short) -1, 0);
-
- /**
- * Contains information related to a zip entry that is stored in the central directory record.
- * This does not contain all the information stored in the central directory record, only the
- * information that can be customized and is not automatically calculated or detected.
- */
- @Deprecated
- public static final class DirectoryEntryInfo {
- private final short madeByVersion;
- private final int externalFileAttribute;
-
- private DirectoryEntryInfo(short madeByVersion, int externalFileAttribute) {
- this.madeByVersion = madeByVersion;
- this.externalFileAttribute = externalFileAttribute;
- }
-
- /**
- * This will be written as "made by" version in the central directory.
- * If -1 (default) then "made by" will be the same to version "needed to extract".
- */
- public DirectoryEntryInfo withMadeByVersion(short madeByVersion) {
- return new DirectoryEntryInfo(madeByVersion, externalFileAttribute);
- }
-
- /**
- * This will be written as external file attribute. The meaning of this depends upon the value
- * set with {@link #withMadeByVersion(short)}. If that value indicates a Unix source, then this
- * value has the file mode and permission bits in the upper two bytes (e.g. possibly
- * {@code 0100644} for a regular file).
- */
- public DirectoryEntryInfo withExternalFileAttribute(int externalFileAttribute) {
- return new DirectoryEntryInfo(madeByVersion, externalFileAttribute);
- }
- }
-
- /**
* Encapsulates the action to take for a ZIP file entry along with optional details specific to
* the action type. The minimum requirements per type are:
* <ul>
@@ -469,58 +420,6 @@ public class ZipCombiner implements AutoCloseable {
}
/**
- * Adds a new entry into the output, by reading the input stream until it returns end of stream.
- * This method does not call {@link ZipEntryFilter#accept}.
- *
- * @throws IOException if one of the underlying streams throws an IOException
- * or if the input stream returns more data than
- * supported by the ZIP format
- * @throws IllegalStateException if an entry with the given name already
- * exists
- * @throws IllegalArgumentException if the given file name is longer than
- * supported by the ZIP format
- */
- @Deprecated
- public void addFile(String filename, Date date, InputStream in,
- DirectoryEntryInfo directoryEntryInfo) throws IOException {
- ZipFileEntry entry = new ZipFileEntry(filename);
- entry.setTime(date != null ? date.getTime() : new Date().getTime());
- entry.setVersion(directoryEntryInfo.madeByVersion);
- entry.setExternalAttributes(directoryEntryInfo.externalFileAttribute);
- addFile(entry, in);
- }
-
- /**
- * Adds the contents of a ZIP file to the combined ZIP file using the specified
- * {@link ZipEntryFilter} to determine the appropriate action for each file.
- *
- * @param in the InputStream of the ZIP file to add to the combined ZIP file
- * @throws IOException if there is an error reading the ZIP file or writing entries to the
- * combined ZIP file
- */
- @Deprecated
- public void addZip(InputStream in) throws IOException {
- addZip(null, in);
- }
-
- /**
- * Adds the contents of a ZIP file to the combined ZIP file using the specified
- * {@link ZipEntryFilter} to determine the appropriate action for each file.
- *
- * @param inputName the name of the ZIP file to add for providing better error messages
- * @param in the InputStream of the ZIP file to add to the combined ZIP file
- * @throws IOException if there is an error reading the ZIP file or writing entries to the
- * combined ZIP file
- */
- @Deprecated
- public void addZip(String inputName, InputStream in) throws IOException {
- File file = Files.createTempFile(inputName, null).toFile();
- Files.copy(in, file.toPath(), StandardCopyOption.REPLACE_EXISTING);
- addZip(file);
- file.deleteOnExit();
- }
-
- /**
* Adds the contents of a ZIP file to the combined ZIP file using the specified
* {@link ZipEntryFilter} to determine the appropriate action for each file.
*
diff --git a/src/java_tools/singlejar/java/com/google/devtools/build/zip/ZipReader.java b/src/java_tools/singlejar/java/com/google/devtools/build/zip/ZipReader.java
index b4ccd5ceb2..de9b245a52 100644
--- a/src/java_tools/singlejar/java/com/google/devtools/build/zip/ZipReader.java
+++ b/src/java_tools/singlejar/java/com/google/devtools/build/zip/ZipReader.java
@@ -67,11 +67,10 @@ public class ZipReader implements Closeable, AutoCloseable {
* @throws IOException if an I/O error has occurred
*/
private ZipEntryInputStream(ZipFileEntry zipEntry) throws IOException {
- stream = new BufferedInputStream(Channels.newInputStream(
- in.getChannel().position(zipEntry.getLocalHeaderOffset())));
+ stream = getStreamAt(zipEntry.getLocalHeaderOffset());
byte[] fileHeader = new byte[LocalFileHeader.FIXED_DATA_SIZE];
- stream.read(fileHeader);
+ ZipUtil.readFully(stream, fileHeader);
if (!ZipUtil.arrayStartsWith(fileHeader,
ZipUtil.intToLittleEndian(LocalFileHeader.SIGNATURE))) {
@@ -84,7 +83,7 @@ public class ZipReader implements Closeable, AutoCloseable {
LocalFileHeader.FILENAME_LENGTH_OFFSET);
int extraFieldLength = ZipUtil.getUnsignedShort(fileHeader,
LocalFileHeader.EXTRA_FIELD_LENGTH_OFFSET);
- stream.skip(nameLength + extraFieldLength);
+ ZipUtil.readFully(stream, new byte[nameLength + extraFieldLength]);
rem = zipEntry.getSize();
if (zipEntry.getMethod() == Compression.DEFLATED) {
stream = new InflaterInputStream(stream, new Inflater(true));
@@ -157,11 +156,10 @@ public class ZipReader implements Closeable, AutoCloseable {
* @throws IOException if an I/O error has occurred
*/
private RawZipEntryInputStream(ZipFileEntry zipEntry) throws IOException {
- stream = new BufferedInputStream(Channels.newInputStream(
- in.getChannel().position(zipEntry.getLocalHeaderOffset())));
+ stream = getStreamAt(zipEntry.getLocalHeaderOffset());
byte[] fileHeader = new byte[LocalFileHeader.FIXED_DATA_SIZE];
- stream.read(fileHeader);
+ ZipUtil.readFully(stream, fileHeader);
if (!ZipUtil.arrayStartsWith(fileHeader,
ZipUtil.intToLittleEndian(LocalFileHeader.SIGNATURE))) {
@@ -174,7 +172,7 @@ public class ZipReader implements Closeable, AutoCloseable {
LocalFileHeader.FILENAME_LENGTH_OFFSET);
int extraFieldLength = ZipUtil.getUnsignedShort(fileHeader,
LocalFileHeader.EXTRA_FIELD_LENGTH_OFFSET);
- stream.skip(nameLength + extraFieldLength);
+ ZipUtil.readFully(stream, new byte[nameLength + extraFieldLength]);
rem = zipEntry.getCompressedSize();
}
@@ -371,18 +369,15 @@ public class ZipReader implements Closeable, AutoCloseable {
*/
private void readCentralDirectory(boolean strictEntries) throws IOException {
long eocdLocation = findEndOfCentralDirectoryRecord();
- InputStream stream = new BufferedInputStream(Channels.newInputStream(
- in.getChannel().position(eocdLocation)));
+ InputStream stream = getStreamAt(eocdLocation);
EndOfCentralDirectoryRecord.read(stream, zipData);
if (zipData.isMaybeZip64()) {
try {
- stream = new BufferedInputStream(Channels.newInputStream(in.getChannel()
- .position(eocdLocation - Zip64EndOfCentralDirectoryLocator.FIXED_DATA_SIZE)));
+ stream = getStreamAt(eocdLocation - Zip64EndOfCentralDirectoryLocator.FIXED_DATA_SIZE);
Zip64EndOfCentralDirectoryLocator.read(stream, zipData);
- stream = new BufferedInputStream(Channels.newInputStream(in.getChannel()
- .position(zipData.getZip64EndOfCentralDirectoryOffset())));
+ stream = getStreamAt(zipData.getZip64EndOfCentralDirectoryOffset());
Zip64EndOfCentralDirectory.read(stream, zipData);
} catch (ZipException e) {
// expected if not in Zip64 format
@@ -484,8 +479,7 @@ public class ZipReader implements Closeable, AutoCloseable {
* @throws IOException if an I/O error has occurred
*/
private void readCentralDirectoryFileHeaders(long count, long fileOffset) throws IOException {
- InputStream centralDirectory = new BufferedInputStream(
- Channels.newInputStream(in.getChannel().position(fileOffset)));
+ InputStream centralDirectory = getStreamAt(fileOffset);
for (long i = 0; i < count; i++) {
ZipFileEntry entry = CentralDirectoryFileHeader.read(centralDirectory, zipData.getCharset());
zipData.addEntry(entry);
@@ -500,11 +494,19 @@ public class ZipReader implements Closeable, AutoCloseable {
* @throws IOException if an I/O error has occurred
*/
private void readCentralDirectoryFileHeaders(long fileOffset) throws IOException {
- CountingInputStream centralDirectory = new CountingInputStream(new BufferedInputStream(
- Channels.newInputStream(in.getChannel().position(fileOffset))));
+ CountingInputStream centralDirectory = new CountingInputStream(getStreamAt(fileOffset));
while (centralDirectory.getCount() < zipData.getCentralDirectorySize()) {
ZipFileEntry entry = CentralDirectoryFileHeader.read(centralDirectory, zipData.getCharset());
zipData.addEntry(entry);
}
}
+
+ /**
+ * Returns a new {@link InputStream} positioned at fileOffset.
+ *
+ * @throws IOException if an I/O error has occurred
+ */
+ protected InputStream getStreamAt(long fileOffset) throws IOException {
+ return new BufferedInputStream(Channels.newInputStream(in.getChannel().position(fileOffset)));
+ }
}
diff --git a/src/java_tools/singlejar/java/com/google/devtools/build/zip/ZipUtil.java b/src/java_tools/singlejar/java/com/google/devtools/build/zip/ZipUtil.java
index 2ba4caf4f2..978bcfb84c 100644
--- a/src/java_tools/singlejar/java/com/google/devtools/build/zip/ZipUtil.java
+++ b/src/java_tools/singlejar/java/com/google/devtools/build/zip/ZipUtil.java
@@ -204,6 +204,27 @@ public class ZipUtil {
return true;
}
+ /** Read from the input stream into the array until it is full. */
+ static int readFully(InputStream in, byte[] b) throws IOException {
+ return readFully(in, b, 0, b.length);
+ }
+
+ /** Read from the input stream into the array starting at off until len bytes have been read. */
+ static int readFully(InputStream in, byte[] b, int off, int len) throws IOException {
+ if (len < 0) {
+ throw new IndexOutOfBoundsException();
+ }
+ int n = 0;
+ while (n < len) {
+ int count = in.read(b, off + n, len - n);
+ if (count < 0) {
+ return n;
+ }
+ n += count;
+ }
+ return n;
+ }
+
static class LocalFileHeader {
static final int SIGNATURE = 0x04034b50;
static final int FIXED_DATA_SIZE = 30;
@@ -277,7 +298,7 @@ public class ZipUtil {
shortToLittleEndian(buf, FILENAME_LENGTH_OFFSET, (short) name.length);
shortToLittleEndian(buf, EXTRA_FIELD_LENGTH_OFFSET, (short) extra.getLength());
System.arraycopy(name, 0, buf, FIXED_DATA_SIZE, name.length);
- extra.getByteStream().read(buf, FIXED_DATA_SIZE + name.length, extra.getLength());
+ readFully(extra.getByteStream(), buf, FIXED_DATA_SIZE + name.length, extra.getLength());
return buf;
}
@@ -311,7 +332,7 @@ public class ZipUtil {
throws IOException {
byte[] fixedSizeData = new byte[FIXED_DATA_SIZE];
- if (in.read(fixedSizeData) != FIXED_DATA_SIZE) {
+ if (readFully(in, fixedSizeData) != FIXED_DATA_SIZE) {
throw new ZipException(
"Unexpected end of file while reading Central Directory File Header.");
}
@@ -324,15 +345,15 @@ public class ZipUtil {
byte[] extraField = new byte[getUnsignedShort(fixedSizeData, EXTRA_FIELD_LENGTH_OFFSET)];
byte[] comment = new byte[getUnsignedShort(fixedSizeData, COMMENT_LENGTH_OFFSET)];
- if (name.length > 0 && in.read(name) != name.length) {
+ if (name.length > 0 && readFully(in, name) != name.length) {
throw new ZipException(
"Unexpected end of file while reading Central Directory File Header.");
}
- if (extraField.length > 0 && in.read(extraField) != extraField.length) {
+ if (extraField.length > 0 && readFully(in, extraField) != extraField.length) {
throw new ZipException(
"Unexpected end of file while reading Central Directory File Header.");
}
- if (comment.length > 0 && in.read(comment) != comment.length) {
+ if (comment.length > 0 && readFully(in, comment) != comment.length) {
throw new ZipException(
"Unexpected end of file while reading Central Directory File Header.");
}
@@ -541,7 +562,7 @@ public class ZipUtil {
}
byte[] fixedSizeData = new byte[FIXED_DATA_SIZE];
- if (in.read(fixedSizeData) != FIXED_DATA_SIZE) {
+ if (readFully(in, fixedSizeData) != FIXED_DATA_SIZE) {
throw new ZipException(
"Unexpected end of file while reading Zip64 End of Central Directory Record.");
}
@@ -592,7 +613,7 @@ public class ZipUtil {
}
byte[] fixedSizeData = new byte[FIXED_DATA_SIZE];
- if (in.read(fixedSizeData) != FIXED_DATA_SIZE) {
+ if (readFully(in, fixedSizeData) != FIXED_DATA_SIZE) {
throw new ZipException(
"Unexpected end of file while reading Zip64 End of Central Directory Locator.");
}
@@ -641,7 +662,7 @@ public class ZipUtil {
}
byte[] fixedSizeData = new byte[FIXED_DATA_SIZE];
- if (in.read(fixedSizeData) != FIXED_DATA_SIZE) {
+ if (readFully(in, fixedSizeData) != FIXED_DATA_SIZE) {
throw new ZipException(
"Unexpected end of file while reading End of Central Directory Record.");
}
@@ -651,7 +672,7 @@ public class ZipUtil {
}
byte[] comment = new byte[getUnsignedShort(fixedSizeData, COMMENT_LENGTH_OFFSET)];
- if (comment.length > 0 && in.read(comment) != comment.length) {
+ if (comment.length > 0 && readFully(in, comment) != comment.length) {
throw new ZipException(
"Unexpected end of file while reading End of Central Directory Record.");
}