1 25 package org.archive.io; 26 27 import java.io.EOFException ; 28 import java.io.IOException ; 29 import java.io.InputStream ; 30 import java.util.zip.CRC32 ; 31 import java.util.zip.Deflater ; 32 import java.util.zip.GZIPInputStream ; 33 34 49 public class GzipHeader { 50 55 public static final int MINIMAL_GZIP_HEADER_LENGTH = 10; 56 57 60 protected int length = 0; 61 62 65 protected int flg; 66 67 70 private int xfl; 71 72 75 private int os; 76 77 80 private byte [] fextra = null; 81 82 85 private int mtime; 86 87 88 93 public GzipHeader() { 94 super(); 95 } 96 97 105 public GzipHeader(InputStream in) throws IOException { 106 super(); 107 readHeader(in); 108 } 109 110 118 public void readHeader(InputStream in) throws IOException { 119 CRC32 crc = new CRC32 (); 120 crc.reset(); 121 if (!testGzipMagic(in, crc)) { 122 throw new NoGzipMagicException(); 123 } 124 this.length += 2; 125 if (readByte(in, crc) != Deflater.DEFLATED) { 126 throw new IOException ("Unknown compression"); 127 } 128 this.length++; 129 130 this.flg = readByte(in, crc); 132 this.length++; 133 134 this.mtime = readInt(in, crc); 136 this.length += 4; 137 138 this.xfl = readByte(in, crc); 140 this.length++; 141 this.os = readByte(in, crc); 142 this.length++; 143 144 final int FLG_FEXTRA = 4; 146 if ((this.flg & FLG_FEXTRA) == FLG_FEXTRA) { 147 int count = readShort(in, crc); 148 this.length +=2; 149 this.fextra = new byte[count]; 150 readByte(in, crc, this.fextra, 0, count); 151 this.length += count; 152 } 153 154 final int FLG_FNAME = 8; 156 if ((this.flg & FLG_FNAME) == FLG_FNAME) { 157 while (readByte(in, crc) != 0) { 158 this.length++; 159 } 160 } 161 162 final int FLG_FCOMMENT = 16; if ((this.flg & FLG_FCOMMENT) == FLG_FCOMMENT) { 165 while (readByte(in, crc) != 0) { 166 this.length++; 167 } 168 } 169 170 final int FLG_FHCRC = 2; 172 if ((this.flg & FLG_FHCRC) == FLG_FHCRC) { 173 int calcCrc = (int)(crc.getValue() & 0xffff); 174 if (readShort(in, crc) != calcCrc) { 175 throw new IOException ("Bad header CRC"); 176 } 177 this.length += 2; 178 } 179 } 180 181 189 public boolean testGzipMagic(InputStream in) throws IOException { 190 return testGzipMagic(in, null); 191 } 192 193 202 public boolean testGzipMagic(InputStream in, CRC32 crc) 203 throws IOException { 204 return readShort(in, crc) == GZIPInputStream.GZIP_MAGIC; 205 } 206 207 219 private int readInt(InputStream in, CRC32 crc) throws IOException { 220 int s = readShort(in, crc); 221 return ((readShort(in, crc) << 16) & 0xffff0000) | s; 222 } 223 224 236 private int readShort(InputStream in, CRC32 crc) throws IOException { 237 int b = readByte(in, crc); 238 return ((readByte(in, crc) << 8) & 0x00ff00) | b; 239 } 240 241 252 protected int readByte(InputStream in) throws IOException { 253 return readByte(in, null); 254 } 255 256 268 protected int readByte(InputStream in, CRC32 crc) throws IOException { 269 int b = in.read(); 270 if (b == -1) { 271 throw new EOFException (); 272 } 273 if (crc != null) { 274 crc.update(b); 275 } 276 return b & 0xff; 277 } 278 279 294 protected int readByte(InputStream in, CRC32 crc, byte [] buffer, 295 int offset, int length) 296 throws IOException { 297 for (int i = offset; i < length; i++) { 298 buffer[offset + i] = (byte)readByte(in, crc); 299 } 300 return length; 301 } 302 303 306 public byte[] getFextra() { 307 return this.fextra; 308 } 309 310 313 public int getFlg() { 314 return this.flg; 315 } 316 317 320 public int getOs() { 321 return this.os; 322 } 323 324 327 public int getXfl() { 328 return this.xfl; 329 } 330 331 334 public int getMtime() { 335 return this.mtime; 336 } 337 338 341 public int getLength() { 342 return length; 343 } 344 } 345 | Popular Tags |