public DeflateStream(Stream stream, ZLibMode mode, ZLibCompLevel level, bool leaveOpen) { NativeMethods.CheckZLibLoaded(); _zstream = new ZStream(); _zstreamPtr = GCHandle.Alloc(_zstream, GCHandleType.Pinned); _leaveOpen = leaveOpen; _baseStream = stream; _mode = mode; _internalBufPos = 0; Debug.Assert(0 < NativeMethods.BufferSize, "Internal Logic Error at DeflateStream"); _internalBuf = new byte[NativeMethods.BufferSize]; ZLibReturnCode ret; if (_mode == ZLibMode.Compress) { ret = NativeMethods.DeflateInit(_zstream, level, WriteType); } else { ret = NativeMethods.InflateInit(_zstream, OpenType); } ZLibException.CheckZLibOK(ret, _zstream); }
public override int Read(byte[] buffer, int offset, int count) { if (_mode != ZLibMode.Decompress) { throw new NotSupportedException("Read() not supported on compression"); } ValidateReadWriteArgs(buffer, offset, count); int readLen = 0; if (_internalBufPos != -1) { using (PinnedArray pinRead = new PinnedArray(_internalBuf)) // [In] Compressed using (PinnedArray pinWrite = new PinnedArray(buffer)) // [Out] Will-be-decompressed { _zstream.NextIn = pinRead[_internalBufPos]; _zstream.NextOut = pinWrite[offset]; _zstream.AvailOut = (uint)count; while (0 < _zstream.AvailOut) { if (_zstream.AvailIn == 0) { // Compressed Data is no longer available in array, so read more from _stream int baseReadSize = _baseStream.Read(_internalBuf, 0, _internalBuf.Length); _internalBufPos = 0; _zstream.NextIn = pinRead; _zstream.AvailIn = (uint)baseReadSize; TotalIn += baseReadSize; } uint inCount = _zstream.AvailIn; uint outCount = _zstream.AvailOut; // flush method for inflate has no effect ZLibReturnCode ret = NativeMethods.Inflate(_zstream, ZLibFlush.NO_FLUSH); _internalBufPos += (int)(inCount - _zstream.AvailIn); readLen += (int)(outCount - _zstream.AvailOut); if (ret == ZLibReturnCode.STREAM_END) { _internalBufPos = -1; // magic for StreamEnd break; } ZLibException.CheckZLibOK(ret, _zstream); } TotalOut += readLen; } } return(readLen); }
public override void Write(byte[] buffer, int offset, int count) { if (_mode != ZLibMode.Compress) { throw new NotSupportedException("Write() not supported on decompression"); } TotalIn += count; using (PinnedArray pinRead = new PinnedArray(buffer)) using (PinnedArray pinWrite = new PinnedArray(_internalBuf)) { _zstream.NextIn = pinRead[offset]; _zstream.AvailIn = (uint)count; _zstream.NextOut = pinWrite[_internalBufPos]; _zstream.AvailOut = (uint)(_internalBuf.Length - _internalBufPos); while (_zstream.AvailIn != 0) { uint outCount = _zstream.AvailOut; ZLibReturnCode ret = NativeMethods.Deflate(_zstream, ZLibFlush.NO_FLUSH); _internalBufPos += (int)(outCount - _zstream.AvailOut); if (_zstream.AvailOut == 0) { _baseStream.Write(_internalBuf, 0, _internalBuf.Length); TotalOut += _internalBuf.Length; _internalBufPos = 0; _zstream.NextOut = pinWrite; _zstream.AvailOut = (uint)_internalBuf.Length; } ZLibException.CheckZLibOK(ret, _zstream); } } }