diff options
author | 2015-06-09 16:39:59 +0000 | |
---|---|---|
committer | 2015-06-10 16:02:22 +0000 | |
commit | 1cad714e2157dd940cc75428e8bb4d682b1bef28 (patch) | |
tree | bf62a5e34762160cbefa096f95364666f840e445 /src/java_tools/singlejar/java/com/google/devtools/build | |
parent | 6b2766dd0e97e37fd56c1c538bc029f22e68dfcd (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')
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."); } |