diff --git a/OpenRA.Game/Primitives/MergedStream.cs b/OpenRA.Game/Primitives/MergedStream.cs index dfa5266eb7..84f1844ec7 100644 --- a/OpenRA.Game/Primitives/MergedStream.cs +++ b/OpenRA.Game/Primitives/MergedStream.cs @@ -80,18 +80,23 @@ namespace OpenRA.Primitives } public override int Read(byte[] buffer, int offset, int count) + { + return Read(buffer.AsSpan(offset, count)); + } + + public override int Read(Span buffer) { int bytesRead; if (position >= Stream1.Length) - bytesRead = Stream2.Read(buffer, offset, count); - else if (count > Stream1.Length) + bytesRead = Stream2.Read(buffer); + else if (buffer.Length > Stream1.Length) { - bytesRead = Stream1.Read(buffer, offset, (int)Stream1.Length); - bytesRead += Stream2.Read(buffer, (int)Stream1.Length, count - (int)Stream1.Length); + bytesRead = Stream1.Read(buffer[..(int)Stream1.Length]); + bytesRead += Stream2.Read(buffer[(int)Stream1.Length..]); } else - bytesRead = Stream1.Read(buffer, offset, count); + bytesRead = Stream1.Read(buffer); position += bytesRead; @@ -108,6 +113,11 @@ namespace OpenRA.Primitives throw new NotSupportedException(); } + public override void Write(ReadOnlySpan buffer) + { + throw new NotSupportedException(); + } + public override bool CanRead => Stream1.CanRead && Stream2.CanRead; public override bool CanSeek => Stream1.CanSeek && Stream2.CanSeek; diff --git a/OpenRA.Game/Primitives/ReadOnlyAdapterStream.cs b/OpenRA.Game/Primitives/ReadOnlyAdapterStream.cs index c8f2f39817..9931df2217 100644 --- a/OpenRA.Game/Primitives/ReadOnlyAdapterStream.cs +++ b/OpenRA.Game/Primitives/ReadOnlyAdapterStream.cs @@ -51,6 +51,7 @@ namespace OpenRA.Primitives public sealed override void SetLength(long value) { throw new NotSupportedException(); } public sealed override void WriteByte(byte value) { throw new NotSupportedException(); } public sealed override void Write(byte[] buffer, int offset, int count) { throw new NotSupportedException(); } + public override void Write(ReadOnlySpan buffer) { throw new NotSupportedException(); } public sealed override void Flush() { throw new NotSupportedException(); } public sealed override int ReadByte() @@ -70,31 +71,36 @@ namespace OpenRA.Primitives public sealed override int Read(byte[] buffer, int offset, int count) { - var copied = 0; - ConsumeData(buffer, offset, count, ref copied); + return Read(buffer.AsSpan(offset, count)); + } - while (copied < count && !baseStreamEmpty) + public override int Read(Span buffer) + { + var copied = 0; + ConsumeData(buffer, ref copied); + + while (copied < buffer.Length && !baseStreamEmpty) { baseStreamEmpty = BufferData(baseStream, data); - ConsumeData(buffer, offset, count, ref copied); + ConsumeData(buffer, ref copied); } return copied; } /// - /// Reads data into a buffer, which will be used to satisfy and - /// calls. + /// Reads data into a buffer, which will be used to satisfy , + /// and calls. /// /// The source stream from which bytes should be read. /// The queue where bytes should be enqueued. Do not dequeue from this buffer. /// Return true if all data has been read; otherwise, false. protected abstract bool BufferData(Stream baseStream, Queue data); - void ConsumeData(byte[] buffer, int offset, int count, ref int copied) + void ConsumeData(Span buffer, ref int copied) { - while (copied < count && data.Count > 0) - buffer[offset + copied++] = data.Dequeue(); + while (copied < buffer.Length && data.Count > 0) + buffer[copied++] = data.Dequeue(); } protected override void Dispose(bool disposing) diff --git a/OpenRA.Game/Primitives/SegmentStream.cs b/OpenRA.Game/Primitives/SegmentStream.cs index d71af205ec..415ba70631 100644 --- a/OpenRA.Game/Primitives/SegmentStream.cs +++ b/OpenRA.Game/Primitives/SegmentStream.cs @@ -68,11 +68,16 @@ namespace OpenRA.Primitives } public override int Read(byte[] buffer, int offset, int count) + { + return Read(buffer.AsSpan(offset, count)); + } + + public override int Read(Span buffer) { var remaining = Length - Position; if (remaining <= 0) return 0; - return BaseStream.Read(buffer, offset, (int)Math.Min(remaining, count)); + return BaseStream.Read(buffer[..(int)Math.Min(remaining, buffer.Length)]); } public override void WriteByte(byte value) @@ -84,9 +89,14 @@ namespace OpenRA.Primitives public override void Write(byte[] buffer, int offset, int count) { - if (Position + count >= Length) + Write(buffer.AsSpan(offset, count)); + } + + public override void Write(ReadOnlySpan buffer) + { + if (Position + buffer.Length >= Length) throw new IOException("Attempted to write past the end of the stream."); - BaseStream.Write(buffer, offset, count); + BaseStream.Write(buffer); } public override void Flush() { BaseStream.Flush(); } diff --git a/OpenRA.Mods.Cnc/AudioLoaders/VocLoader.cs b/OpenRA.Mods.Cnc/AudioLoaders/VocLoader.cs index ec725f12e4..bb684d4810 100644 --- a/OpenRA.Mods.Cnc/AudioLoaders/VocLoader.cs +++ b/OpenRA.Mods.Cnc/AudioLoaders/VocLoader.cs @@ -332,18 +332,16 @@ namespace OpenRA.Mods.Cnc.AudioLoaders } } - int Read(byte[] buffer, int offset, int count) + int Read(Span buffer) { var bytesWritten = 0; - var samplesLeft = Math.Min(count, buffer.Length - offset); - while (samplesLeft > 0) + while (buffer.Length > 0) { - var len = FillBuffer(samplesLeft); + var len = FillBuffer(buffer.Length); if (len == 0) break; - Buffer.BlockCopy(this.buffer, 0, buffer, offset, len); - samplesLeft -= len; - offset += len; + this.buffer.AsSpan(..len).CopyTo(buffer); + buffer = buffer[len..]; bytesWritten += len; } @@ -372,13 +370,19 @@ namespace OpenRA.Mods.Cnc.AudioLoaders public override int Read(byte[] buffer, int offset, int count) { - return format.Read(buffer, offset, count); + return Read(buffer.AsSpan(offset, count)); + } + + public override int Read(Span buffer) + { + return format.Read(buffer); } public override void Flush() { throw new NotImplementedException(); } public override long Seek(long offset, SeekOrigin origin) { throw new NotImplementedException(); } public override void SetLength(long value) { throw new NotImplementedException(); } public override void Write(byte[] buffer, int offset, int count) { throw new NotImplementedException(); } + public override void Write(ReadOnlySpan buffer) { throw new NotImplementedException(); } protected override void Dispose(bool disposing) { diff --git a/OpenRA.Mods.Common/AudioLoaders/OggLoader.cs b/OpenRA.Mods.Common/AudioLoaders/OggLoader.cs index 2ad8e492f4..c8bd3044f6 100644 --- a/OpenRA.Mods.Common/AudioLoaders/OggLoader.cs +++ b/OpenRA.Mods.Common/AudioLoaders/OggLoader.cs @@ -96,9 +96,14 @@ namespace OpenRA.Mods.Common.AudioLoaders } public override int Read(byte[] buffer, int offset, int count) + { + return Read(buffer.AsSpan(offset, count)); + } + + public override int Read(Span buffer) { // Adjust count so it is in 16-bit samples instead of bytes. - count /= 2; + var count = buffer.Length / 2; // Make sure we don't have an odd count. count -= count % format.reader.Channels; @@ -112,8 +117,8 @@ namespace OpenRA.Mods.Common.AudioLoaders for (var i = 0; i < samples; i++) { var conversion = (short)(floatBuffer[i] * 32767); - buffer[offset++] = (byte)(conversion & 255); - buffer[offset++] = (byte)(conversion >> 8); + buffer[i * 2 + 0] = (byte)(conversion & 255); + buffer[i * 2 + 1] = (byte)(conversion >> 8); } // Adjust count back to bytes. @@ -124,6 +129,7 @@ namespace OpenRA.Mods.Common.AudioLoaders public override long Seek(long offset, SeekOrigin origin) { throw new NotImplementedException(); } public override void SetLength(long value) { throw new NotImplementedException(); } public override void Write(byte[] buffer, int offset, int count) { throw new NotImplementedException(); } + public override void Write(ReadOnlySpan buffer) { throw new NotImplementedException(); } protected override void Dispose(bool disposing) {