using CommunityToolkit.Mvvm.ComponentModel; using System.Text; namespace MultiTerm.Protocols.Model; /// /// A class that represents a Character and contains some additional information and methods. /// A time can be stored in combination with this Character using the property. E.g. to represent arrived or sent time. /// Several methods to display the Character in other formats than Unicode are provided. /// public partial class ExtendedChar { /// /// Data in the form of a character. UTF-16 code unit. /// public char Character { get; set; } /// /// Time that is associated with the . /// E.g. to represent arrived or sent time. /// public TimeOnly Time { get; private set; } /// /// Creates an instance of ExtendedChar with a given . /// Sets to now. /// /// data public ExtendedChar(char character) : this(character, TimeOnly.FromDateTime(DateTime.Now)) { } /// /// Creates an instance of ExtendedChar with a given and . /// Initializes string properties , and . /// /// data /// time public ExtendedChar(char character, TimeOnly time) { this.Character = character; this.Time = time; } public override string ToString() { return this.Character.ToString(); } public string ToUtf16String() { string characterString; // character is ASCII encoded and is a control sequence if (char.IsAscii(this.Character) && this.Character <= '\x001F') { // conver to unicode Control Picture (see https://en.wikipedia.org/wiki/Control_Pictures) characterString = ((char)('\u2400' + this.Character)).ToString(); // TODO Remove //characterString = this.Character switch //{ // '\t' => "\\t", // ' ' => " ", // '\n' => "\u240A", // '\r' => "\u240D", // '\v' => "\\v", // '\f' => "\\f", // _ => this.Character.ToString() //}; } // TODO Remove //else if (char.IsControl(this.Character)) //{ // characterString = ""; //} else { characterString = this.Character.ToString(); } return characterString; } public string ToHexString() { // hexadecimal converter for byte to string Converter hexConverter = (ch) => Convert.ToHexString(new byte[] { ch }); // extract bytes from character and convert to correct format return ConvertToString(GetCharacterByteArray(this.Character), hexConverter, 2); //// foreach byte convert to hex and add to string //string hexString = String.Empty; //for (int i = 0; i < byteArray.Length; i++) //{ // // add byte to string in binary format, padding left with zeros up to 8 // hexString += $"{Convert.ToString(byteArray[i], 2).PadLeft(8, '0')}"; // // if not last byte add space separator // if (i < byteArray.Length - 1) // { // hexString += " "; // } //} //return hexString; //// get byte array from character and convert to hexadecimal //return Convert.ToHexString(GetCharacterByteArray(this.Character)).PadLeft(2); } public string ToBinaryString() { // binary converter for byte to string Converter binaryConverter = (ch) => Convert.ToString(ch, 2); // extract bytes from character and convert to correct format return ConvertToString(GetCharacterByteArray(this.Character), binaryConverter, 8); } private static string ConvertToString(byte[] byteArray, Converter conversionFunction, int oneByteWidth) { // foreach byte convert to binary and add to string string resultString = String.Empty; // go through whole array for (int i = 0; i < byteArray.Length; i++) { // add byte to string in correct format, padding left with zeros up to width of one byte resultString += $"{conversionFunction(byteArray[i]).PadLeft(oneByteWidth, '0')}"; // if not last byte add space separator if (i < byteArray.Length - 1) { resultString += " "; } } return resultString; } private static byte[] GetCharacterByteArray(char character) { byte[] byteArray = Array.Empty(); if (char.IsAscii(character)) { byteArray = Encoding.ASCII.GetBytes(character.ToString()); } else { // extract bytes from utf16 character byteArray = Encoding.Unicode.GetBytes(character.ToString()); } return byteArray; } }