diff options
Diffstat (limited to 'Ryujinx.Common/Extensions')
-rw-r--r-- | Ryujinx.Common/Extensions/BinaryReaderExtensions.cs | 14 | ||||
-rw-r--r-- | Ryujinx.Common/Extensions/BinaryWriterExtensions.cs | 28 | ||||
-rw-r--r-- | Ryujinx.Common/Extensions/StreamExtensions.cs | 138 |
3 files changed, 166 insertions, 14 deletions
diff --git a/Ryujinx.Common/Extensions/BinaryReaderExtensions.cs b/Ryujinx.Common/Extensions/BinaryReaderExtensions.cs index ea404d2a..21da6fc0 100644 --- a/Ryujinx.Common/Extensions/BinaryReaderExtensions.cs +++ b/Ryujinx.Common/Extensions/BinaryReaderExtensions.cs @@ -12,19 +12,5 @@ namespace Ryujinx.Common { return MemoryMarshal.Cast<byte, T>(reader.ReadBytes(Unsafe.SizeOf<T>()))[0]; } - - public unsafe static void WriteStruct<T>(this BinaryWriter writer, T value) - where T : unmanaged - { - ReadOnlySpan<byte> data = MemoryMarshal.Cast<T, byte>(MemoryMarshal.CreateReadOnlySpan(ref value, 1)); - - writer.Write(data); - } - - public static void Write(this BinaryWriter writer, UInt128 value) - { - writer.Write((ulong)value); - writer.Write((ulong)(value >> 64)); - } } } diff --git a/Ryujinx.Common/Extensions/BinaryWriterExtensions.cs b/Ryujinx.Common/Extensions/BinaryWriterExtensions.cs new file mode 100644 index 00000000..fddc8c1b --- /dev/null +++ b/Ryujinx.Common/Extensions/BinaryWriterExtensions.cs @@ -0,0 +1,28 @@ +using System; +using System.IO; +using System.Runtime.InteropServices; + +namespace Ryujinx.Common +{ + public static class BinaryWriterExtensions + { + public unsafe static void WriteStruct<T>(this BinaryWriter writer, T value) + where T : unmanaged + { + ReadOnlySpan<byte> data = MemoryMarshal.Cast<T, byte>(MemoryMarshal.CreateReadOnlySpan(ref value, 1)); + + writer.Write(data); + } + + public static void Write(this BinaryWriter writer, UInt128 value) + { + writer.Write((ulong)value); + writer.Write((ulong)(value >> 64)); + } + + public static void Write(this BinaryWriter writer, MemoryStream stream) + { + stream.CopyTo(writer.BaseStream); + } + } +} diff --git a/Ryujinx.Common/Extensions/StreamExtensions.cs b/Ryujinx.Common/Extensions/StreamExtensions.cs new file mode 100644 index 00000000..f6fc870a --- /dev/null +++ b/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); + } + } + } +} |