diff options
Diffstat (limited to 'src/Ryujinx.Common/Extensions/StreamExtensions.cs')
-rw-r--r-- | src/Ryujinx.Common/Extensions/StreamExtensions.cs | 138 |
1 files changed, 138 insertions, 0 deletions
diff --git a/src/Ryujinx.Common/Extensions/StreamExtensions.cs b/src/Ryujinx.Common/Extensions/StreamExtensions.cs new file mode 100644 index 00000000..f6fc870a --- /dev/null +++ b/src/Ryujinx.Common/Extensions/StreamExtensions.cs @@ -0,0 +1,138 @@ +using System; +using System.Buffers.Binary; +using System.IO; +using System.Runtime.InteropServices; + +namespace Ryujinx.Common +{ + public static class StreamExtensions + { + /// <summary> + /// Writes a <cref="ReadOnlySpan<int>" /> to this stream. + /// + /// This default implementation converts each buffer value to a stack-allocated + /// byte array, then writes it to the Stream using <cref="System.Stream.Write(byte[])" />. + /// </summary> + /// <param name="stream">The stream to be written to</param> + /// <param name="buffer">The buffer of values to be written</param> + public static void Write(this Stream stream, ReadOnlySpan<int> buffer) + { + if (buffer.Length == 0) + { + return; + } + + if (BitConverter.IsLittleEndian) + { + ReadOnlySpan<byte> byteBuffer = MemoryMarshal.Cast<int, byte>(buffer); + stream.Write(byteBuffer); + } + else + { + Span<byte> byteBuffer = stackalloc byte[sizeof(int)]; + + foreach (int value in buffer) + { + BinaryPrimitives.WriteInt32LittleEndian(byteBuffer, value); + stream.Write(byteBuffer); + } + } + } + + /// <summary> + /// Writes a four-byte signed integer to this stream. The current position + /// of the stream is advanced by four. + /// </summary> + /// <param name="stream">The stream to be written to</param> + /// <param name="value">The value to be written</param> + public static void Write(this Stream stream, int value) + { + Span<byte> buffer = stackalloc byte[sizeof(int)]; + BinaryPrimitives.WriteInt32LittleEndian(buffer, value); + stream.Write(buffer); + } + + /// <summary> + /// Writes an eight-byte signed integer to this stream. The current position + /// of the stream is advanced by eight. + /// </summary> + /// <param name="stream">The stream to be written to</param> + /// <param name="value">The value to be written</param> + public static void Write(this Stream stream, long value) + { + Span<byte> buffer = stackalloc byte[sizeof(long)]; + BinaryPrimitives.WriteInt64LittleEndian(buffer, value); + stream.Write(buffer); + } + + /// <summary> + // Writes a four-byte unsigned integer to this stream. The current position + // of the stream is advanced by four. + /// </summary> + /// <param name="stream">The stream to be written to</param> + /// <param name="value">The value to be written</param> + public static void Write(this Stream stream, uint value) + { + Span<byte> buffer = stackalloc byte[sizeof(uint)]; + BinaryPrimitives.WriteUInt32LittleEndian(buffer, value); + stream.Write(buffer); + } + + /// <summary> + /// Writes an eight-byte unsigned integer to this stream. The current + /// position of the stream is advanced by eight. + /// </summary> + /// <param name="stream">The stream to be written to</param> + /// <param name="value">The value to be written</param> + public static void Write(this Stream stream, ulong value) + { + Span<byte> buffer = stackalloc byte[sizeof(ulong)]; + BinaryPrimitives.WriteUInt64LittleEndian(buffer, value); + stream.Write(buffer); + } + + /// <summary> + /// Writes the contents of source to stream by calling source.CopyTo(stream). + /// Provides consistency with other Stream.Write methods. + /// </summary> + /// <param name="stream">The stream to be written to</param> + /// <param name="source">The stream to be read from</param> + public static void Write(this Stream stream, Stream source) + { + source.CopyTo(stream); + } + + /// <summary> + /// Writes a sequence of bytes to the Stream. + /// </summary> + /// <param name="stream">The stream to be written to.</param> + /// <param name="value">The byte to be written</param> + /// <param name="count">The number of times the value should be written</param> + public static void WriteByte(this Stream stream, byte value, int count) + { + if (count <= 0) + { + return; + } + + const int BlockSize = 16; + + int blockCount = count / BlockSize; + if (blockCount > 0) + { + Span<byte> span = stackalloc byte[BlockSize]; + span.Fill(value); + for (int x = 0; x < blockCount; x++) + { + stream.Write(span); + } + } + + int nonBlockBytes = count % BlockSize; + for (int x = 0; x < nonBlockBytes; x++) + { + stream.WriteByte(value); + } + } + } +} |