Multiprocotol Terminalprogram (BAT)
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.
MultiTerm/MultiTerm.Core/Model/MultiFormatString.cs

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