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);
}
}
}
}