GZIPInputStreampublic class GZIPInputStream extends InflaterInputStream This class implements a stream filter for reading compressed data in
the GZIP file format. |
Fields Summary |
---|
protected CRC32 | crcCRC-32 for uncompressed data. | protected boolean | eosIndicates end of input stream. | private boolean | closed | public static final int | GZIP_MAGICGZIP header magic number. | private static final int | FTEXT | private static final int | FHCRC | private static final int | FEXTRA | private static final int | FNAME | private static final int | FCOMMENT | private byte[] | tmpbuf |
Constructors Summary |
---|
public GZIPInputStream(InputStream in, int size)Creates a new input stream with the specified buffer size.
super(in, new Inflater(true), size);
usesDefaultInflater = true;
readHeader();
crc.reset();
| public GZIPInputStream(InputStream in)Creates a new input stream with a default buffer size.
this(in, 512);
|
Methods Summary |
---|
public void | close()Closes this input stream and releases any system resources associated
with the stream.
if (!closed) {
super.close();
eos = true;
closed = true;
}
| private void | ensureOpen()Check to make sure that this stream has not been closed
if (closed) {
throw new IOException("Stream closed");
}
| public int | read(byte[] buf, int off, int len)Reads uncompressed data into an array of bytes. If len is not
zero, the method will block until some input can be decompressed; otherwise,
no bytes are read and 0 is returned.
ensureOpen();
if (eos) {
return -1;
}
len = super.read(buf, off, len);
if (len == -1) {
readTrailer();
eos = true;
} else {
crc.update(buf, off, len);
}
return len;
| private void | readHeader() // File comment
/*
* Reads GZIP member header.
*/
CheckedInputStream in = new CheckedInputStream(this.in, crc);
crc.reset();
// Check header magic
if (readUShort(in) != GZIP_MAGIC) {
throw new IOException("Not in GZIP format");
}
// Check compression method
if (readUByte(in) != 8) {
throw new IOException("Unsupported compression method");
}
// Read flags
int flg = readUByte(in);
// Skip MTIME, XFL, and OS fields
skipBytes(in, 6);
// Skip optional extra field
if ((flg & FEXTRA) == FEXTRA) {
skipBytes(in, readUShort(in));
}
// Skip optional file name
if ((flg & FNAME) == FNAME) {
while (readUByte(in) != 0) ;
}
// Skip optional file comment
if ((flg & FCOMMENT) == FCOMMENT) {
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");
}
}
| private void | readTrailer()
InputStream in = this.in;
int n = inf.getRemaining();
if (n > 0) {
in = new SequenceInputStream(
new ByteArrayInputStream(buf, len - n, n), in);
}
// Uses left-to-right evaluation order
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");
| private int | readUByte(java.io.InputStream in)
int b = in.read();
if (b == -1) {
throw new EOFException();
}
if (b < -1 || b > 255) {
// Report on this.in, not argument in; see read{Header, Trailer}.
throw new IOException(this.in.getClass().getName()
+ ".read() returned value out of range -1..255: " + b);
}
return b;
| private long | readUInt(java.io.InputStream in)
long s = readUShort(in);
return ((long)readUShort(in) << 16) | s;
| private int | readUShort(java.io.InputStream in)
int b = readUByte(in);
return ((int)readUByte(in) << 8) | b;
| private void | skipBytes(java.io.InputStream in, int n)
/*
* Skips bytes of input data blocking until all bytes are skipped.
* Does not assume that the input stream is capable of seeking.
*/
while (n > 0) {
int len = in.read(tmpbuf, 0, n < tmpbuf.length ? n : tmpbuf.length);
if (len == -1) {
throw new EOFException();
}
n -= len;
}
|
|