diff options
Diffstat (limited to 'src/share/classes/java/util/zip')
-rw-r--r-- | src/share/classes/java/util/zip/GZIPInputStream.java | 87 | ||||
-rw-r--r-- | src/share/classes/java/util/zip/GZIPOutputStream.java | 90 | ||||
-rw-r--r-- | src/share/classes/java/util/zip/ZipException.java | 6 | ||||
-rw-r--r-- | src/share/classes/java/util/zip/package.html | 15 |
4 files changed, 144 insertions, 54 deletions
diff --git a/src/share/classes/java/util/zip/GZIPInputStream.java b/src/share/classes/java/util/zip/GZIPInputStream.java index 1140c38b3..8d60d1996 100644 --- a/src/share/classes/java/util/zip/GZIPInputStream.java +++ b/src/share/classes/java/util/zip/GZIPInputStream.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -66,19 +66,24 @@ class GZIPInputStream extends InflaterInputStream { * Creates a new input stream with the specified buffer size. * @param in the input stream * @param size the input buffer size + * + * @exception ZipException if a GZIP format error has occurred or the + * compression method used is unsupported * @exception IOException if an I/O error has occurred * @exception IllegalArgumentException if size is <= 0 */ public GZIPInputStream(InputStream in, int size) throws IOException { super(in, new Inflater(true), size); usesDefaultInflater = true; - readHeader(); - crc.reset(); + readHeader(in); } /** * Creates a new input stream with a default buffer size. * @param in the input stream + * + * @exception ZipException if a GZIP format error has occurred or the + * compression method used is unsupported * @exception IOException if an I/O error has occurred */ public GZIPInputStream(InputStream in) throws IOException { @@ -94,26 +99,30 @@ class GZIPInputStream extends InflaterInputStream { * @param len the maximum number of bytes read * @return the actual number of bytes read, or -1 if the end of the * compressed input stream is reached + * * @exception NullPointerException If <code>buf</code> is <code>null</code>. * @exception IndexOutOfBoundsException If <code>off</code> is negative, * <code>len</code> is negative, or <code>len</code> is greater than * <code>buf.length - off</code> - * @exception IOException if an I/O error has occurred or the compressed - * input data is corrupt + * @exception ZipException if the compressed input data is corrupt. + * @exception IOException if an I/O error has occurred. + * */ public int read(byte[] buf, int off, int len) throws IOException { ensureOpen(); if (eos) { return -1; } - len = super.read(buf, off, len); - if (len == -1) { - readTrailer(); - eos = true; + int n = super.read(buf, off, len); + if (n == -1) { + if (readTrailer()) + eos = true; + else + return this.read(buf, off, len); } else { - crc.update(buf, off, len); + crc.update(buf, off, n); } - return len; + return n; } /** @@ -144,48 +153,61 @@ class GZIPInputStream extends InflaterInputStream { private final static int FCOMMENT = 16; // File comment /* - * Reads GZIP member header. + * Reads GZIP member header and returns the total byte number + * of this member header. */ - private void readHeader() throws IOException { - CheckedInputStream in = new CheckedInputStream(this.in, crc); + private int readHeader(InputStream this_in) throws IOException { + CheckedInputStream in = new CheckedInputStream(this_in, crc); crc.reset(); // Check header magic if (readUShort(in) != GZIP_MAGIC) { - throw new IOException("Not in GZIP format"); + throw new ZipException("Not in GZIP format"); } // Check compression method if (readUByte(in) != 8) { - throw new IOException("Unsupported compression method"); + throw new ZipException("Unsupported compression method"); } // Read flags int flg = readUByte(in); // Skip MTIME, XFL, and OS fields skipBytes(in, 6); + int n = 2 + 2 + 6; // Skip optional extra field if ((flg & FEXTRA) == FEXTRA) { - skipBytes(in, readUShort(in)); + int m = readUShort(in); + skipBytes(in, m); + n += m + 2; } // Skip optional file name if ((flg & FNAME) == FNAME) { - while (readUByte(in) != 0) ; + do { + n++; + } while (readUByte(in) != 0); } // Skip optional file comment if ((flg & FCOMMENT) == FCOMMENT) { - while (readUByte(in) != 0) ; + do { + n++; + } while (readUByte(in) != 0); } // Check optional header CRC if ((flg & FHCRC) == FHCRC) { int v = (int)crc.getValue() & 0xffff; if (readUShort(in) != v) { - throw new IOException("Corrupt GZIP header"); + throw new ZipException("Corrupt GZIP header"); } + n += 2; } + crc.reset(); + return n; } /* - * Reads GZIP member trailer. + * Reads GZIP member trailer and returns true if the eos + * reached, false if there are more (concatenated gzip + * data set) */ - private void readTrailer() throws IOException { + private boolean readTrailer() throws IOException { InputStream in = this.in; int n = inf.getRemaining(); if (n > 0) { @@ -196,7 +218,25 @@ class GZIPInputStream extends InflaterInputStream { if ((readUInt(in) != crc.getValue()) || // rfc1952; ISIZE is the input size modulo 2^32 (readUInt(in) != (inf.getBytesWritten() & 0xffffffffL))) - throw new IOException("Corrupt GZIP trailer"); + throw new ZipException("Corrupt GZIP trailer"); + + // If there are more bytes available in "in" or + // the leftover in the "inf" is > 26 bytes: + // this.trailer(8) + next.header.min(10) + next.trailer(8) + // try concatenated case + if (this.in.available() > 0 || n > 26) { + int m = 8; // this.trailer + try { + m += readHeader(in); // next.header + } catch (IOException ze) { + return true; // ignore any malformed, do nothing + } + inf.reset(); + if (n > m) + inf.setInput(buf, len - n + m, n - m); + return false; + } + return true; } /* @@ -231,7 +271,6 @@ class GZIPInputStream extends InflaterInputStream { return b; } - private byte[] tmpbuf = new byte[128]; /* diff --git a/src/share/classes/java/util/zip/GZIPOutputStream.java b/src/share/classes/java/util/zip/GZIPOutputStream.java index 4473f78db..d5edcf122 100644 --- a/src/share/classes/java/util/zip/GZIPOutputStream.java +++ b/src/share/classes/java/util/zip/GZIPOutputStream.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2002, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -54,25 +54,82 @@ class GZIPOutputStream extends DeflaterOutputStream { /** * Creates a new output stream with the specified buffer size. + * + * <p>The new output stream instance is created as if by invoking + * the 3-argument constructor GZIPOutputStream(out, size, false). + * * @param out the output stream * @param size the output buffer size * @exception IOException If an I/O error has occurred. * @exception IllegalArgumentException if size is <= 0 + */ public GZIPOutputStream(OutputStream out, int size) throws IOException { - super(out, new Deflater(Deflater.DEFAULT_COMPRESSION, true), size); + this(out, size, false); + } + + /** + * Creates a new output stream with the specified buffer size and + * flush mode. + * + * @param out the output stream + * @param size the output buffer size + * @param syncFlush + * if {@code true} invocation of the inherited + * {@link DeflaterOutputStream#flush() flush()} method of + * this instance flushes the compressor with flush mode + * {@link Deflater#SYNC_FLUSH} before flushing the output + * stream, otherwise only flushes the output stream + * @exception IOException If an I/O error has occurred. + * @exception IllegalArgumentException if size is <= 0 + * + * @since 1.7 + */ + public GZIPOutputStream(OutputStream out, int size, boolean syncFlush) + throws IOException + { + super(out, new Deflater(Deflater.DEFAULT_COMPRESSION, true), + size, + syncFlush); usesDefaultDeflater = true; writeHeader(); crc.reset(); } + /** * Creates a new output stream with a default buffer size. + * + * <p>The new output stream instance is created as if by invoking + * the 2-argument constructor GZIPOutputStream(out, false). + * * @param out the output stream * @exception IOException If an I/O error has occurred. */ public GZIPOutputStream(OutputStream out) throws IOException { - this(out, 512); + this(out, 512, false); + } + + /** + * Creates a new output stream with a default buffer size and + * the specified flush mode. + * + * @param out the output stream + * @param syncFlush + * if {@code true} invocation of the inherited + * {@link DeflaterOutputStream#flush() flush()} method of + * this instance flushes the compressor with flush mode + * {@link Deflater#SYNC_FLUSH} before flushing the output + * stream, otherwise only flushes the output stream + * + * @exception IOException If an I/O error has occurred. + * + * @since 1.7 + */ + public GZIPOutputStream(OutputStream out, boolean syncFlush) + throws IOException + { + this(out, 512, syncFlush); } /** @@ -122,22 +179,19 @@ class GZIPOutputStream extends DeflaterOutputStream { /* * Writes GZIP member header. */ - - private final static byte[] header = { - (byte) GZIP_MAGIC, // Magic number (short) - (byte)(GZIP_MAGIC >> 8), // Magic number (short) - Deflater.DEFLATED, // Compression method (CM) - 0, // Flags (FLG) - 0, // Modification time MTIME (int) - 0, // Modification time MTIME (int) - 0, // Modification time MTIME (int) - 0, // Modification time MTIME (int) - 0, // Extra flags (XFLG) - 0 // Operating system (OS) - }; - private void writeHeader() throws IOException { - out.write(header); + out.write(new byte[] { + (byte) GZIP_MAGIC, // Magic number (short) + (byte)(GZIP_MAGIC >> 8), // Magic number (short) + Deflater.DEFLATED, // Compression method (CM) + 0, // Flags (FLG) + 0, // Modification time MTIME (int) + 0, // Modification time MTIME (int) + 0, // Modification time MTIME (int) + 0, // Modification time MTIME (int) + 0, // Extra flags (XFLG) + 0 // Operating system (OS) + }); } /* diff --git a/src/share/classes/java/util/zip/ZipException.java b/src/share/classes/java/util/zip/ZipException.java index 4c5fb99c2..4bcfe0368 100644 --- a/src/share/classes/java/util/zip/ZipException.java +++ b/src/share/classes/java/util/zip/ZipException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 2008, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1995, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -40,7 +40,7 @@ class ZipException extends IOException { private static final long serialVersionUID = 8000196834066748623L; /** - * Constructs an <code>ZipException</code> with <code>null</code> + * Constructs a <code>ZipException</code> with <code>null</code> * as its error detail message. */ public ZipException() { @@ -48,7 +48,7 @@ class ZipException extends IOException { } /** - * Constructs an <code>ZipException</code> with the specified detail + * Constructs a <code>ZipException</code> with the specified detail * message. * * @param s the detail message. diff --git a/src/share/classes/java/util/zip/package.html b/src/share/classes/java/util/zip/package.html index 9365f15f0..e83f98fde 100644 --- a/src/share/classes/java/util/zip/package.html +++ b/src/share/classes/java/util/zip/package.html @@ -58,25 +58,22 @@ input streams. PKWARE ZIP File Format Specification</a> - Language Encoding Flag (EFS) to encode ZIP entry filename and comment fields using UTF-8. <p> - <li><a href="http://www.isi.edu/in-notes/rfc1950.txt"> + <li><a href="http://www.ietf.org/rfc/rfc1950.txt"> ZLIB Compressed Data Format Specification version 3.3</a> - <a href="http://www.isi.edu/in-notes/rfc1950.ps"> - (PostScript)</a> + <a href="http://www.ietf.org/rfc/rfc1950.txt.pdf">(pdf)</a> (RFC 1950) <p> - <li><a href="http://www.isi.edu/in-notes/rfc1951.txt"> + <li><a href="http://www.ietf.org/rfc/rfc1951.txt"> DEFLATE Compressed Data Format Specification version 1.3</a> - <a href="http://www.isi.edu/in-notes/rfc1951.ps"> - (PostScript)</a> + <a href="http://www.ietf.org/rfc/rfc1951.txt.pdf">(pdf)</a> (RFC 1951) <p> - <li><a href="http://www.isi.edu/in-notes/rfc1952.txt"> + <li><a href="http://www.ietf.org/rfc/rfc1952.txt"> GZIP file format specification version 4.3</a> - <a href="http://www.isi.edu/in-notes/rfc1952.ps"> - (PostScript)</a> + <a href="http://www.ietf.org/rfc/rfc1952.txt.pdf">(pdf)</a> (RFC 1952) <p> <li>CRC-32 checksum is described in RFC 1952 (above) |