You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
171 lines
5.7 KiB
171 lines
5.7 KiB
using MultiTerm.Core.Types;
|
|
using System.Text;
|
|
|
|
namespace MultiTerm.Core.Model;
|
|
|
|
public class MultiFormatString
|
|
{
|
|
public List<Tuple<FormatType, string>> FormatValuePairs { get; private set; } = new();
|
|
|
|
public void Add(FormatType format, string value)
|
|
{
|
|
// check if value is valid, if yes add to FormatValuePairs
|
|
if (ValidateValue(format, value))
|
|
{
|
|
this.FormatValuePairs.Add(Tuple.Create(format, value));
|
|
}
|
|
}
|
|
|
|
public void Remove(int amount)
|
|
{
|
|
// guard amount <= 0
|
|
if (amount <= 0) throw new ArgumentException($"{nameof(amount)} cannot be <= 0");
|
|
|
|
// limit amount to maximum
|
|
int listCount = this.FormatValuePairs.Count;
|
|
if (amount > listCount)
|
|
{
|
|
amount = listCount;
|
|
}
|
|
|
|
// remove range
|
|
this.FormatValuePairs.RemoveRange( (listCount - amount) , amount);
|
|
}
|
|
|
|
// TODO Setup Unit Tests
|
|
public override string ToString()
|
|
{
|
|
StringBuilder stringBuilder = new();
|
|
string hexConversionCharacters = String.Empty, binaryConversionCharacters = String.Empty;
|
|
|
|
// parameter == null will force ending
|
|
void finalizeHexConversion(Tuple<FormatType, string>? formatValuePair)
|
|
{
|
|
// hex conversion ongoing?
|
|
if (String.IsNullOrEmpty(hexConversionCharacters) == false)
|
|
{
|
|
// ending conversion or reached limit of characters?
|
|
if (formatValuePair == null ||
|
|
formatValuePair.Item1 != FormatType.Hexadecimal ||
|
|
hexConversionCharacters.Count() == 4)
|
|
{
|
|
// finalize conversion
|
|
stringBuilder.Append(FromHexString(hexConversionCharacters));
|
|
// reset ongoing conversion
|
|
hexConversionCharacters = String.Empty;
|
|
}
|
|
}
|
|
}
|
|
|
|
// parameter == null will force ending
|
|
void finalizeBinaryConversion(Tuple<FormatType, string>? formatValuePair)
|
|
{
|
|
// binary conversion ongoing?
|
|
if (String.IsNullOrEmpty(binaryConversionCharacters) == false)
|
|
{
|
|
// ending conversion or reached limit of characters?
|
|
if (formatValuePair == null ||
|
|
formatValuePair.Item1 != FormatType.Binary ||
|
|
binaryConversionCharacters.Count() == 16)
|
|
{
|
|
// finalize conversion
|
|
stringBuilder.Append(FromBinaryString(binaryConversionCharacters));
|
|
// reset ongoing conversion
|
|
binaryConversionCharacters = String.Empty;
|
|
}
|
|
}
|
|
}
|
|
|
|
foreach (var formatValuePair in this.FormatValuePairs)
|
|
{
|
|
finalizeHexConversion(formatValuePair);
|
|
finalizeBinaryConversion(formatValuePair);
|
|
|
|
switch (formatValuePair.Item1) // switch by format
|
|
{
|
|
case FormatType.Character:
|
|
stringBuilder.Append(formatValuePair.Item2);
|
|
break;
|
|
|
|
case FormatType.Hexadecimal:
|
|
hexConversionCharacters += formatValuePair.Item2;
|
|
break;
|
|
|
|
case FormatType.Binary:
|
|
binaryConversionCharacters += formatValuePair.Item2;
|
|
break;
|
|
|
|
default:
|
|
throw new NotImplementedException($"'{nameof(ToString)}()' does not implement conversion for format {formatValuePair.Item1}");
|
|
}
|
|
}
|
|
|
|
finalizeHexConversion(null);
|
|
finalizeBinaryConversion(null);
|
|
|
|
return stringBuilder.ToString();
|
|
}
|
|
|
|
|
|
public static bool ValidateValue(FormatType format, string value)
|
|
{
|
|
// invalid if more than one character
|
|
if(value.Count() > 1)
|
|
{ return false; }
|
|
|
|
// extract character
|
|
var character = value.First();
|
|
|
|
switch (format)
|
|
{
|
|
case FormatType.Character:
|
|
return true;
|
|
|
|
case FormatType.Hexadecimal:
|
|
if (character >= '0' && character <= '9' ||
|
|
character >= 'A' && character <= 'F' ||
|
|
character >= 'a' && character <= 'f')
|
|
{ return true; }
|
|
else
|
|
{ return false; };
|
|
|
|
case FormatType.Binary:
|
|
if (character == '0' || character == '1')
|
|
{ return true; }
|
|
else
|
|
{ return false; };
|
|
|
|
default:
|
|
throw new NotImplementedException($"'{nameof(ValidateValue)}()' does not implement validation for format {format}");
|
|
}
|
|
}
|
|
|
|
// from: https://stackoverflow.com/questions/724862/converting-from-hex-to-string
|
|
// test with: returns: "Hello world" for "48656C6C6F20776F726C64"
|
|
// see https://www.fileformat.info/info/charset/UTF-16/list.htm
|
|
public static string FromHexString(string hexString)
|
|
{
|
|
// Added PadLeft so strings with one character do not get ignored
|
|
string internalHexString = hexString.PadLeft(4, '0');
|
|
var bytes = new byte[internalHexString.Length / 2];
|
|
for (var i = 0; i < bytes.Length; i++)
|
|
{
|
|
bytes[i] = Convert.ToByte(internalHexString.Substring(i * 2, 2), 16);
|
|
}
|
|
|
|
return Encoding.BigEndianUnicode.GetString(bytes);
|
|
}
|
|
|
|
public static string FromBinaryString(string binaryString)
|
|
{
|
|
string internalBinaryString = binaryString.PadLeft(16, '0');
|
|
var bytes = new byte[internalBinaryString.Length / 8];
|
|
for (var i = 0; i < bytes.Length; i++)
|
|
{
|
|
bytes[i] = Convert.ToByte(internalBinaryString.Substring(i * 8, 8), 2);
|
|
}
|
|
|
|
return Encoding.BigEndianUnicode.GetString(bytes);
|
|
}
|
|
|
|
}
|
|
|