/// <summary> /// Read from the stream /// </summary> /// <param name="buffer">the buffer to read</param> /// <param name="offset">the offset at which to start</param> /// <param name="count">the number of bytes to read</param> /// <returns>the number of bytes actually read</returns> public override int Read(byte[] buffer, int offset, int count) { int bytesToRead = count; // Need to limit the # of bytes returned, if the stream is intended to have // a definite length. This is especially useful when returning a stream for // the uncompressed data directly to the application. The app won't // necessarily read only the UncompressedSize number of bytes. For example // wrapping the stream returned from OpenReader() into a StreadReader() and // calling ReadToEnd() on it, We can "over-read" the zip data and get a // corrupt string. The length limits that, prevents that problem. if (_lengthLimit != CrcCalculatorStream.UnsetLengthLimit) { if (_Crc32.TotalBytesRead >= _lengthLimit) { return(0); // EOF } Int64 bytesRemaining = _lengthLimit - _Crc32.TotalBytesRead; if (bytesRemaining < count) { bytesToRead = (int)bytesRemaining; } } int n = _innerStream.Read(buffer, offset, bytesToRead); if (n > 0) { _Crc32.SlurpBlock(buffer, offset, n); } return(n); }
public override void Write(System.Byte[] buffer, int offset, int count) { // workitem 7159 // calculate the CRC on the unccompressed data (before writing) if (crc != null) crc.SlurpBlock(buffer, offset, count); if (_streamMode == StreamMode.Undefined) _streamMode = StreamMode.Writer; else if (_streamMode != StreamMode.Writer) throw new ZlibException("Cannot Write after Reading."); if (count == 0) return; // first reference of z property will initialize the private var _z z.InputBuffer = buffer; _z.NextIn = offset; _z.AvailableBytesIn = count; bool done = false; do { _z.OutputBuffer = workingBuffer; _z.NextOut = 0; _z.AvailableBytesOut = _workingBuffer.Length; int rc = (_wantCompress) ? _z.Deflate(_flushMode) : _z.Inflate(_flushMode); if (rc != ZlibConstants.Z_OK && rc != ZlibConstants.Z_STREAM_END) throw new ZlibException((_wantCompress ? "de" : "in") + "flating: " + _z.Message); //if (_workingBuffer.Length - _z.AvailableBytesOut > 0) _stream.Write(_workingBuffer, 0, _workingBuffer.Length - _z.AvailableBytesOut); done = _z.AvailableBytesIn == 0 && _z.AvailableBytesOut != 0; // If GZIP and de-compress, we're done when 8 bytes remain. if (_flavor == ZlibStreamFlavor.GZIP && !_wantCompress) done = (_z.AvailableBytesIn == 8 && _z.AvailableBytesOut != 0); } while (!done); }
public ZipReturn CenteralDirectoryRead() { try { BinaryReader br = new BinaryReader(_zipFs); uint thisSignature = br.ReadUInt32(); if (thisSignature != CentralDirectoryHeaderSigniature) return ZipReturn.ZipCenteralDirError; br.ReadUInt16(); // Version Made By br.ReadUInt16(); // Version Needed To Extract _generalPurposeBitFlag = br.ReadUInt16(); _compressionMethod = br.ReadUInt16(); if (_compressionMethod != 8 && _compressionMethod != 0) return ZipReturn.ZipUnsupportedCompression; _lastModFileTime = br.ReadUInt16(); _lastModFileDate = br.ReadUInt16(); CRC = ReadCRC(br); _compressedSize = br.ReadUInt32(); UncompressedSize = br.ReadUInt32(); ushort fileNameLength = br.ReadUInt16(); ushort extraFieldLength = br.ReadUInt16(); ushort fileCommentLength = br.ReadUInt16(); br.ReadUInt16(); // diskNumberStart br.ReadUInt16(); // internalFileAttributes br.ReadUInt32(); // externalFileAttributes RelativeOffsetOfLocalHeader = br.ReadUInt32(); byte[] bFileName = br.ReadBytes(fileNameLength); FileName = (_generalPurposeBitFlag & (1 << 11)) == 0 ? GetString(bFileName) : Encoding.UTF8.GetString(bFileName, 0, fileNameLength); Byte[] extraField = br.ReadBytes(extraFieldLength); br.ReadBytes(fileCommentLength); // File Comments int pos = 0; while (extraFieldLength > pos) { ushort type = BitConverter.ToUInt16(extraField, pos); pos += 2; ushort blockLength = BitConverter.ToUInt16(extraField, pos); pos += 2; switch (type) { case 0x0001: Zip64 = true; if (UncompressedSize == 0xffffffff) { UncompressedSize = BitConverter.ToUInt64(extraField, pos); pos += 8; } if (_compressedSize == 0xffffffff) { _compressedSize = BitConverter.ToUInt64(extraField, pos); pos += 8; } if (RelativeOffsetOfLocalHeader == 0xffffffff) { RelativeOffsetOfLocalHeader = BitConverter.ToUInt64(extraField, pos); pos += 8; } break; case 0x7075: //byte version = extraField[pos]; pos += 1; uint nameCRC32 = BitConverter.ToUInt32(extraField, pos); pos += 4; CRC32 crcTest = new CRC32(); crcTest.SlurpBlock(bFileName, 0, fileNameLength); uint fCRC = crcTest.Crc32ResultU; if (nameCRC32 != fCRC) return ZipReturn.ZipCenteralDirError; int charLen = blockLength - 5; FileName = Encoding.UTF8.GetString(extraField, pos, charLen); pos += charLen; break; default: pos += blockLength; break; } } return ZipReturn.ZipGood; } catch { return ZipReturn.ZipCenteralDirError; } }
public ZipReturn LocalFileHeaderReadQuick() { try { TrrntZip = true; BinaryReader br = new BinaryReader(_zipFs); _zipFs.Position = (long)RelativeOffsetOfLocalHeader; uint thisSignature = br.ReadUInt32(); if (thisSignature != LocalFileHeaderSignature) return ZipReturn.ZipLocalFileHeaderError; br.ReadUInt16(); // version needed to extract _generalPurposeBitFlag = br.ReadUInt16(); if ((_generalPurposeBitFlag & 8) == 8) return ZipReturn.ZipCannotFastOpen; _compressionMethod = br.ReadUInt16(); _lastModFileTime = br.ReadUInt16(); _lastModFileDate = br.ReadUInt16(); CRC = ReadCRC(br); _compressedSize = br.ReadUInt32(); UncompressedSize = br.ReadUInt32(); ushort fileNameLength = br.ReadUInt16(); ushort extraFieldLength = br.ReadUInt16(); byte[] bFileName = br.ReadBytes(fileNameLength); FileName = (_generalPurposeBitFlag & (1 << 11)) == 0 ? GetString(bFileName) : Encoding.UTF8.GetString(bFileName, 0, fileNameLength); byte[] extraField = br.ReadBytes(extraFieldLength); Zip64 = false; int pos = 0; while (extraFieldLength > pos) { ushort type = BitConverter.ToUInt16(extraField, pos); pos += 2; ushort blockLength = BitConverter.ToUInt16(extraField, pos); pos += 2; switch (type) { case 0x0001: Zip64 = true; if (UncompressedSize == 0xffffffff) { UncompressedSize = BitConverter.ToUInt64(extraField, pos); pos += 8; } if (_compressedSize == 0xffffffff) { _compressedSize = BitConverter.ToUInt64(extraField, pos); pos += 8; } break; case 0x7075: pos += 1; uint nameCRC32 = BitConverter.ToUInt32(extraField, pos); pos += 4; CRC32 crcTest = new CRC32(); crcTest.SlurpBlock(bFileName, 0, fileNameLength); uint fCRC = crcTest.Crc32ResultU; if (nameCRC32 != fCRC) return ZipReturn.ZipLocalFileHeaderError; int charLen = blockLength - 5; FileName = Encoding.UTF8.GetString(extraField, pos, charLen); pos += charLen; break; default: pos += blockLength; break; } } _dataLocation = (ulong)_zipFs.Position; return ZipReturn.ZipGood; } catch { return ZipReturn.ZipLocalFileHeaderError; } }
public ZipReturn LocalFileHeaderRead() { try { TrrntZip = true; BinaryReader br = new BinaryReader(_zipFs); _zipFs.Position = (long)RelativeOffsetOfLocalHeader; uint thisSignature = br.ReadUInt32(); if (thisSignature != LocalFileHeaderSignature) return ZipReturn.ZipLocalFileHeaderError; br.ReadUInt16(); // version needed to extract ushort generalPurposeBitFlagLocal = br.ReadUInt16(); if (generalPurposeBitFlagLocal != _generalPurposeBitFlag) TrrntZip = false; ushort tshort = br.ReadUInt16(); if (tshort != _compressionMethod) return ZipReturn.ZipLocalFileHeaderError; tshort = br.ReadUInt16(); if (tshort != _lastModFileTime) return ZipReturn.ZipLocalFileHeaderError; tshort = br.ReadUInt16(); if (tshort != _lastModFileDate) return ZipReturn.ZipLocalFileHeaderError; byte[] tCRC = ReadCRC(br); if (((_generalPurposeBitFlag & 8) == 0) && !ByteArrCompare(tCRC, CRC)) return ZipReturn.ZipLocalFileHeaderError; uint tCompressedSize = br.ReadUInt32(); if (Zip64 && tCompressedSize != 0xffffffff && tCompressedSize != _compressedSize) // if Zip64 File then the compressedSize should be 0xffffffff return ZipReturn.ZipLocalFileHeaderError; if ((_generalPurposeBitFlag & 8) == 8 && tCompressedSize != 0) // if bit 4 set then no compressedSize is set yet return ZipReturn.ZipLocalFileHeaderError; if (!Zip64 && (_generalPurposeBitFlag & 8) != 8 && tCompressedSize != _compressedSize) // check the compressedSize return ZipReturn.ZipLocalFileHeaderError; uint tUnCompressedSize = br.ReadUInt32(); if (Zip64 && tUnCompressedSize != 0xffffffff && tUnCompressedSize != UncompressedSize) // if Zip64 File then the unCompressedSize should be 0xffffffff return ZipReturn.ZipLocalFileHeaderError; if ((_generalPurposeBitFlag & 8) == 8 && tUnCompressedSize != 0) // if bit 4 set then no unCompressedSize is set yet return ZipReturn.ZipLocalFileHeaderError; if (!Zip64 && (_generalPurposeBitFlag & 8) != 8 && tUnCompressedSize != UncompressedSize) // check the unCompressedSize return ZipReturn.ZipLocalFileHeaderError; ushort fileNameLength = br.ReadUInt16(); ushort extraFieldLength = br.ReadUInt16(); byte[] bFileName = br.ReadBytes(fileNameLength); string tFileName = (generalPurposeBitFlagLocal & (1 << 11)) == 0 ? GetString(bFileName) : Encoding.UTF8.GetString(bFileName, 0, fileNameLength); byte[] extraField = br.ReadBytes(extraFieldLength); Zip64 = false; int pos = 0; while (extraFieldLength > pos) { ushort type = BitConverter.ToUInt16(extraField, pos); pos += 2; ushort blockLength = BitConverter.ToUInt16(extraField, pos); pos += 2; switch (type) { case 0x0001: Zip64 = true; if (tUnCompressedSize == 0xffffffff) { ulong tLong = BitConverter.ToUInt64(extraField, pos); if (tLong != UncompressedSize) return ZipReturn.ZipLocalFileHeaderError; pos += 8; } if (tCompressedSize == 0xffffffff) { ulong tLong = BitConverter.ToUInt64(extraField, pos); if (tLong != _compressedSize) return ZipReturn.ZipLocalFileHeaderError; pos += 8; } break; case 0x7075: //byte version = extraField[pos]; pos += 1; uint nameCRC32 = BitConverter.ToUInt32(extraField, pos); pos += 4; CRC32 crcTest = new CRC32(); crcTest.SlurpBlock(bFileName, 0, fileNameLength); uint fCRC = crcTest.Crc32ResultU; if (nameCRC32 != fCRC) return ZipReturn.ZipLocalFileHeaderError; int charLen = blockLength - 5; tFileName = Encoding.UTF8.GetString(extraField, pos, charLen); pos += charLen; break; default: pos += blockLength; break; } } if (!CompareString(FileName, tFileName)) return ZipReturn.ZipLocalFileHeaderError; _dataLocation = (ulong)_zipFs.Position; if ((_generalPurposeBitFlag & 8) == 0) return ZipReturn.ZipGood; _zipFs.Position += (long)_compressedSize; tCRC = ReadCRC(br); if (!ByteArrCompare(tCRC, new byte[] { 0x50, 0x4b, 0x07, 0x08 })) tCRC = ReadCRC(br); if (!ByteArrCompare(tCRC, CRC)) return ZipReturn.ZipLocalFileHeaderError; uint tint = br.ReadUInt32(); if (tint != _compressedSize) return ZipReturn.ZipLocalFileHeaderError; tint = br.ReadUInt32(); if (tint != UncompressedSize) return ZipReturn.ZipLocalFileHeaderError; return ZipReturn.ZipGood; } catch { return ZipReturn.ZipLocalFileHeaderError; } }
protected override void HashCore(byte[] buffer, int start, int length) { _Crc32.SlurpBlock(buffer, start, length); }