1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154
|
// GZIPInputStream.java - Input tiler for reading gzip file.
/* Copyright (C) 1999 Cygnus Solutions
This file is part of libgcj.
This software is copyrighted work licensed under the terms of the
Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
details. */
package java.util.zip;
import java.io.InputStream;
import java.io.IOException;
/**
* @author Tom Tromey
* @date May 17, 1999
*/
/* Written using on-line Java Platform 1.2 API Specification
* and JCL book.
* Believed complete and correct.
*/
public class GZIPInputStream extends InflaterInputStream
{
public static final int GZIP_MAGIC = 0x8b1f;
public void close () throws IOException
{
// Nothing to do here.
super.close();
}
public GZIPInputStream (InputStream istream) throws IOException
{
this (istream, 512);
}
private final int eof_read () throws IOException
{
int r = in.read();
if (r == -1)
throw new ZipException ("gzip header corrupted");
return r & 0xff;
}
public GZIPInputStream (InputStream istream, int readsize)
throws IOException
{
super (istream, new Inflater (true), readsize);
// NOTE: header reading code taken from zlib's gzio.c.
// Read the magic number.
int magic = eof_read () | (eof_read () << 8);
if (magic != GZIP_MAGIC)
throw new ZipException ("gzip header corrupted");
int method = eof_read ();
int flags = eof_read ();
// Test from zlib.
if (method != Z_DEFLATED || (flags & RESERVED) != 0)
throw new ZipException ("gzip header corrupted");
// Discard time, xflags, OS code.
for (int i = 0; i < 6; ++i)
eof_read ();
// Skip the extra field.
if ((flags & EXTRA_FIELD) != 0)
{
int len = eof_read () | (eof_read () << 8);
while (len-- != 0)
eof_read ();
}
if ((flags & ORIG_NAME) != 0)
{
while (true)
{
int c = eof_read ();
if (c == 0)
break;
}
}
if ((flags & COMMENT) != 0)
{
while (true)
{
int c = eof_read ();
if (c == 0)
break;
}
}
if ((flags & HEAD_CRC) != 0)
{
// FIXME: consider checking CRC of the header.
eof_read ();
eof_read ();
}
crc = new CRC32 ();
}
public int read (byte[] buf, int off, int len) throws IOException
{
if (eos)
return -1;
int r = super.read(buf, off, len);
if (r == -1)
{
eos = true;
int header_crc = read4 ();
if (crc.getValue() != header_crc)
throw new ZipException ("corrupted gzip file");
// Read final `ISIZE' field.
// FIXME: should we check this length?
read4 ();
return -1;
}
crc.update(buf, off, r);
return r;
}
private final int read4 () throws IOException
{
int byte0 = in.read();
int byte1 = in.read();
int byte2 = in.read();
int byte3 = in.read();
if (byte3 < 0)
throw new ZipException (".zip archive ended prematurely");
return ((byte3 & 0xFF) << 24) + ((byte2 & 0xFF) << 16)
+ ((byte1 & 0xFF) << 8) + (byte0 & 0xFF);
}
// Checksum used by this input stream.
protected CRC32 crc;
// Indicates whether end-of-stream has been reached.
protected boolean eos;
// Some constants from zlib.
static final int Z_DEFLATED = 8;
static final int HEAD_CRC = 0x02;
static final int EXTRA_FIELD = 0x04;
static final int ORIG_NAME = 0x08;
static final int COMMENT = 0x10;
static final int RESERVED = 0xe0;
}
|