aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Common/Extensions/StreamExtensions.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Ryujinx.Common/Extensions/StreamExtensions.cs')
-rw-r--r--Ryujinx.Common/Extensions/StreamExtensions.cs138
1 files changed, 138 insertions, 0 deletions
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);
+ }
+ }
+ }
+}