protected DeflateStream(Stream baseStream, ZLibCompressOptions compOpts, Format format) { ZLibInit.Manager.EnsureLoaded(); BaseStream = baseStream ?? throw new ArgumentNullException(nameof(baseStream)); _mode = Mode.Compress; _disposed = false; // Check and set compress options _leaveOpen = compOpts.LeaveOpen; _bufferSize = CheckBufferSize(compOpts.BufferSize); _workBuf = new byte[_bufferSize]; int formatWindowBits = CheckFormatWindowBits(compOpts.WindowBits, _mode, format); CheckMemLevel(compOpts.MemLevel); // Prepare and init ZStream switch (ZLibInit.Lib.PlatformLongSize) { case PlatformLongSize.Long32: { _zs32 = new ZStreamL32(); _zsPin = GCHandle.Alloc(_zs32, GCHandleType.Pinned); ZLibRet ret = ZLibInit.Lib.L32.DeflateInit(_zs32, compOpts.Level, formatWindowBits, compOpts.MemLevel); ZLibException.CheckReturnValue(ret, _zs32); break; } case PlatformLongSize.Long64: { _zs64 = new ZStreamL64(); _zsPin = GCHandle.Alloc(_zs64, GCHandleType.Pinned); ZLibRet ret = ZLibInit.Lib.L64.DeflateInit(_zs64, compOpts.Level, formatWindowBits, compOpts.MemLevel); ZLibException.CheckReturnValue(ret, _zs64); break; } default: throw new PlatformNotSupportedException(); } }
public unsafe void Write(ReadOnlySpan <byte> span) #endif { if (_mode != Mode.Compress) { throw new NotSupportedException("Write() not supported on decompression"); } TotalIn += span.Length; fixed(byte *readPtr = span) // [In] Compressed fixed(byte *writePtr = _workBuf) // [Out] Will-be-decompressed { switch (ZLibInit.Lib.PlatformLongSize) { case PlatformLongSize.Long32: { _zs32.NextIn = readPtr; _zs32.AvailIn = (uint)span.Length; _zs32.NextOut = writePtr + _workBufPos; _zs32.AvailOut = (uint)(_workBuf.Length - _workBufPos); while (_zs32.AvailIn != 0) { uint outCount = _zs32.AvailOut; ZLibRet ret = ZLibInit.Lib.L32.Deflate(_zs32, ZLibFlush.NoFlush); _workBufPos += (int)(outCount - _zs32.AvailOut); if (_zs32.AvailOut == 0) { BaseStream.Write(_workBuf, 0, _workBuf.Length); TotalOut += _workBuf.Length; _workBufPos = 0; _zs32.NextOut = writePtr; _zs32.AvailOut = (uint)_workBuf.Length; } ZLibException.CheckReturnValue(ret, _zs32); } break; } case PlatformLongSize.Long64: { _zs64.NextIn = readPtr; _zs64.AvailIn = (uint)span.Length; _zs64.NextOut = writePtr + _workBufPos; _zs64.AvailOut = (uint)(_workBuf.Length - _workBufPos); while (_zs64.AvailIn != 0) { uint outCount = _zs64.AvailOut; ZLibRet ret = ZLibInit.Lib.L64.Deflate(_zs64, ZLibFlush.NoFlush); _workBufPos += (int)(outCount - _zs64.AvailOut); if (_zs64.AvailOut == 0) { BaseStream.Write(_workBuf, 0, _workBuf.Length); TotalOut += _workBuf.Length; _workBufPos = 0; _zs64.NextOut = writePtr; _zs64.AvailOut = (uint)_workBuf.Length; } ZLibException.CheckReturnValue(ret, _zs64); } break; } } } }
public unsafe int Read(Span <byte> span) #endif { // For Decompress if (_mode != Mode.Decompress) { throw new NotSupportedException("Read() not supported on compression"); } if (_workBufPos == ReadDone) { return(0); } int readSize = 0; fixed(byte *readPtr = _workBuf) // [In] Compressed fixed(byte *writePtr = span) // [Out] Will-be-decompressed { switch (ZLibInit.Lib.PlatformLongSize) { case PlatformLongSize.Long32: { _zs32.NextIn = readPtr + _workBufPos; _zs32.NextOut = writePtr; _zs32.AvailOut = (uint)span.Length; while (0 < _zs32.AvailOut) { if (_zs32.AvailIn == 0) { // Compressed Data is no longer available in array, so read more from _stream int baseReadSize = BaseStream.Read(_workBuf, 0, _workBuf.Length); _workBufPos = 0; _zs32.NextIn = readPtr; _zs32.AvailIn = (uint)baseReadSize; TotalIn += baseReadSize; } uint inCount = _zs32.AvailIn; uint outCount = _zs32.AvailOut; // flush method for inflate has no effect ZLibRet ret = ZLibInit.Lib.L32.Inflate(_zs32, ZLibFlush.NoFlush); _workBufPos += (int)(inCount - _zs32.AvailIn); readSize += (int)(outCount - _zs32.AvailOut); if (ret == ZLibRet.StreamEnd) { _workBufPos = ReadDone; // magic for StreamEnd break; } ZLibException.CheckReturnValue(ret, _zs32); } } break; case PlatformLongSize.Long64: { _zs64.NextIn = readPtr + _workBufPos; _zs64.NextOut = writePtr; _zs64.AvailOut = (uint)span.Length; while (0 < _zs64.AvailOut) { if (_zs64.AvailIn == 0) { // Compressed Data is no longer available in array, so read more from _stream int baseReadSize = BaseStream.Read(_workBuf, 0, _workBuf.Length); _workBufPos = 0; _zs64.NextIn = readPtr; _zs64.AvailIn = (uint)baseReadSize; TotalIn += baseReadSize; } uint inCount = _zs64.AvailIn; uint outCount = _zs64.AvailOut; // flush method for inflate has no effect ZLibRet ret = ZLibInit.Lib.L64.Inflate(_zs64, ZLibFlush.NoFlush); _workBufPos += (int)(inCount - _zs64.AvailIn); readSize += (int)(outCount - _zs64.AvailOut); if (ret == ZLibRet.StreamEnd) { _workBufPos = ReadDone; // magic for StreamEnd break; } ZLibException.CheckReturnValue(ret, _zs64); } } break; } } TotalOut += readSize; return(readSize); }