116 lines
3.4 KiB
C#
116 lines
3.4 KiB
C#
using System;
|
|
using System.Globalization;
|
|
using System.Linq;
|
|
using System.Numerics;
|
|
|
|
namespace IOB_UT_NEXT.Services.Core
|
|
{
|
|
public class BinaryUtils : IFormatProvider, ICustomFormatter
|
|
{
|
|
#region Public Methods
|
|
|
|
public string Format(string format, object arg, IFormatProvider formatProvider)
|
|
{
|
|
if (arg == null) return string.Empty;
|
|
|
|
// 1. Estrazione del formato (B, O, H)
|
|
string thisFmt = string.IsNullOrEmpty(format) ? string.Empty : format.Substring(0, 1).ToUpper();
|
|
|
|
// 2. Pattern matching supportato da C# 7.0+
|
|
byte[] bytes;
|
|
switch (arg)
|
|
{
|
|
case sbyte sb:
|
|
bytes = new byte[] { unchecked((byte)sb) };
|
|
break;
|
|
|
|
case byte b:
|
|
bytes = new byte[] { b };
|
|
break;
|
|
|
|
case short s:
|
|
bytes = BitConverter.GetBytes(s);
|
|
break;
|
|
|
|
case ushort us:
|
|
bytes = BitConverter.GetBytes(us);
|
|
break;
|
|
|
|
case int i:
|
|
bytes = BitConverter.GetBytes(i);
|
|
break;
|
|
|
|
case uint ui:
|
|
bytes = BitConverter.GetBytes(ui);
|
|
break;
|
|
|
|
case long l:
|
|
bytes = BitConverter.GetBytes(l);
|
|
break;
|
|
|
|
case ulong ul:
|
|
bytes = BitConverter.GetBytes(ul);
|
|
break;
|
|
|
|
case BigInteger bi:
|
|
bytes = bi.ToByteArray();
|
|
break;
|
|
|
|
default:
|
|
// Se non è un numero supportato, delega alla formattazione standard
|
|
return HandleOtherFormats(format, arg);
|
|
}
|
|
|
|
// 3. Formattazione e unione dei byte
|
|
switch (thisFmt)
|
|
{
|
|
case "B":
|
|
return FormatBytes(bytes, 2, 8);
|
|
|
|
case "O":
|
|
return FormatBytes(bytes, 8, 4);
|
|
|
|
case "H":
|
|
return FormatBytes(bytes, 16, 2);
|
|
|
|
default:
|
|
return HandleOtherFormats(format, arg);
|
|
}
|
|
}
|
|
|
|
public object GetFormat(Type formatType)
|
|
{
|
|
return formatType == typeof(ICustomFormatter) ? this : null;
|
|
}
|
|
|
|
#endregion Public Methods
|
|
|
|
#region Private Methods
|
|
|
|
private string FormatBytes(byte[] bytes, int baseNumber, int padding)
|
|
{
|
|
// Reverse per rispettare l'ordine Big-Endian dell'originale
|
|
var formattedParts = bytes.Reverse().Select(b => Convert.ToString(b, baseNumber).PadLeft(padding, '0'));
|
|
return string.Join(" ", formattedParts);
|
|
}
|
|
|
|
private string HandleOtherFormats(string format, object arg)
|
|
{
|
|
try
|
|
{
|
|
// Pattern matching base disponibile in C# 7.0
|
|
if (arg is IFormattable formattable)
|
|
{
|
|
return formattable.ToString(format, CultureInfo.CurrentCulture);
|
|
}
|
|
return arg.ToString();
|
|
}
|
|
catch (FormatException e)
|
|
{
|
|
throw new FormatException($"The format of '{format}' is invalid.", e);
|
|
}
|
|
}
|
|
|
|
#endregion Private Methods
|
|
}
|
|
} |