bool ReadHeader() { // Initialize CRC for this block crc = new Crc32(); // Make sure there is data in file. We can't rely on ReadLeByte() to fill the buffer, as this could be EOF, // which is fine, but ReadLeByte() throws an exception if it doesn't find data, so we do this part ourselves. if (inputBuffer.Available <= 0) { inputBuffer.Fill(); if (inputBuffer.Available <= 0) { // No header, EOF. return false; } } // 1. Check the two magic bytes Crc32 headCRC = new Crc32(); int magic = inputBuffer.ReadLeByte(); if (magic < 0) { throw new EndOfStreamException("EOS reading GZIP header"); } headCRC.Update(magic); if (magic != (GZipConstants.GZIP_MAGIC >> 8)) { throw new GZipException("Error GZIP header, first magic byte doesn't match"); } //magic = baseInputStream.ReadByte(); magic = inputBuffer.ReadLeByte(); if (magic < 0) { throw new EndOfStreamException("EOS reading GZIP header"); } if (magic != (GZipConstants.GZIP_MAGIC & 0xFF)) { throw new GZipException("Error GZIP header, second magic byte doesn't match"); } headCRC.Update(magic); // 2. Check the compression type (must be 8) int compressionType = inputBuffer.ReadLeByte(); if (compressionType < 0) { throw new EndOfStreamException("EOS reading GZIP header"); } if (compressionType != 8) { throw new GZipException("Error GZIP header, data not in deflate format"); } headCRC.Update(compressionType); // 3. Check the flags int flags = inputBuffer.ReadLeByte(); if (flags < 0) { throw new EndOfStreamException("EOS reading GZIP header"); } headCRC.Update(flags); /* This flag byte is divided into individual bits as follows: bit 0 FTEXT bit 1 FHCRC bit 2 FEXTRA bit 3 FNAME bit 4 FCOMMENT bit 5 reserved bit 6 reserved bit 7 reserved */ // 3.1 Check the reserved bits are zero if ((flags & 0xE0) != 0) { throw new GZipException("Reserved flag bits in GZIP header != 0"); } // 4.-6. Skip the modification time, extra flags, and OS type for (int i = 0; i < 6; i++) { int readByte = inputBuffer.ReadLeByte(); if (readByte < 0) { throw new EndOfStreamException("EOS reading GZIP header"); } headCRC.Update(readByte); } // 7. Read extra field if ((flags & GZipConstants.FEXTRA) != 0) { // Skip subfield id for (int i = 0; i < 2; i++) { int readByte = inputBuffer.ReadLeByte(); if (readByte < 0) { throw new EndOfStreamException("EOS reading GZIP header"); } headCRC.Update(readByte); } if (inputBuffer.ReadLeByte() < 0 || inputBuffer.ReadLeByte() < 0) { throw new EndOfStreamException("EOS reading GZIP header"); } int len1, len2; len1 = inputBuffer.ReadLeByte(); len2 = inputBuffer.ReadLeByte(); if ((len1 < 0) || (len2 < 0)) { throw new EndOfStreamException("EOS reading GZIP header"); } headCRC.Update(len1); headCRC.Update(len2); int extraLen = (len1 << 8) | len2; for (int i = 0; i < extraLen; i++) { int readByte = inputBuffer.ReadLeByte(); if (readByte < 0) { throw new EndOfStreamException("EOS reading GZIP header"); } headCRC.Update(readByte); } } // 8. Read file name if ((flags & GZipConstants.FNAME) != 0) { int readByte; while ((readByte = inputBuffer.ReadLeByte()) > 0) { headCRC.Update(readByte); } if (readByte < 0) { throw new EndOfStreamException("EOS reading GZIP header"); } headCRC.Update(readByte); } // 9. Read comment if ((flags & GZipConstants.FCOMMENT) != 0) { int readByte; while ((readByte = inputBuffer.ReadLeByte()) > 0) { headCRC.Update(readByte); } if (readByte < 0) { throw new EndOfStreamException("EOS reading GZIP header"); } headCRC.Update(readByte); } // 10. Read header CRC if ((flags & GZipConstants.FHCRC) != 0) { int tempByte; int crcval = inputBuffer.ReadLeByte(); if (crcval < 0) { throw new EndOfStreamException("EOS reading GZIP header"); } tempByte = inputBuffer.ReadLeByte(); if (tempByte < 0) { throw new EndOfStreamException("EOS reading GZIP header"); } crcval = (crcval << 8) | tempByte; if (crcval != ((int)headCRC.Value & 0xffff)) { throw new GZipException("Header CRC value mismatch"); } } readGZIPHeader = true; return true; }
bool ReadHeader() { // Initialize CRC for this block crc = new Crc32(); // Make sure there is data in file. We can't rely on ReadLeByte() to fill the buffer, as this could be EOF, // which is fine, but ReadLeByte() throws an exception if it doesn't find data, so we do this part ourselves. if (inputBuffer.Available <= 0) { inputBuffer.Fill(); if (inputBuffer.Available <= 0) { // No header, EOF. return(false); } } // 1. Check the two magic bytes Crc32 headCRC = new Crc32(); int magic = inputBuffer.ReadLeByte(); if (magic < 0) { throw new EndOfStreamException("EOS reading GZIP header"); } headCRC.Update(magic); if (magic != (GZipConstants.GZIP_MAGIC >> 8)) { throw new GZipException("Error GZIP header, first magic byte doesn't match"); } //magic = baseInputStream.ReadByte(); magic = inputBuffer.ReadLeByte(); if (magic < 0) { throw new EndOfStreamException("EOS reading GZIP header"); } if (magic != (GZipConstants.GZIP_MAGIC & 0xFF)) { throw new GZipException("Error GZIP header, second magic byte doesn't match"); } headCRC.Update(magic); // 2. Check the compression type (must be 8) int compressionType = inputBuffer.ReadLeByte(); if (compressionType < 0) { throw new EndOfStreamException("EOS reading GZIP header"); } if (compressionType != 8) { throw new GZipException("Error GZIP header, data not in deflate format"); } headCRC.Update(compressionType); // 3. Check the flags int flags = inputBuffer.ReadLeByte(); if (flags < 0) { throw new EndOfStreamException("EOS reading GZIP header"); } headCRC.Update(flags); /* This flag byte is divided into individual bits as follows: * * bit 0 FTEXT * bit 1 FHCRC * bit 2 FEXTRA * bit 3 FNAME * bit 4 FCOMMENT * bit 5 reserved * bit 6 reserved * bit 7 reserved */ // 3.1 Check the reserved bits are zero if ((flags & 0xE0) != 0) { throw new GZipException("Reserved flag bits in GZIP header != 0"); } // 4.-6. Skip the modification time, extra flags, and OS type for (int i = 0; i < 6; i++) { int readByte = inputBuffer.ReadLeByte(); if (readByte < 0) { throw new EndOfStreamException("EOS reading GZIP header"); } headCRC.Update(readByte); } // 7. Read extra field if ((flags & GZipConstants.FEXTRA) != 0) { // Skip subfield id for (int i = 0; i < 2; i++) { int readByte = inputBuffer.ReadLeByte(); if (readByte < 0) { throw new EndOfStreamException("EOS reading GZIP header"); } headCRC.Update(readByte); } if (inputBuffer.ReadLeByte() < 0 || inputBuffer.ReadLeByte() < 0) { throw new EndOfStreamException("EOS reading GZIP header"); } int len1, len2; len1 = inputBuffer.ReadLeByte(); len2 = inputBuffer.ReadLeByte(); if ((len1 < 0) || (len2 < 0)) { throw new EndOfStreamException("EOS reading GZIP header"); } headCRC.Update(len1); headCRC.Update(len2); int extraLen = (len1 << 8) | len2; for (int i = 0; i < extraLen; i++) { int readByte = inputBuffer.ReadLeByte(); if (readByte < 0) { throw new EndOfStreamException("EOS reading GZIP header"); } headCRC.Update(readByte); } } // 8. Read file name if ((flags & GZipConstants.FNAME) != 0) { int readByte; while ((readByte = inputBuffer.ReadLeByte()) > 0) { headCRC.Update(readByte); } if (readByte < 0) { throw new EndOfStreamException("EOS reading GZIP header"); } headCRC.Update(readByte); } // 9. Read comment if ((flags & GZipConstants.FCOMMENT) != 0) { int readByte; while ((readByte = inputBuffer.ReadLeByte()) > 0) { headCRC.Update(readByte); } if (readByte < 0) { throw new EndOfStreamException("EOS reading GZIP header"); } headCRC.Update(readByte); } // 10. Read header CRC if ((flags & GZipConstants.FHCRC) != 0) { int tempByte; int crcval = inputBuffer.ReadLeByte(); if (crcval < 0) { throw new EndOfStreamException("EOS reading GZIP header"); } tempByte = inputBuffer.ReadLeByte(); if (tempByte < 0) { throw new EndOfStreamException("EOS reading GZIP header"); } crcval = (crcval << 8) | tempByte; if (crcval != ((int)headCRC.Value & 0xffff)) { throw new GZipException("Header CRC value mismatch"); } } readGZIPHeader = true; return(true); }