Files
sharpcompress/src/SharpCompress/IO/BufferedSubStream.Async.cs

93 lines
2.3 KiB
C#
Raw Normal View History

2026-01-22 13:38:20 +00:00
using System;
using System.Buffers;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
namespace SharpCompress.IO;
internal partial class BufferedSubStream
{
private async ValueTask RefillCacheAsync(CancellationToken cancellationToken)
{
2026-01-26 14:20:42 +00:00
if (_isDisposed)
{
throw new ObjectDisposedException(nameof(BufferedSubStream));
}
var count = (int)Math.Min(BytesLeftToRead, _cache!.Length);
2026-01-22 13:38:20 +00:00
_cacheOffset = 0;
if (count == 0)
{
_cacheLength = 0;
return;
}
2026-01-26 14:20:42 +00:00
// Only seek if we're not already at the correct position
// This avoids expensive seek operations when reading sequentially
2026-01-31 15:29:34 +00:00
if (_stream.CanSeek && _stream.Position != origin)
2026-01-26 14:20:42 +00:00
{
2026-01-31 15:29:34 +00:00
_stream.Position = origin;
2026-01-26 14:20:42 +00:00
}
2026-01-31 15:29:34 +00:00
_cacheLength = await _stream
2026-01-22 13:38:20 +00:00
.ReadAsync(_cache, 0, count, cancellationToken)
.ConfigureAwait(false);
origin += _cacheLength;
BytesLeftToRead -= _cacheLength;
}
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);
2026-01-26 14:20:42 +00:00
Buffer.BlockCopy(_cache!, _cacheOffset, buffer, offset, count);
2026-01-22 13:38:20 +00:00
_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);
2026-01-26 14:20:42 +00:00
_cache!.AsSpan(_cacheOffset, count).CopyTo(buffer.Span);
2026-01-22 13:38:20 +00:00
_cacheOffset += count;
}
return count;
}
#endif
}