using System; using System.IO; using System.Text; namespace SabreTools.Numerics.Extensions { /// /// Extensions for BinaryWriter /// public static class BinaryWriterExtensions { /// /// Writes in both-endian format public static bool WriteBothEndian(this BinaryWriter writer, BothUInt8 value) { writer.Write(value.LittleEndian); writer.Write(value.BigEndian); return true; } /// /// Writes in both-endian format public static bool WriteBothEndian(this BinaryWriter writer, BothInt8 value) { writer.Write(value.LittleEndian); writer.Write(value.BigEndian); return true; } /// /// Writes in big-endian format public static bool WriteBigEndian(this BinaryWriter writer, byte[] value) { Array.Reverse(value); return WriteFromBuffer(writer, value); } /// public static bool Write(this BinaryWriter writer, char value, Encoding encoding) { byte[] buffer = encoding.GetBytes($"{value}"); return WriteFromBuffer(writer, buffer); } /// /// Writes in big-endian format public static bool WriteBigEndian(this BinaryWriter writer, short value) { byte[] buffer = value.GetBytesBigEndian(); return WriteFromBuffer(writer, buffer); } /// /// Writes in little-endian format public static bool WriteLittleEndian(this BinaryWriter writer, short value) { byte[] buffer = value.GetBytesLittleEndian(); return WriteFromBuffer(writer, buffer); } /// /// Writes in both-endian format public static bool WriteBothEndian(this BinaryWriter writer, BothInt16 value) { writer.WriteLittleEndian(value.LittleEndian); writer.WriteBigEndian(value.BigEndian); return true; } /// /// Writes in big-endian format public static bool WriteBigEndian(this BinaryWriter writer, ushort value) { byte[] buffer = value.GetBytesBigEndian(); return WriteFromBuffer(writer, buffer); } /// /// Writes in little-endian format public static bool WriteLittleEndian(this BinaryWriter writer, ushort value) { byte[] buffer = value.GetBytesLittleEndian(); return WriteFromBuffer(writer, buffer); } /// /// Writes in both-endian format public static bool WriteBothEndian(this BinaryWriter writer, BothUInt16 value) { writer.WriteLittleEndian(value.LittleEndian); writer.WriteBigEndian(value.BigEndian); return true; } #if NET5_0_OR_GREATER /// /// Write a Half to the underlying stream /// /// Writes in machine native format public static bool Write(this BinaryWriter writer, Half value) { if (BitConverter.IsLittleEndian) return writer.WriteLittleEndian(value); else return writer.WriteBigEndian(value); } /// /// Writes in big-endian format public static bool WriteBigEndian(this BinaryWriter writer, Half value) { byte[] buffer = value.GetBytesBigEndian(); return WriteFromBuffer(writer, buffer); } /// /// Writes in little-endian format public static bool WriteLittleEndian(this BinaryWriter writer, Half value) { byte[] buffer = value.GetBytesLittleEndian(); return WriteFromBuffer(writer, buffer); } #endif /// /// Write an Int24 to the underlying stream /// /// Writes in machine native format public static bool Write(this BinaryWriter writer, Int24 value) { if (BitConverter.IsLittleEndian) return writer.WriteLittleEndian(value); else return writer.WriteBigEndian(value); } /// /// Write an Int24 to the underlying stream /// /// Writes in big-endian format public static bool WriteBigEndian(this BinaryWriter writer, Int24 value) { byte[] buffer = value.GetBytesBigEndian(); return WriteFromBuffer(writer, buffer); } /// /// Write an Int24 to the underlying stream /// /// Writes in little-endian format public static bool WriteLittleEndian(this BinaryWriter writer, Int24 value) { byte[] buffer = value.GetBytesLittleEndian(); return WriteFromBuffer(writer, buffer); } /// /// Write a UInt24 to the underlying stream /// /// Writes in machine native format public static bool Write(this BinaryWriter writer, UInt24 value) { if (BitConverter.IsLittleEndian) return writer.WriteLittleEndian(value); else return writer.WriteBigEndian(value); } /// /// Write a UInt24 to the underlying stream /// /// Writes in big-endian format public static bool WriteBigEndian(this BinaryWriter writer, UInt24 value) { byte[] buffer = value.GetBytesBigEndian(); return WriteFromBuffer(writer, buffer); } /// /// Write a UInt24 to the underlying stream /// /// Writes in little-endian format public static bool WriteLittleEndian(this BinaryWriter writer, UInt24 value) { byte[] buffer = value.GetBytesLittleEndian(); return WriteFromBuffer(writer, buffer); } /// /// Writes in big-endian format public static bool WriteBigEndian(this BinaryWriter writer, int value) { byte[] buffer = value.GetBytesBigEndian(); return WriteFromBuffer(writer, buffer); } /// /// Writes in little-endian format public static bool WriteLittleEndian(this BinaryWriter writer, int value) { byte[] buffer = value.GetBytesLittleEndian(); return WriteFromBuffer(writer, buffer); } /// /// Writes in both-endian format public static bool WriteBothEndian(this BinaryWriter writer, BothInt32 value) { writer.WriteLittleEndian(value.LittleEndian); writer.WriteBigEndian(value.BigEndian); return true; } /// /// Writes in big-endian format public static bool WriteBigEndian(this BinaryWriter writer, uint value) { byte[] buffer = value.GetBytesBigEndian(); return WriteFromBuffer(writer, buffer); } /// /// Writes in little-endian format public static bool WriteLittleEndian(this BinaryWriter writer, uint value) { byte[] buffer = value.GetBytesLittleEndian(); return WriteFromBuffer(writer, buffer); } /// /// Writes in both-endian format public static bool WriteBothEndian(this BinaryWriter writer, BothUInt32 value) { writer.WriteLittleEndian(value.LittleEndian); writer.WriteBigEndian(value.BigEndian); return true; } /// /// Writes in big-endian format public static bool WriteBigEndian(this BinaryWriter writer, float value) { byte[] buffer = value.GetBytesBigEndian(); return WriteFromBuffer(writer, buffer); } /// /// Writes in little-endian format public static bool WriteLittleEndian(this BinaryWriter writer, float value) { byte[] buffer = value.GetBytesLittleEndian(); return WriteFromBuffer(writer, buffer); } /// /// Write an Int48 to the underlying stream /// /// Writes in machine native format public static bool Write(this BinaryWriter writer, Int48 value) { if (BitConverter.IsLittleEndian) return writer.WriteLittleEndian(value); else return writer.WriteBigEndian(value); } /// /// Write an Int48 to the underlying stream /// /// Writes in big-endian format public static bool WriteBigEndian(this BinaryWriter writer, Int48 value) { byte[] buffer = value.GetBytesBigEndian(); return WriteFromBuffer(writer, buffer); } /// /// Write an Int48 to the underlying stream /// /// Writes in little-endian format public static bool WriteLittleEndian(this BinaryWriter writer, Int48 value) { byte[] buffer = value.GetBytesLittleEndian(); return WriteFromBuffer(writer, buffer); } /// /// Write a UInt48 to the underlying stream /// /// Writes in machine native format public static bool Write(this BinaryWriter writer, UInt48 value) { if (BitConverter.IsLittleEndian) return writer.WriteLittleEndian(value); else return writer.WriteBigEndian(value); } /// /// Write a UInt48 to the underlying stream /// /// Writes in big-endian format public static bool WriteBigEndian(this BinaryWriter writer, UInt48 value) { byte[] buffer = value.GetBytesBigEndian(); return WriteFromBuffer(writer, buffer); } /// /// Write a UInt48 to the underlying stream /// /// Writes in little-endian format public static bool WriteLittleEndian(this BinaryWriter writer, UInt48 value) { byte[] buffer = value.GetBytesLittleEndian(); return WriteFromBuffer(writer, buffer); } /// /// Writes in big-endian format public static bool WriteBigEndian(this BinaryWriter writer, long value) { byte[] buffer = value.GetBytesBigEndian(); return WriteFromBuffer(writer, buffer); } /// /// Writes in little-endian format public static bool WriteLittleEndian(this BinaryWriter writer, long value) { byte[] buffer = value.GetBytesLittleEndian(); return WriteFromBuffer(writer, buffer); } /// /// Writes in both-endian format public static bool WriteBothEndian(this BinaryWriter writer, BothInt64 value) { writer.WriteLittleEndian(value.LittleEndian); writer.WriteBigEndian(value.BigEndian); return true; } /// /// Writes in big-endian format public static bool WriteBigEndian(this BinaryWriter writer, ulong value) { byte[] buffer = value.GetBytesBigEndian(); return WriteFromBuffer(writer, buffer); } /// /// Writes in little-endian format public static bool WriteLittleEndian(this BinaryWriter writer, ulong value) { byte[] buffer = value.GetBytesLittleEndian(); return WriteFromBuffer(writer, buffer); } /// /// Writes in both-endian format public static bool WriteBothEndian(this BinaryWriter writer, BothUInt64 value) { writer.WriteLittleEndian(value.LittleEndian); writer.WriteBigEndian(value.BigEndian); return true; } /// /// Writes in big-endian format public static bool WriteBigEndian(this BinaryWriter writer, double value) { byte[] buffer = value.GetBytesBigEndian(); return WriteFromBuffer(writer, buffer); } /// /// Writes in little-endian format public static bool WriteLittleEndian(this BinaryWriter writer, double value) { byte[] buffer = value.GetBytesLittleEndian(); return WriteFromBuffer(writer, buffer); } /// /// Write a Guid /// /// Writes in machine native format public static bool Write(this BinaryWriter writer, Guid value) { if (BitConverter.IsLittleEndian) return writer.WriteLittleEndian(value); else return writer.WriteBigEndian(value); } /// /// Write a Guid /// /// Writes in big-endian format public static bool WriteBigEndian(this BinaryWriter writer, Guid value) { byte[] buffer = value.GetBytesBigEndian(); return WriteFromBuffer(writer, buffer); } /// /// Write a Guid /// /// Writes in big-endian format public static bool WriteLittleEndian(this BinaryWriter writer, Guid value) { byte[] buffer = value.GetBytesLittleEndian(); return WriteFromBuffer(writer, buffer); } #if NET7_0_OR_GREATER /// /// Write an Int128 to the underlying stream /// /// Writes in machine native format public static bool Write(this BinaryWriter writer, Int128 value) { if (BitConverter.IsLittleEndian) return writer.WriteLittleEndian(value); else return writer.WriteBigEndian(value); } /// /// Write an Int128 to the underlying stream /// /// Writes in big-endian format public static bool WriteBigEndian(this BinaryWriter writer, Int128 value) { byte[] buffer = value.GetBytesBigEndian(); return WriteFromBuffer(writer, buffer); } /// /// Write an Int128 to the underlying stream /// /// Writes in little-endian format public static bool WriteLittleEndian(this BinaryWriter writer, Int128 value) { byte[] buffer = value.GetBytesLittleEndian(); return WriteFromBuffer(writer, buffer); } /// /// Write a UInt128 to the underlying stream /// /// Writes in machine native format public static bool Write(this BinaryWriter writer, UInt128 value) { if (BitConverter.IsLittleEndian) return writer.WriteLittleEndian(value); else return writer.WriteBigEndian(value); } /// /// Write a UInt128 to the underlying stream /// /// Writes in big-endian format public static bool WriteBigEndian(this BinaryWriter writer, UInt128 value) { byte[] buffer = value.GetBytesBigEndian(); return WriteFromBuffer(writer, buffer); } /// /// Write a UInt128 to the underlying stream /// /// Writes in little-endian format public static bool WriteLittleEndian(this BinaryWriter writer, UInt128 value) { byte[] buffer = value.GetBytesLittleEndian(); return WriteFromBuffer(writer, buffer); } #endif /// /// Writes in big-endian format public static bool WriteBigEndian(this BinaryWriter writer, decimal value) { byte[] buffer = value.GetBytesBigEndian(); return WriteFromBuffer(writer, buffer); } /// /// Writes in little-endian format public static bool WriteLittleEndian(this BinaryWriter writer, decimal value) { byte[] buffer = value.GetBytesLittleEndian(); return WriteFromBuffer(writer, buffer); } /// /// Write an array of bytes to the underlying stream /// private static bool WriteFromBuffer(BinaryWriter writer, byte[] value) { // If the stream is not writable if (!writer.BaseStream.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 writer.Write(value, 0, value.Length); return true; } } }