using System; using System.Text; using SabreTools.Numerics; namespace SabreTools.Text.Extensions { // TODO: Add extension for printing enums, if possible public static class StringBuilderExtensions { /// /// Append a line containing a boolean to a StringBuilder /// public static StringBuilder AppendLine(this StringBuilder sb, bool? value, string prefixString) { string valueString = value is null ? "[NULL]" : value.Value.ToString(); return sb.AppendLine($"{prefixString}: {valueString}"); } /// /// Append a line containing a Char to a StringBuilder /// public static StringBuilder AppendLine(this StringBuilder sb, char? value, string prefixString) { string valueString = value is null ? "[NULL]" : value.Value.ToString(); return sb.AppendLine($"{prefixString}: {valueString}"); } /// /// Append a line containing a Int8 to a StringBuilder /// public static StringBuilder AppendLine(this StringBuilder sb, sbyte? value, string prefixString) { string valueString = value is null ? "[NULL]" : $"{value} (0x{value:X2})"; return sb.AppendLine($"{prefixString}: {valueString}"); } /// /// Append a line containing a potentially both-endian Int8 to a StringBuilder /// public static StringBuilder AppendLineBothEndian(this StringBuilder sb, BothInt8? value, string prefixString) { if (value is null) return sb.AppendLine($"{prefixString}: [NULL]"); if (value.IsValid) return sb.AppendLine(value, prefixString); sb = sb.AppendLine(value.LittleEndian, $"{prefixString} (Little-Endian)"); return sb.AppendLine(value.BigEndian, $"{prefixString} (Big-Endian)"); } /// /// Append a line containing a UInt8 to a StringBuilder /// public static StringBuilder AppendLine(this StringBuilder sb, byte? value, string prefixString) { string valueString = value is null ? "[NULL]" : $"{value} (0x{value:X2})"; return sb.AppendLine($"{prefixString}: {valueString}"); } /// /// Append a line containing a potentially both-endian UInt8 to a StringBuilder /// public static StringBuilder AppendLineBothEndian(this StringBuilder sb, BothUInt8? value, string prefixString) { if (value is null) return sb.AppendLine($"{prefixString}: [NULL]"); if (value.IsValid) return sb.AppendLine(value, prefixString); sb = sb.AppendLine(value.LittleEndian, $"{prefixString} (Little-Endian)"); return sb.AppendLine(value.BigEndian, $"{prefixString} (Big-Endian)"); } /// /// Append a line containing a Int16 to a StringBuilder /// public static StringBuilder AppendLine(this StringBuilder sb, short? value, string prefixString) { string valueString = value is null ? "[NULL]" : $"{value} (0x{value:X4})"; return sb.AppendLine($"{prefixString}: {valueString}"); } /// /// Append a line containing a potentially both-endian Int16 to a StringBuilder /// public static StringBuilder AppendLineBothEndian(this StringBuilder sb, BothInt16? value, string prefixString) { if (value is null) return sb.AppendLine($"{prefixString}: [NULL]"); if (value.IsValid) return sb.AppendLine(value, prefixString); sb = sb.AppendLine(value.LittleEndian, $"{prefixString} (Little-Endian)"); return sb.AppendLine(value.BigEndian, $"{prefixString} (Big-Endian)"); } /// /// Append a line containing a UInt16 to a StringBuilder /// public static StringBuilder AppendLine(this StringBuilder sb, ushort? value, string prefixString) { string valueString = value is null ? "[NULL]" : $"{value} (0x{value:X4})"; return sb.AppendLine($"{prefixString}: {valueString}"); } /// /// Append a line containing a potentially both-endian UInt16 to a StringBuilder /// public static StringBuilder AppendLineBothEndian(this StringBuilder sb, BothUInt16? value, string prefixString) { if (value is null) return sb.AppendLine($"{prefixString}: [NULL]"); if (value.IsValid) return sb.AppendLine(value, prefixString); sb = sb.AppendLine(value.LittleEndian, $"{prefixString} (Little-Endian)"); return sb.AppendLine(value.BigEndian, $"{prefixString} (Big-Endian)"); } #if NET5_0_OR_GREATER /// /// Append a line containing a Half to a StringBuilder /// public static StringBuilder AppendLine(this StringBuilder sb, Half? value, string prefixString) { string valueString = value is null ? "[NULL]" : $"{value}"; return sb.AppendLine($"{prefixString}: {valueString}"); } #endif /// /// Append a line containing a Int24 to a StringBuilder /// public static StringBuilder AppendLine(this StringBuilder sb, Int24? value, string prefixString) { string hexValue = value is null ? string.Empty : $"{(int)value:X8}".Substring(2, 6); string valueString = value is null ? "[NULL]" : $"{(int)value} (0x{hexValue})"; return sb.AppendLine($"{prefixString}: {valueString}"); } /// /// Append a line containing a UInt24 to a StringBuilder /// public static StringBuilder AppendLine(this StringBuilder sb, UInt24? value, string prefixString) { string hexValue = value is null ? string.Empty : $"{(uint)value:X8}".Substring(2, 6); string valueString = value is null ? "[NULL]" : $"{(uint)value} (0x{hexValue})"; return sb.AppendLine($"{prefixString}: {valueString}"); } /// /// Append a line containing a Int32 to a StringBuilder /// public static StringBuilder AppendLine(this StringBuilder sb, int? value, string prefixString) { string valueString = value is null ? "[NULL]" : $"{value} (0x{value:X8})"; return sb.AppendLine($"{prefixString}: {valueString}"); } /// /// Append a line containing a potentially both-endian Int32 to a StringBuilder /// public static StringBuilder AppendLineBothEndian(this StringBuilder sb, BothInt32? value, string prefixString) { if (value is null) return sb.AppendLine($"{prefixString}: [NULL]"); if (value.IsValid) return sb.AppendLine(value, prefixString); sb = sb.AppendLine(value.LittleEndian, $"{prefixString} (Little-Endian)"); return sb.AppendLine(value.BigEndian, $"{prefixString} (Big-Endian)"); } /// /// Append a line containing a UInt32 to a StringBuilder /// public static StringBuilder AppendLine(this StringBuilder sb, uint? value, string prefixString) { string valueString = value is null ? "[NULL]" : $"{value} (0x{value:X8})"; return sb.AppendLine($"{prefixString}: {valueString}"); } /// /// Append a line containing a potentially both-endian UInt32 to a StringBuilder /// public static StringBuilder AppendLineBothEndian(this StringBuilder sb, BothUInt32? value, string prefixString) { if (value is null) return sb.AppendLine($"{prefixString}: [NULL]"); if (value.IsValid) return sb.AppendLine(value, prefixString); sb = sb.AppendLine(value.LittleEndian, $"{prefixString} (Little-Endian)"); return sb.AppendLine(value.BigEndian, $"{prefixString} (Big-Endian)"); } /// /// Append a line containing a Single to a StringBuilder /// public static StringBuilder AppendLine(this StringBuilder sb, float? value, string prefixString) { string valueString = value is null ? "[NULL]" : $"{value}"; return sb.AppendLine($"{prefixString}: {valueString}"); } /// /// Append a line containing a Int48 to a StringBuilder /// public static StringBuilder AppendLine(this StringBuilder sb, Int48? value, string prefixString) { string hexValue = value is null ? string.Empty : $"{(long)value:X16}".Substring(4, 12); string valueString = value is null ? "[NULL]" : $"{(long)value} (0x{hexValue})"; return sb.AppendLine($"{prefixString}: {valueString}"); } /// /// Append a line containing a UInt48 to a StringBuilder /// public static StringBuilder AppendLine(this StringBuilder sb, UInt48? value, string prefixString) { string hexValue = value is null ? string.Empty : $"{(ulong)value:X16}".Substring(4, 12); string valueString = value is null ? "[NULL]" : $"{(ulong)value} (0x{hexValue})"; return sb.AppendLine($"{prefixString}: {valueString}"); } /// /// Append a line containing a Int64 to a StringBuilder /// public static StringBuilder AppendLine(this StringBuilder sb, long? value, string prefixString) { string valueString = value is null ? "[NULL]" : $"{value} (0x{value:X16})"; return sb.AppendLine($"{prefixString}: {valueString}"); } /// /// Append a line containing a potentially both-endian Int64 to a StringBuilder /// public static StringBuilder AppendLineBothEndian(this StringBuilder sb, BothInt64? value, string prefixString) { if (value is null) return sb.AppendLine($"{prefixString}: [NULL]"); if (value.IsValid) return sb.AppendLine(value, prefixString); sb = sb.AppendLine(value.LittleEndian, $"{prefixString} (Little-Endian)"); return sb.AppendLine(value.BigEndian, $"{prefixString} (Big-Endian)"); } /// /// Append a line containing a UInt64 to a StringBuilder /// public static StringBuilder AppendLine(this StringBuilder sb, ulong? value, string prefixString) { string valueString = value is null ? "[NULL]" : $"{value} (0x{value:X16})"; return sb.AppendLine($"{prefixString}: {valueString}"); } /// /// Append a line containing a potentially both-endian UInt64 to a StringBuilder /// public static StringBuilder AppendLineBothEndian(this StringBuilder sb, BothUInt64? value, string prefixString) { if (value is null) return sb.AppendLine($"{prefixString}: [NULL]"); if (value.IsValid) return sb.AppendLine(value, prefixString); sb = sb.AppendLine(value.LittleEndian, $"{prefixString} (Little-Endian)"); return sb.AppendLine(value.BigEndian, $"{prefixString} (Big-Endian)"); } /// /// Append a line containing a Double to a StringBuilder /// public static StringBuilder AppendLine(this StringBuilder sb, double? value, string prefixString) { string valueString = value is null ? "[NULL]" : $"{value}"; return sb.AppendLine($"{prefixString}: {valueString}"); } #if NET7_0_OR_GREATER /// /// Append a line containing a Int128 to a StringBuilder /// public static StringBuilder AppendLine(this StringBuilder sb, Int128? value, string prefixString) { string valueString = value is null ? "[NULL]" : $"{value} (0x{value:X32})"; return sb.AppendLine($"{prefixString}: {valueString}"); } /// /// Append a line containing a UInt128 to a StringBuilder /// public static StringBuilder AppendLine(this StringBuilder sb, UInt128? value, string prefixString) { string valueString = value is null ? "[NULL]" : $"{value} (0x{value:X32})"; return sb.AppendLine($"{prefixString}: {valueString}"); } #endif /// /// Append a line containing a Decimal to a StringBuilder /// public static StringBuilder AppendLine(this StringBuilder sb, decimal? value, string prefixString) { string valueString = value is null ? "[NULL]" : $"{value}"; return sb.AppendLine($"{prefixString}: {valueString}"); } /// /// Append a line containing a string to a StringBuilder /// public static StringBuilder AppendLine(this StringBuilder sb, string? value, string prefixString) { string valueString = value ?? "[NULL]"; if (valueString.Length == 0) return sb.AppendLine($"{prefixString}: [EMPTY]"); return sb.AppendLine($"{prefixString}: {valueString}"); } /// /// Append a line containing a Guid to a StringBuilder /// public static StringBuilder AppendLine(this StringBuilder sb, Guid? value, string prefixString) { string valueString = value is null ? "[NULL]" : value.Value.ToString(); return sb.AppendLine($"{prefixString}: {valueString}"); } /// /// Append a line containing a UInt8[] value to a StringBuilder /// public static StringBuilder AppendLine(this StringBuilder sb, sbyte[]? value, string prefixString) { byte[]? valueArray = value is null ? null : Array.ConvertAll(value, b => (byte)b); string valueString = valueArray is null ? "[NULL]" : BitConverter.ToString(valueArray).Replace('-', ' '); if (valueString.Length == 0) return sb.AppendLine($"{prefixString}: [EMPTY]"); return sb.AppendLine($"{prefixString}: {valueString}"); } /// /// Append a line containing a UInt8[] value to a StringBuilder /// public static StringBuilder AppendLine(this StringBuilder sb, byte[]? value, string prefixString) { string valueString = value is null ? "[NULL]" : BitConverter.ToString(value).Replace('-', ' '); if (valueString.Length == 0) return sb.AppendLine($"{prefixString}: [EMPTY]"); return sb.AppendLine($"{prefixString}: {valueString}"); } /// /// Append a line containing a UInt8[] value as a string to a StringBuilder /// public static StringBuilder AppendLine(this StringBuilder sb, byte[]? value, string prefixString, Encoding encoding) { string valueString = value is null ? "[NULL]" : encoding.GetString(value).Replace("\0", string.Empty); if (valueString.Length == 0) return sb.AppendLine($"{prefixString}: [EMPTY]"); return sb.AppendLine($"{prefixString}: {valueString}"); } /// /// Append a line containing a UInt8[][] value to a StringBuilder /// public static StringBuilder AppendLine(this StringBuilder sb, byte[][]? value, string prefixString) { string valueString = "[NULL]"; if (value is not null) { var valueArr = Array.ConvertAll(value, ba => ba is null ? "[NULL]" : BitConverter.ToString(ba).Replace('-', ' ')); valueString = string.Join(", ", valueArr); } if (valueString.Length == 0) return sb.AppendLine($"{prefixString}: [EMPTY]"); return sb.AppendLine($"{prefixString}: {valueString}"); } /// /// Append a line containing a Char[] value to a StringBuilder /// public static StringBuilder AppendLine(this StringBuilder sb, char[]? value, string prefixString) { string valueString = "[NULL]"; if (value is not null) { var valueArr = Array.ConvertAll(value, c => c.ToString()); valueString = string.Join(", ", valueArr); } if (valueString.Length == 0) return sb.AppendLine($"{prefixString}: [EMPTY]"); return sb.AppendLine($"{prefixString}: {valueString}"); } /// /// Append a line containing a Int16[] value to a StringBuilder /// public static StringBuilder AppendLine(this StringBuilder sb, short[]? value, string prefixString) { string valueString = "[NULL]"; if (value is not null) { var valueArr = Array.ConvertAll(value, s => s.ToString()); valueString = string.Join(", ", valueArr); } if (valueString.Length == 0) return sb.AppendLine($"{prefixString}: [EMPTY]"); return sb.AppendLine($"{prefixString}: {valueString}"); } /// /// Append a line containing a UInt16[] value to a StringBuilder /// public static StringBuilder AppendLine(this StringBuilder sb, ushort[]? value, string prefixString) { string valueString = "[NULL]"; if (value is not null) { var valueArr = Array.ConvertAll(value, u => u.ToString()); valueString = string.Join(", ", valueArr); } if (valueString.Length == 0) return sb.AppendLine($"{prefixString}: [EMPTY]"); return sb.AppendLine($"{prefixString}: {valueString}"); } #if NET5_0_OR_GREATER /// /// Append a line containing a Half[] value to a StringBuilder /// public static StringBuilder AppendLine(this StringBuilder sb, Half[]? value, string prefixString) { string valueString = "[NULL]"; if (value is not null) { var valueArr = Array.ConvertAll(value, u => u.ToString()); valueString = string.Join(", ", valueArr); } if (valueString.Length == 0) return sb.AppendLine($"{prefixString}: [EMPTY]"); return sb.AppendLine($"{prefixString}: {valueString}"); } #endif /// /// Append a line containing a Int24[] value to a StringBuilder /// public static StringBuilder AppendLine(this StringBuilder sb, Int24[]? value, string prefixString) { string valueString = "[NULL]"; if (value is not null) { var valueArr = Array.ConvertAll(value, i => i.ToString()); valueString = string.Join(", ", valueArr); } if (valueString.Length == 0) return sb.AppendLine($"{prefixString}: [EMPTY]"); return sb.AppendLine($"{prefixString}: {valueString}"); } /// /// Append a line containing a UInt24[] value to a StringBuilder /// public static StringBuilder AppendLine(this StringBuilder sb, UInt24[]? value, string prefixString) { string valueString = "[NULL]"; if (value is not null) { var valueArr = Array.ConvertAll(value, u => u.ToString()); valueString = string.Join(", ", valueArr); } if (valueString.Length == 0) return sb.AppendLine($"{prefixString}: [EMPTY]"); return sb.AppendLine($"{prefixString}: {valueString}"); } /// /// Append a line containing a Int32[] value to a StringBuilder /// public static StringBuilder AppendLine(this StringBuilder sb, int[]? value, string prefixString) { string valueString = "[NULL]"; if (value is not null) { var valueArr = Array.ConvertAll(value, i => i.ToString()); valueString = string.Join(", ", valueArr); } if (valueString.Length == 0) return sb.AppendLine($"{prefixString}: [EMPTY]"); return sb.AppendLine($"{prefixString}: {valueString}"); } /// /// Append a line containing a UInt32[] value to a StringBuilder /// public static StringBuilder AppendLine(this StringBuilder sb, uint[]? value, string prefixString) { string valueString = "[NULL]"; if (value is not null) { var valueArr = Array.ConvertAll(value, u => u.ToString()); valueString = string.Join(", ", valueArr); } if (valueString.Length == 0) return sb.AppendLine($"{prefixString}: [EMPTY]"); return sb.AppendLine($"{prefixString}: {valueString}"); } /// /// Append a line containing a Single[] value to a StringBuilder /// public static StringBuilder AppendLine(this StringBuilder sb, float[]? value, string prefixString) { string valueString = "[NULL]"; if (value is not null) { var valueArr = Array.ConvertAll(value, u => u.ToString()); valueString = string.Join(", ", valueArr); } if (valueString.Length == 0) return sb.AppendLine($"{prefixString}: [EMPTY]"); return sb.AppendLine($"{prefixString}: {valueString}"); } /// /// Append a line containing a Int48[] value to a StringBuilder /// public static StringBuilder AppendLine(this StringBuilder sb, Int48[]? value, string prefixString) { string valueString = "[NULL]"; if (value is not null) { var valueArr = Array.ConvertAll(value, l => l.ToString()); valueString = string.Join(", ", valueArr); } if (valueString.Length == 0) return sb.AppendLine($"{prefixString}: [EMPTY]"); return sb.AppendLine($"{prefixString}: {valueString}"); } /// /// Append a line containing a UInt48[] value to a StringBuilder /// public static StringBuilder AppendLine(this StringBuilder sb, UInt48[]? value, string prefixString) { string valueString = "[NULL]"; if (value is not null) { var valueArr = Array.ConvertAll(value, u => u.ToString()); valueString = string.Join(", ", valueArr); } if (valueString.Length == 0) return sb.AppendLine($"{prefixString}: [EMPTY]"); return sb.AppendLine($"{prefixString}: {valueString}"); } /// /// Append a line containing a Int64[] value to a StringBuilder /// public static StringBuilder AppendLine(this StringBuilder sb, long[]? value, string prefixString) { string valueString = "[NULL]"; if (value is not null) { var valueArr = Array.ConvertAll(value, l => l.ToString()); valueString = string.Join(", ", valueArr); } if (valueString.Length == 0) return sb.AppendLine($"{prefixString}: [EMPTY]"); return sb.AppendLine($"{prefixString}: {valueString}"); } /// /// Append a line containing a UInt64[] value to a StringBuilder /// public static StringBuilder AppendLine(this StringBuilder sb, ulong[]? value, string prefixString) { string valueString = "[NULL]"; if (value is not null) { var valueArr = Array.ConvertAll(value, u => u.ToString()); valueString = string.Join(", ", valueArr); } if (valueString.Length == 0) return sb.AppendLine($"{prefixString}: [EMPTY]"); return sb.AppendLine($"{prefixString}: {valueString}"); } /// /// Append a line containing a Double[] value to a StringBuilder /// public static StringBuilder AppendLine(this StringBuilder sb, double[]? value, string prefixString) { string valueString = "[NULL]"; if (value is not null) { var valueArr = Array.ConvertAll(value, u => u.ToString()); valueString = string.Join(", ", valueArr); } if (valueString.Length == 0) return sb.AppendLine($"{prefixString}: [EMPTY]"); return sb.AppendLine($"{prefixString}: {valueString}"); } #if NET7_0_OR_GREATER /// /// Append a line containing a Int64[] value to a StringBuilder /// public static StringBuilder AppendLine(this StringBuilder sb, Int128[]? value, string prefixString) { string valueString = "[NULL]"; if (value is not null) { var valueArr = Array.ConvertAll(value, l => l.ToString()); valueString = string.Join(", ", valueArr); } if (valueString.Length == 0) return sb.AppendLine($"{prefixString}: [EMPTY]"); return sb.AppendLine($"{prefixString}: {valueString}"); } /// /// Append a line containing a UInt64[] value to a StringBuilder /// public static StringBuilder AppendLine(this StringBuilder sb, UInt128[]? value, string prefixString) { string valueString = "[NULL]"; if (value is not null) { var valueArr = Array.ConvertAll(value, u => u.ToString()); valueString = string.Join(", ", valueArr); } if (valueString.Length == 0) return sb.AppendLine($"{prefixString}: [EMPTY]"); return sb.AppendLine($"{prefixString}: {valueString}"); } #endif /// /// Append a line containing a Decimal[] value to a StringBuilder /// public static StringBuilder AppendLine(this StringBuilder sb, decimal[]? value, string prefixString) { string valueString = "[NULL]"; if (value is not null) { var valueArr = Array.ConvertAll(value, u => u.ToString()); valueString = string.Join(", ", valueArr); } if (valueString.Length == 0) return sb.AppendLine($"{prefixString}: [EMPTY]"); return sb.AppendLine($"{prefixString}: {valueString}"); } /// /// Append a line containing a String[] value to a StringBuilder /// public static StringBuilder AppendLine(this StringBuilder sb, string?[]? value, string prefixString) { string valueString = "[NULL]"; if (value is not null) { var valueArr = Array.ConvertAll(value, s => s is null ? "[NULL]" : s); valueString = string.Join(", ", valueArr); } if (valueString.Length == 0) return sb.AppendLine($"{prefixString}: [EMPTY]"); return sb.AppendLine($"{prefixString}: {valueString}"); } /// /// Append a line containing a UInt64[] value to a StringBuilder /// public static StringBuilder AppendLine(this StringBuilder sb, Guid[]? value, string prefixString) { string valueString = "[NULL]"; if (value is not null) { var valueArr = Array.ConvertAll(value, g => g.ToString()); valueString = string.Join(", ", valueArr); } if (valueString.Length == 0) return sb.AppendLine($"{prefixString}: [EMPTY]"); return sb.AppendLine($"{prefixString}: {valueString}"); } } }