using System; using System.Buffers.Binary; using System.IO; using System.Runtime.InteropServices; namespace Ryujinx.Common { public static class StreamExtensions { /// /// Writes a " /> to this stream. /// /// This default implementation converts each buffer value to a stack-allocated /// byte array, then writes it to the Stream using . /// /// The stream to be written to /// The buffer of values to be written public static void Write(this Stream stream, ReadOnlySpan buffer) { if (buffer.Length == 0) { return; } if (BitConverter.IsLittleEndian) { ReadOnlySpan byteBuffer = MemoryMarshal.Cast(buffer); stream.Write(byteBuffer); } else { Span byteBuffer = stackalloc byte[sizeof(int)]; foreach (int value in buffer) { BinaryPrimitives.WriteInt32LittleEndian(byteBuffer, value); stream.Write(byteBuffer); } } } /// /// Writes a four-byte signed integer to this stream. The current position /// of the stream is advanced by four. /// /// The stream to be written to /// The value to be written public static void Write(this Stream stream, int value) { Span buffer = stackalloc byte[sizeof(int)]; BinaryPrimitives.WriteInt32LittleEndian(buffer, value); stream.Write(buffer); } /// /// Writes an eight-byte signed integer to this stream. The current position /// of the stream is advanced by eight. /// /// The stream to be written to /// The value to be written public static void Write(this Stream stream, long value) { Span buffer = stackalloc byte[sizeof(long)]; BinaryPrimitives.WriteInt64LittleEndian(buffer, value); stream.Write(buffer); } /// // Writes a four-byte unsigned integer to this stream. The current position // of the stream is advanced by four. /// /// The stream to be written to /// The value to be written public static void Write(this Stream stream, uint value) { Span buffer = stackalloc byte[sizeof(uint)]; BinaryPrimitives.WriteUInt32LittleEndian(buffer, value); stream.Write(buffer); } /// /// Writes an eight-byte unsigned integer to this stream. The current /// position of the stream is advanced by eight. /// /// The stream to be written to /// The value to be written public static void Write(this Stream stream, ulong value) { Span buffer = stackalloc byte[sizeof(ulong)]; BinaryPrimitives.WriteUInt64LittleEndian(buffer, value); stream.Write(buffer); } /// /// Writes the contents of source to stream by calling source.CopyTo(stream). /// Provides consistency with other Stream.Write methods. /// /// The stream to be written to /// The stream to be read from public static void Write(this Stream stream, Stream source) { source.CopyTo(stream); } /// /// Writes a sequence of bytes to the Stream. /// /// The stream to be written to. /// The byte to be written /// The number of times the value should be written 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 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); } } } }