using System;
using System.IO;
using System.Text;
namespace SabreTools.Numerics.Extensions
{
///
/// Extensions for Streams
///
public static class StreamWriterExtensions
{
///
/// Write a UInt8
///
public static bool Write(this Stream stream, byte value)
=> WriteFromBuffer(stream, [value]);
///
/// Write a UInt8
///
/// Writes in both-endian format
public static bool WriteBothEndian(this Stream stream, BothUInt8 value)
{
bool actual = stream.Write(value.LittleEndian);
actual &= stream.Write(value.BigEndian);
return actual;
}
///
/// Write a UInt8[]
///
public static bool Write(this Stream stream, byte[] value)
=> WriteFromBuffer(stream, value);
///
/// Write a UInt8[]
///
/// Writes in big-endian format
public static bool WriteBigEndian(this Stream stream, byte[] value)
{
Array.Reverse(value);
return WriteFromBuffer(stream, value);
}
///
/// Write an Int8
///
public static bool Write(this Stream stream, sbyte value)
=> WriteFromBuffer(stream, [(byte)value]);
///
/// Write a Int8
///
/// Writes in both-endian format
public static bool WriteBothEndian(this Stream stream, BothInt8 value)
{
bool actual = stream.Write(value.LittleEndian);
actual &= stream.Write(value.BigEndian);
return actual;
}
///
/// Write a Char
///
public static bool Write(this Stream stream, char value)
{
byte[] buffer = BitConverter.GetBytes(value);
return WriteFromBuffer(stream, buffer);
}
///
/// Write a Char with an Encoding
///
public static bool Write(this Stream stream, char value, Encoding encoding)
{
byte[] buffer = encoding.GetBytes($"{value}");
return WriteFromBuffer(stream, buffer);
}
///
/// Write an Int16
///
/// Writes in machine native format
public static bool Write(this Stream stream, short value)
{
if (BitConverter.IsLittleEndian)
return stream.WriteLittleEndian(value);
else
return stream.WriteBigEndian(value);
}
///
/// Write an Int16
///
/// Writes in big-endian format
public static bool WriteBigEndian(this Stream stream, short value)
{
byte[] buffer = value.GetBytesBigEndian();
return WriteFromBuffer(stream, buffer);
}
///
/// Write an Int16
///
/// Writes in little-endian format
public static bool WriteLittleEndian(this Stream stream, short value)
{
byte[] buffer = value.GetBytesLittleEndian();
return WriteFromBuffer(stream, buffer);
}
///
/// Write a Int16
///
/// Writes in both-endian format
public static bool WriteBothEndian(this Stream stream, BothInt16 value)
{
bool actual = stream.WriteLittleEndian(value.LittleEndian);
actual &= stream.WriteBigEndian(value.BigEndian);
return actual;
}
///
/// Write a UInt16
///
/// Writes in machine native format
public static bool Write(this Stream stream, ushort value)
{
if (BitConverter.IsLittleEndian)
return stream.WriteLittleEndian(value);
else
return stream.WriteBigEndian(value);
}
///
/// Write a UInt16
///
/// Writes in big-endian format
public static bool WriteBigEndian(this Stream stream, ushort value)
{
byte[] buffer = value.GetBytesBigEndian();
return WriteFromBuffer(stream, buffer);
}
///
/// Write a UInt16
///
/// Writes in little-endian format
public static bool WriteLittleEndian(this Stream stream, ushort value)
{
byte[] buffer = value.GetBytesLittleEndian();
return WriteFromBuffer(stream, buffer);
}
///
/// Write a UInt16
///
/// Writes in both-endian format
public static bool WriteBothEndian(this Stream stream, BothUInt16 value)
{
bool actual = stream.WriteLittleEndian(value.LittleEndian);
actual &= stream.WriteBigEndian(value.BigEndian);
return actual;
}
#if NET5_0_OR_GREATER
///
/// Write a Half
///
/// Writes in machine native format
public static bool Write(this Stream stream, Half value)
{
if (BitConverter.IsLittleEndian)
return stream.WriteLittleEndian(value);
else
return stream.WriteBigEndian(value);
}
///
/// Write a Half
///
/// Writes in big-endian format
public static bool WriteBigEndian(this Stream stream, Half value)
{
byte[] buffer = value.GetBytesBigEndian();
return WriteFromBuffer(stream, buffer);
}
///
/// Write a Half
///
/// Writes in little-endian format
public static bool WriteLittleEndian(this Stream stream, Half value)
{
byte[] buffer = value.GetBytesLittleEndian();
return WriteFromBuffer(stream, buffer);
}
#endif
///
/// Write an Int24
///
/// Writes in machine native format
public static bool Write(this Stream stream, Int24 value)
{
if (BitConverter.IsLittleEndian)
return stream.WriteLittleEndian(value);
else
return stream.WriteBigEndian(value);
}
///
/// Write an Int24
///
/// Writes in big-endian format
public static bool WriteBigEndian(this Stream stream, Int24 value)
{
byte[] buffer = value.GetBytesBigEndian();
return WriteFromBuffer(stream, buffer);
}
///
/// Write an Int24
///
/// Writes in little-endian format
public static bool WriteLittleEndian(this Stream stream, Int24 value)
{
byte[] buffer = value.GetBytesLittleEndian();
return WriteFromBuffer(stream, buffer);
}
///
/// Write a UInt24
///
/// Writes in machine native format
public static bool Write(this Stream stream, UInt24 value)
{
if (BitConverter.IsLittleEndian)
return stream.WriteLittleEndian(value);
else
return stream.WriteBigEndian(value);
}
///
/// Write a UInt24
///
/// Writes in big-endian format
public static bool WriteBigEndian(this Stream stream, UInt24 value)
{
byte[] buffer = value.GetBytesBigEndian();
return WriteFromBuffer(stream, buffer);
}
///
/// Write a UInt24
///
/// Writes in little-endian format
public static bool WriteLittleEndian(this Stream stream, UInt24 value)
{
byte[] buffer = value.GetBytesLittleEndian();
return WriteFromBuffer(stream, buffer);
}
///
/// Write an Int32
///
/// Writes in machine native format
public static bool Write(this Stream stream, int value)
{
if (BitConverter.IsLittleEndian)
return stream.WriteLittleEndian(value);
else
return stream.WriteBigEndian(value);
}
///
/// Write an Int32
///
/// Writes in big-endian format
public static bool WriteBigEndian(this Stream stream, int value)
{
byte[] buffer = value.GetBytesBigEndian();
return WriteFromBuffer(stream, buffer);
}
///
/// Write an Int32
///
/// Writes in little-endian format
public static bool WriteLittleEndian(this Stream stream, int value)
{
byte[] buffer = value.GetBytesLittleEndian();
return WriteFromBuffer(stream, buffer);
}
///
/// Write a Int32
///
/// Writes in both-endian format
public static bool WriteBothEndian(this Stream stream, BothInt32 value)
{
bool actual = stream.WriteLittleEndian(value.LittleEndian);
actual &= stream.WriteBigEndian(value.BigEndian);
return actual;
}
///
/// Write a UInt32
///
/// Writes in machine native format
public static bool Write(this Stream stream, uint value)
{
if (BitConverter.IsLittleEndian)
return stream.WriteLittleEndian(value);
else
return stream.WriteBigEndian(value);
}
///
/// Write a UInt32
///
/// Writes in big-endian format
public static bool WriteBigEndian(this Stream stream, uint value)
{
byte[] buffer = value.GetBytesBigEndian();
return WriteFromBuffer(stream, buffer);
}
///
/// Write a UInt32
///
/// Writes in little-endian format
public static bool WriteLittleEndian(this Stream stream, uint value)
{
byte[] buffer = value.GetBytesLittleEndian();
return WriteFromBuffer(stream, buffer);
}
///
/// Write a UInt32
///
/// Writes in both-endian format
public static bool WriteBothEndian(this Stream stream, BothUInt32 value)
{
bool actual = stream.WriteLittleEndian(value.LittleEndian);
actual &= stream.WriteBigEndian(value.BigEndian);
return actual;
}
///
/// Write a Single
///
/// Writes in machine native format
public static bool Write(this Stream stream, float value)
{
if (BitConverter.IsLittleEndian)
return stream.WriteLittleEndian(value);
else
return stream.WriteBigEndian(value);
}
///
/// Write a Single
///
/// Writes in big-endian format
public static bool WriteBigEndian(this Stream stream, float value)
{
byte[] buffer = value.GetBytesBigEndian();
return WriteFromBuffer(stream, buffer);
}
///
/// Write a Single
///
public static bool WriteLittleEndian(this Stream stream, float value)
{
byte[] buffer = value.GetBytesLittleEndian();
return WriteFromBuffer(stream, buffer);
}
///
/// Write an Int48
///
/// Writes in machine native format
public static bool Write(this Stream stream, Int48 value)
{
if (BitConverter.IsLittleEndian)
return stream.WriteLittleEndian(value);
else
return stream.WriteBigEndian(value);
}
///
/// Write an Int48
///
/// Writes in big-endian format
public static bool WriteBigEndian(this Stream stream, Int48 value)
{
byte[] buffer = value.GetBytesBigEndian();
return WriteFromBuffer(stream, buffer);
}
///
/// Write an Int48
///
/// Writes in little-endian format
public static bool WriteLittleEndian(this Stream stream, Int48 value)
{
byte[] buffer = value.GetBytesLittleEndian();
return WriteFromBuffer(stream, buffer);
}
///
/// Write a UInt48
///
/// Writes in machine native format
public static bool Write(this Stream stream, UInt48 value)
{
if (BitConverter.IsLittleEndian)
return stream.WriteLittleEndian(value);
else
return stream.WriteBigEndian(value);
}
///
/// Write a UInt48
///
/// Writes in big-endian format
public static bool WriteBigEndian(this Stream stream, UInt48 value)
{
byte[] buffer = value.GetBytesBigEndian();
return WriteFromBuffer(stream, buffer);
}
///
/// Write a UInt48
///
/// Writes in little-endian format
public static bool WriteLittleEndian(this Stream stream, UInt48 value)
{
byte[] buffer = value.GetBytesLittleEndian();
return WriteFromBuffer(stream, buffer);
}
///
/// Write an Int64
///
/// Writes in machine native format
public static bool Write(this Stream stream, long value)
{
if (BitConverter.IsLittleEndian)
return stream.WriteLittleEndian(value);
else
return stream.WriteBigEndian(value);
}
///
/// Write an Int64
///
/// Writes in big-endian format
public static bool WriteBigEndian(this Stream stream, long value)
{
byte[] buffer = value.GetBytesBigEndian();
return WriteFromBuffer(stream, buffer);
}
///
/// Write an Int64
///
/// Writes in little-endian format
public static bool WriteLittleEndian(this Stream stream, long value)
{
byte[] buffer = value.GetBytesLittleEndian();
return WriteFromBuffer(stream, buffer);
}
///
/// Write a Int64
///
/// Writes in both-endian format
public static bool WriteBothEndian(this Stream stream, BothInt64 value)
{
bool actual = stream.WriteLittleEndian(value.LittleEndian);
actual &= stream.WriteBigEndian(value.BigEndian);
return actual;
}
///
/// Write a UInt64
///
/// Writes in machine native format
public static bool Write(this Stream stream, ulong value)
{
if (BitConverter.IsLittleEndian)
return stream.WriteLittleEndian(value);
else
return stream.WriteBigEndian(value);
}
///
/// Write a UInt64
///
/// Writes in big-endian format
public static bool WriteBigEndian(this Stream stream, ulong value)
{
byte[] buffer = value.GetBytesBigEndian();
return WriteFromBuffer(stream, buffer);
}
///
/// Write a UInt64
///
/// Writes in little-endian format
public static bool WriteLittleEndian(this Stream stream, ulong value)
{
byte[] buffer = value.GetBytesLittleEndian();
return WriteFromBuffer(stream, buffer);
}
///
/// Write a UInt64
///
/// Writes in both-endian format
public static bool WriteBothEndian(this Stream stream, BothUInt64 value)
{
bool actual = stream.WriteLittleEndian(value.LittleEndian);
actual &= stream.WriteBigEndian(value.BigEndian);
return actual;
}
///
/// Write a Double
///
/// Writes in machine native format
public static bool Write(this Stream stream, double value)
{
if (BitConverter.IsLittleEndian)
return stream.WriteLittleEndian(value);
else
return stream.WriteBigEndian(value);
}
///
/// Write a Double
///
/// Writes in big-endian format
public static bool WriteBigEndian(this Stream stream, double value)
{
byte[] buffer = value.GetBytesBigEndian();
return WriteFromBuffer(stream, buffer);
}
///
/// Write a Double
///
/// Writes in little-endian format
public static bool WriteLittleEndian(this Stream stream, double value)
{
byte[] buffer = value.GetBytesLittleEndian();
return WriteFromBuffer(stream, buffer);
}
///
/// Write a Guid
///
/// Writes in machine native format
public static bool Write(this Stream stream, Guid value)
{
if (BitConverter.IsLittleEndian)
return stream.WriteLittleEndian(value);
else
return stream.WriteBigEndian(value);
}
///
/// Write a Guid
///
/// Writes in big-endian format
public static bool WriteBigEndian(this Stream stream, Guid value)
{
byte[] buffer = value.GetBytesBigEndian();
return WriteFromBuffer(stream, buffer);
}
///
/// Write a Guid
///
/// Writes in little-endian format
public static bool WriteLittleEndian(this Stream stream, Guid value)
{
byte[] buffer = value.GetBytesLittleEndian();
return WriteFromBuffer(stream, buffer);
}
#if NET7_0_OR_GREATER
///
/// Write an Int128
///
/// Writes in machine native format
public static bool Write(this Stream stream, Int128 value)
{
if (BitConverter.IsLittleEndian)
return stream.WriteLittleEndian(value);
else
return stream.WriteBigEndian(value);
}
///
/// Write an Int128
///
/// Writes in big-endian format
public static bool WriteBigEndian(this Stream stream, Int128 value)
{
byte[] buffer = value.GetBytesBigEndian();
return WriteFromBuffer(stream, buffer);
}
///
/// Write an Int128
///
/// Writes in little-endian format
public static bool WriteLittleEndian(this Stream stream, Int128 value)
{
byte[] buffer = value.GetBytesLittleEndian();
return WriteFromBuffer(stream, buffer);
}
///
/// Write a UInt128
///
/// Writes in machine native format
public static bool Write(this Stream stream, UInt128 value)
{
if (BitConverter.IsLittleEndian)
return stream.WriteLittleEndian(value);
else
return stream.WriteBigEndian(value);
}
///
/// Write a UInt128
///
/// Writes in big-endian format
public static bool WriteBigEndian(this Stream stream, UInt128 value)
{
byte[] buffer = value.GetBytesBigEndian();
return WriteFromBuffer(stream, buffer);
}
///
/// Write a UInt128
///
/// Writes in little-endian format
public static bool WriteLittleEndian(this Stream stream, UInt128 value)
{
byte[] buffer = value.GetBytesLittleEndian();
return WriteFromBuffer(stream, buffer);
}
#endif
///
/// Write a Decimal and increment the pointer to an array
///
/// Writes in machine native format
public static bool Write(this Stream stream, decimal value)
{
if (BitConverter.IsLittleEndian)
return stream.WriteLittleEndian(value);
else
return stream.WriteBigEndian(value);
}
///
/// Write a Decimal and increment the pointer to an array
///
/// Writes in big-endian format
public static bool WriteBigEndian(this Stream stream, decimal value)
{
byte[] buffer = value.GetBytesBigEndian();
return WriteFromBuffer(stream, buffer);
}
///
/// Write a Decimal and increment the pointer to an array
///
/// Writes in little-endian format
public static bool WriteLittleEndian(this Stream stream, decimal value)
{
byte[] buffer = value.GetBytesLittleEndian();
return WriteFromBuffer(stream, buffer);
}
///
/// Write an array of bytes to the stream
///
private static bool WriteFromBuffer(Stream stream, byte[] value)
{
// If the stream is not writable
if (!stream.CanWrite)
return false;
// Handle the 0-byte case
if (value.Length == 0)
return true;
// Handle the general case, forcing a write of the correct length
stream.Write(value, 0, value.Length);
return true;
}
}
}