public override Task<int> ReadAsync(byte[] array, int offset, int count, CancellationToken cancellationToken)
{
EnsureDecompressionMode();
// We use this checking order for compat to earlier versions:
if (_asyncOperations != 0)
throw new InvalidOperationException(SR.InvalidBeginCall);
ValidateParameters(array, offset, count);
EnsureNotDisposed();
if (cancellationToken.IsCancellationRequested)
{
return Task.FromCanceled<int>(cancellationToken);
}
Interlocked.Increment(ref _asyncOperations);
Task<int> readTask = null;
try
{
// Try to read decompressed data in output buffer
int bytesRead = _inflater.Inflate(array, offset, count);
if (bytesRead != 0)
{
// If decompression output buffer is not empty, return immediately.
return Task.FromResult(bytesRead);
}
if (_inflater.Finished())
{
// end of compression stream
return Task.FromResult(0);
}
// If there is no data on the output buffer and we are not at
// the end of the stream, we need to get more data from the base stream
readTask = _stream.ReadAsync(_buffer, 0, _buffer.Length, cancellationToken);
if (readTask == null)
{
throw new InvalidOperationException(SR.NotSupported_UnreadableStream);
}
return ReadAsyncCore(readTask, array, offset, count, cancellationToken);
}
finally
{
// if we haven't started any async work, decrement the counter to end the transaction
if (readTask == null)
{
Interlocked.Decrement(ref _asyncOperations);
}
}
}