/// <exception cref="NotSupportedException">The stream must be in decompress mode to read from.</exception> /// <exception cref="ArgumentNullException"><paramref name="p"/> is <see langword="null" />.</exception> /// <exception cref="ArgumentOutOfRangeException">length cannot be negative.</exception> /// <exception cref="ObjectDisposedException">The method cannot be called after the object has been disposed.</exception> public unsafe int Read(byte *p, int length) { if (!CanRead) { throw new NotSupportedException($"{nameof(GZipStream)} must be in decompress mode to read from"); } if (p == null) { throw new ArgumentNullException(nameof(p)); } if (length < 0) { throw new ArgumentOutOfRangeException(nameof(length), "length cannot be negative"); } if (_isDisposed) { throw new ObjectDisposedException(nameof(GZipStream)); } Contract.EndContractBlock(); var exitLoop = false; _zstream.next_out = p; _zstream.avail_out = (uint)length; while (_zstream.avail_out > 0 && exitLoop == false) { if (_zstream.avail_in == 0) { var readLength = _stream.Read(_tmpBuffer, 0, _tmpBuffer.Length); _zstream.avail_in = (uint)readLength; _zstream.next_in = (byte *)_tmpBufferPtr; } var result = ZLibNative.inflate(ref _zstream, ZLibFlush.NoFlush); switch (result) { case ZLibReturnCode.StreamEnd: exitLoop = true; break; case ZLibReturnCode.Ok: break; case ZLibReturnCode.MemError: throw new OutOfMemoryException($"ZLib return code: {result}"); default: throw new Exception($"ZLib return code: {result}"); } } return(length - (int)_zstream.avail_out); }