protected override void Dispose(bool disposing) { if (disposing && !_disposed) { if (BaseStream != null) { if (_mode == ZLibMode.Compress) { Flush(); } if (!_leaveOpen) { BaseStream.Close(); } } if (_zstream != null) { if (_mode == ZLibMode.Compress) { ZLibNative.DeflateEnd(_zstream); } else { ZLibNative.InflateEnd(_zstream); } _zstreamPtr.Free(); _zstream = null; } _disposed = true; } }
public ZLibStream(Stream stream, ZLibMode mode, ZLibCompLevel level, bool leaveOpen = false) { BaseStream = stream; _zstream = new ZStream(); _zstreamPtr = GCHandle.Alloc(_zstream, GCHandleType.Pinned); _leaveOpen = leaveOpen; _mode = mode; _internalBufPos = 0; _internalBuf = new byte[BufferSize]; ZLibReturnCode ret; if (_mode == ZLibMode.Compress) { ret = ZLibNative.DeflateInit(_zstream, level, _writeType); } else { ret = ZLibNative.InflateInit(_zstream, _openType); } if (ret != ZLibReturnCode.OK) { throw new Exception(ret + " " + _zstream.LastErrorMsg); } }
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 = ZLibNative.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; } if (ret != ZLibReturnCode.OK) { throw new Exception(ret + " " + _zstream.LastErrorMsg); } } TotalOut += readLen; } } return(readLen); }
public override void Flush() { if (_mode == ZLibMode.Decompress) { BaseStream.Flush(); return; } using (PinnedArray pinWrite = new PinnedArray(_internalBuf)) { _zstream.NextIn = IntPtr.Zero; _zstream.AvailIn = 0; _zstream.NextOut = pinWrite[_internalBufPos]; _zstream.AvailOut = (uint)(_internalBuf.Length - _internalBufPos); ZLibReturnCode ret = ZLibReturnCode.OK; while (ret != ZLibReturnCode.STREAM_END) { if (_zstream.AvailOut != 0) { uint outCount = _zstream.AvailOut; ret = ZLibNative.Deflate(_zstream, ZLibFlush.FINISH); _internalBufPos += (int)(outCount - _zstream.AvailOut); if (ret != ZLibReturnCode.STREAM_END && ret != ZLibReturnCode.OK) { throw new Exception(ret + " " + _zstream.LastErrorMsg); } } BaseStream.Write(_internalBuf, 0, _internalBufPos); TotalOut += _internalBufPos; _internalBufPos = 0; _zstream.NextOut = pinWrite; _zstream.AvailOut = (uint)_internalBuf.Length; } } BaseStream.Flush(); }
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 = ZLibNative.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; } if (ret != ZLibReturnCode.OK) { throw new Exception(ret + " " + _zstream.LastErrorMsg); } } } }