aboutsummaryrefslogtreecommitdiff
path: root/src/share/classes/java/util/zip
diff options
context:
space:
mode:
Diffstat (limited to 'src/share/classes/java/util/zip')
-rw-r--r--src/share/classes/java/util/zip/GZIPInputStream.java87
-rw-r--r--src/share/classes/java/util/zip/GZIPOutputStream.java90
-rw-r--r--src/share/classes/java/util/zip/ZipException.java6
-rw-r--r--src/share/classes/java/util/zip/package.html15
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>
&nbsp;
- <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>
&nbsp;
- <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>
&nbsp;
- <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)