Merge fixes

This commit is contained in:
Adam Hathcock
2026-01-26 14:20:42 +00:00
parent 04eabb7866
commit 979c8d9234
5 changed files with 18 additions and 137 deletions

View File

@@ -35,25 +35,11 @@ public partial class EntryStream
{
if (ss.BaseStream() is SharpCompress.Compressors.Deflate.DeflateStream deflateStream)
{
try
{
await deflateStream.FlushAsync().ConfigureAwait(false); //Deflate over reads. Knock it back
}
catch (NotSupportedException)
{
// Ignore: underlying stream does not support required operations for Flush
}
await deflateStream.FlushAsync().ConfigureAwait(false);
}
else if (ss.BaseStream() is SharpCompress.Compressors.LZMA.LzmaStream lzmaStream)
{
try
{
await lzmaStream.FlushAsync().ConfigureAwait(false); //Lzma over reads. Knock it back
}
catch (NotSupportedException)
{
// Ignore: underlying stream does not support required operations for Flush
}
await lzmaStream.FlushAsync().ConfigureAwait(false);
}
}
#if DEBUG_STREAMS

View File

@@ -84,39 +84,6 @@ public partial class EntryStream : Stream, IStreamStack
_stream.Dispose();
}
#if !LEGACY_DOTNET
public override async ValueTask DisposeAsync()
{
if (_isDisposed)
{
return;
}
_isDisposed = true;
if (!(_completed || _reader.Cancelled))
{
await SkipEntryAsync().ConfigureAwait(false);
}
//Need a safe standard approach to this - it's okay for compression to overreads. Handling needs to be standardised
if (_stream is IStreamStack ss)
{
if (ss.BaseStream() is SharpCompress.Compressors.Deflate.DeflateStream deflateStream)
{
await deflateStream.FlushAsync().ConfigureAwait(false);
}
else if (ss.BaseStream() is SharpCompress.Compressors.LZMA.LzmaStream lzmaStream)
{
await lzmaStream.FlushAsync().ConfigureAwait(false);
}
}
#if DEBUG_STREAMS
this.DebugDispose(typeof(EntryStream));
#endif
await base.DisposeAsync().ConfigureAwait(false);
await _stream.DisposeAsync().ConfigureAwait(false);
}
#endif
public override bool CanRead => true;
public override bool CanSeek => false;

View File

@@ -10,14 +10,24 @@ internal partial class BufferedSubStream
{
private async ValueTask RefillCacheAsync(CancellationToken cancellationToken)
{
var count = (int)Math.Min(BytesLeftToRead, _cache.Length);
if (_isDisposed)
{
throw new ObjectDisposedException(nameof(BufferedSubStream));
}
var count = (int)Math.Min(BytesLeftToRead, _cache!.Length);
_cacheOffset = 0;
if (count == 0)
{
_cacheLength = 0;
return;
}
Stream.Position = origin;
// Only seek if we're not already at the correct position
// This avoids expensive seek operations when reading sequentially
if (Stream.CanSeek && Stream.Position != origin)
{
Stream.Position = origin;
}
_cacheLength = await Stream
.ReadAsync(_cache, 0, count, cancellationToken)
.ConfigureAwait(false);
@@ -45,7 +55,7 @@ internal partial class BufferedSubStream
}
count = Math.Min(count, _cacheLength - _cacheOffset);
Buffer.BlockCopy(_cache, _cacheOffset, buffer, offset, count);
Buffer.BlockCopy(_cache!, _cacheOffset, buffer, offset, count);
_cacheOffset += count;
}
@@ -72,7 +82,7 @@ internal partial class BufferedSubStream
}
count = Math.Min(count, _cacheLength - _cacheOffset);
_cache.AsSpan(_cacheOffset, count).CopyTo(buffer.Span);
_cache!.AsSpan(_cacheOffset, count).CopyTo(buffer.Span);
_cacheOffset += count;
}

View File

@@ -94,33 +94,6 @@ internal partial class BufferedSubStream : SharpCompressStream, IStreamStack
BytesLeftToRead -= _cacheLength;
}
private async ValueTask RefillCacheAsync(CancellationToken cancellationToken)
{
if (_isDisposed)
{
throw new ObjectDisposedException(nameof(BufferedSubStream));
}
var count = (int)Math.Min(BytesLeftToRead, _cache!.Length);
_cacheOffset = 0;
if (count == 0)
{
_cacheLength = 0;
return;
}
// Only seek if we're not already at the correct position
// This avoids expensive seek operations when reading sequentially
if (Stream.CanSeek && Stream.Position != origin)
{
Stream.Position = origin;
}
_cacheLength = await Stream
.ReadAsync(_cache, 0, count, cancellationToken)
.ConfigureAwait(false);
origin += _cacheLength;
BytesLeftToRead -= _cacheLength;
}
public override int Read(byte[] buffer, int offset, int count)
{
if (count > Length)
@@ -157,61 +130,6 @@ internal partial class BufferedSubStream : SharpCompressStream, IStreamStack
return _cache![_cacheOffset++];
}
public override async Task<int> ReadAsync(
byte[] buffer,
int offset,
int count,
CancellationToken cancellationToken
)
{
if (count > Length)
{
count = (int)Length;
}
if (count > 0)
{
if (_cacheOffset == _cacheLength)
{
await RefillCacheAsync(cancellationToken).ConfigureAwait(false);
}
count = Math.Min(count, _cacheLength - _cacheOffset);
Buffer.BlockCopy(_cache!, _cacheOffset, buffer, offset, count);
_cacheOffset += count;
}
return count;
}
#if !LEGACY_DOTNET
public override async ValueTask<int> ReadAsync(
Memory<byte> buffer,
CancellationToken cancellationToken = default
)
{
var count = buffer.Length;
if (count > Length)
{
count = (int)Length;
}
if (count > 0)
{
if (_cacheOffset == _cacheLength)
{
await RefillCacheAsync(cancellationToken).ConfigureAwait(false);
}
count = Math.Min(count, _cacheLength - _cacheOffset);
_cache!.AsSpan(_cacheOffset, count).CopyTo(buffer.Span);
_cacheOffset += count;
}
return count;
}
#endif
public override long Seek(long offset, SeekOrigin origin) => throw new NotSupportedException();
public override void SetLength(long value) => throw new NotSupportedException();

View File

@@ -347,7 +347,7 @@ public class ZipReaderAsyncTests : ReaderTests
var path = Path.Combine(TEST_ARCHIVES_PATH, "Zip.deflate.dd.zip");
using var fileStream = File.OpenRead(path);
using Stream stream = new ThrowOnFlushStream(fileStream);
await using var reader = ReaderFactory.OpenAsyncReader(new AsyncOnlyStream(stream));
await using var reader = await ReaderFactory.OpenAsyncReader(new AsyncOnlyStream(stream));
var count = 0;
while (await reader.MoveToNextEntryAsync())
@@ -371,7 +371,7 @@ public class ZipReaderAsyncTests : ReaderTests
var path = Path.Combine(TEST_ARCHIVES_PATH, "Zip.lzma.dd.zip");
using var fileStream = File.OpenRead(path);
using Stream stream = new ThrowOnFlushStream(fileStream);
await using var reader = ReaderFactory.OpenAsyncReader(new AsyncOnlyStream(stream));
await using var reader = await ReaderFactory.OpenAsyncReader(new AsyncOnlyStream(stream));
var count = 0;
while (await reader.MoveToNextEntryAsync())