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