Пример #1
0
		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;
		}
Пример #2
0
		/// <summary>
		/// Closes the zip input stream
		/// </summary>
		public override void Close()
		{
			internalReader = new ReadDataHandler(ReadingNotAvailable);
			crc = null;
			entry = null;

			base.Close();
		}