diff --git a/src/NexusMods.DataModel/ChunkedStreams/ChunkedStream.cs b/src/NexusMods.DataModel/ChunkedStreams/ChunkedStream.cs index d99d38b5f4..1abf63a3dc 100644 --- a/src/NexusMods.DataModel/ChunkedStreams/ChunkedStream.cs +++ b/src/NexusMods.DataModel/ChunkedStreams/ChunkedStream.cs @@ -1,4 +1,5 @@ using System.Buffers; +using System.Diagnostics; using Reloaded.Memory.Extensions; namespace NexusMods.DataModel.ChunkedStreams; @@ -29,10 +30,12 @@ public ChunkedStream(T source, int capacity = 16) /// public override void Flush() { } - + + /// + public override int Read(byte[] buffer, int offset, int count) => Read(buffer.AsSpan(offset, count)); /// - public override int Read(byte[] buffer, int offset, int count) + public override int Read(Span buffer) { if (_position >= _source.Size.Value) { @@ -43,8 +46,11 @@ public override int Read(byte[] buffer, int offset, int count) var chunkOffset = _position % _source.ChunkSize.Value; var isLastChunk = chunkIdx == _source.ChunkCount - 1; var chunk = GetChunk(chunkIdx); + var readToEnd = Math.Clamp(_source.Size.Value - _position, 0, Int32.MaxValue); - var toRead = Math.Min(count, (int)(_source.ChunkSize.Value - chunkOffset)); + var toRead = Math.Min(buffer.Length, (int)(_source.ChunkSize.Value - chunkOffset)); + toRead = Math.Min(toRead, (int)readToEnd); + if (isLastChunk) { var lastChunkExtraSize = _source.Size.Value % _source.ChunkSize.Value; @@ -56,15 +62,17 @@ public override int Read(byte[] buffer, int offset, int count) chunk.Slice((int)chunkOffset, toRead) .Span - .CopyTo(buffer.AsSpan(offset, toRead)); + .CopyTo(buffer.SliceFast(0, toRead)); _position += (ulong)toRead; + + Debug.Assert(_position <= _source.Size.Value, "Read more than the size of the stream"); return toRead; } /// public override async ValueTask ReadAsync(Memory buffer, - CancellationToken cancellationToken = new CancellationToken()) + CancellationToken cancellationToken = new()) { if (_position >= _source.Size.Value) { @@ -92,6 +100,7 @@ public override async ValueTask ReadAsync(Memory buffer, .Span .CopyTo(buffer.Span.SliceFast(0, toRead)); _position += (ulong)toRead; + Debug.Assert(_position <= _source.Size.Value, "Read more than the size of the stream"); return toRead; }