diff --git a/src/ICSharpCode.SharpZipLib/Encryption/ZipAESStream.cs b/src/ICSharpCode.SharpZipLib/Encryption/ZipAESStream.cs
index 80ce0b4ab..09dd3a6be 100644
--- a/src/ICSharpCode.SharpZipLib/Encryption/ZipAESStream.cs
+++ b/src/ICSharpCode.SharpZipLib/Encryption/ZipAESStream.cs
@@ -67,6 +67,44 @@ public ZipAESStream(Stream stream, ZipAESTransform transform, CryptoStreamMode m
/// and advances the position within the stream by the number of bytes read.
///
public override int Read(byte[] buffer, int offset, int count)
+ {
+ // If we have buffered data, read that first
+ int nBytes = ReadDataFromBuffer(buffer, ref offset, ref count);
+
+ // If we've read the requested amount of data, return just that
+ if (count == 0)
+ return nBytes;
+
+ // Read more data from the input, if available
+ if (_slideBuffer != null)
+ {
+ nBytes += ReadAndTransformAsync(buffer, offset, count, false, default).GetAwaiter().GetResult();
+ }
+
+ return nBytes;
+ }
+
+ ///
+ public override async Task ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
+ {
+ // If we have buffered data, read that first
+ int nBytes = ReadDataFromBuffer(buffer, ref offset, ref count);
+
+ // If we've read the requested amount of data, return just that
+ if (count == 0)
+ return nBytes;
+
+ // Read more data from the input, if available
+ if (_slideBuffer != null)
+ {
+ nBytes += await ReadAndTransformAsync(buffer, offset, count, true, cancellationToken).ConfigureAwait(false);
+ }
+
+ return nBytes;
+ }
+
+ // Read up to the requested amount of data from the buffer
+ private int ReadDataFromBuffer(byte[] buffer, ref int offset, ref int count)
{
// Nothing to do
if (count == 0)
@@ -78,30 +116,15 @@ public override int Read(byte[] buffer, int offset, int count)
{
nBytes = ReadBufferedData(buffer, offset, count);
- // Read all requested data from the buffer
- if (nBytes == count)
- return nBytes;
-
offset += nBytes;
count -= nBytes;
}
- // Read more data from the input, if available
- if (_slideBuffer != null)
- nBytes += ReadAndTransform(buffer, offset, count);
-
return nBytes;
}
- ///
- public override Task ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
- {
- var readCount = Read(buffer, offset, count);
- return Task.FromResult(readCount);
- }
-
// Read data from the underlying stream and decrypt it
- private int ReadAndTransform(byte[] buffer, int offset, int count)
+ private async Task ReadAndTransformAsync(byte[] buffer, int offset, int count, bool useAsync, CancellationToken cancellationToken)
{
int nBytes = 0;
while (nBytes < count)
@@ -126,7 +149,11 @@ private int ReadAndTransform(byte[] buffer, int offset, int count)
_slideBufFreePos -= _slideBufStartPos; // Note the -=
_slideBufStartPos = 0;
}
- int obtained = StreamUtils.ReadRequestedBytes(_stream, _slideBuffer, _slideBufFreePos, lengthToRead);
+
+ int obtained = useAsync ?
+ await StreamUtils.ReadRequestedBytesAsync(_stream, _slideBuffer, _slideBufFreePos, lengthToRead, cancellationToken).ConfigureAwait(false) :
+ StreamUtils.ReadRequestedBytes(_stream, _slideBuffer, _slideBufFreePos, lengthToRead);
+
_slideBufFreePos += obtained;
// Recalculate how much data we now have