diff --git a/MultiTerm.Core.Tests/ExtendedByteTests.cs b/MultiTerm.Core.Tests/ExtendedByteTests.cs
new file mode 100644
index 0000000..f956352
--- /dev/null
+++ b/MultiTerm.Core.Tests/ExtendedByteTests.cs
@@ -0,0 +1,87 @@
+using FluentAssertions;
+using MultiTerm.Protocols.Model;
+
+namespace MultiTerm.Protocols.Tests;
+
+[TestFixture(Author = "JonasArnold")]
+public class ExtendedByteTests
+{
+ // testname: thema_aktion_expectedout
+ // ablauf: arrange, act, assert
+ [SetUp]
+ public void Setup()
+ {
+ }
+
+ [Test]
+ [TestCase((byte)40 , "(")]
+ [TestCase((byte)10, "\n")]
+ [TestCase((byte)13, "\r")]
+ [TestCase((byte)32, " ")]
+ [TestCase((byte)125, "}")]
+ [TestCase((byte)128, "?")]
+ public void ToString_ByteConverted_ResultsInAsciiEncodedString(byte dataByte, string expectedOutcome)
+ {
+ // Arrange
+ ExtendedByte extdByte = new(dataByte);
+
+ // Act
+ var toStringResult = extdByte.ToString();
+
+ // Assert
+ toStringResult.Should().BeEquivalentTo(expectedOutcome);
+ }
+
+ [Test]
+ [TestCase((byte)40, "(")]
+ [TestCase((byte)10, "\u240A")]
+ [TestCase((byte)13, "\u240D")]
+ [TestCase((byte)32, " ")]
+ [TestCase((byte)125, "}")]
+ [TestCase((byte)128, "?")]
+ public void ToCharacterString_ByteConverted_ResultsInDisplayableCharacterString(byte dataByte, string expectedOutcome)
+ {
+ // Arrange
+ ExtendedByte extdByte = new(dataByte);
+
+ // Act
+ var toStringResult = extdByte.ToCharacterString();
+
+ // Assert
+ toStringResult.Should().BeEquivalentTo(expectedOutcome);
+ }
+
+ [Test]
+ [TestCase((byte)30, "00011110")]
+ [TestCase((byte)10, "00001010")]
+ [TestCase((byte)240, "11110000")]
+ public void ToBinaryString_ByteConverted_ResultsInCorrectlyFormattedBinaryString(byte dataByte, string expectedOutcome)
+ {
+ // Arrange
+ ExtendedByte extdByte = new(dataByte);
+
+ // Act
+ var toStringResult = extdByte.ToBinaryString();
+
+ // Assert
+ toStringResult.Should().BeEquivalentTo(expectedOutcome);
+ }
+
+ [Test]
+ [TestCase((byte)2, "02")]
+ [TestCase((byte)10, "0A")]
+ [TestCase((byte)127, "7F")]
+ [TestCase((byte)240, "F0")]
+ public void ToHexString_ByteConverted_ResultsInCorrectlyFormattedHexString(byte dataByte, string expectedOutcome)
+ {
+ // Arrange
+ ExtendedByte extdByte = new(dataByte);
+
+ // Act
+ var toStringResult = extdByte.ToHexString();
+
+ // Assert
+ toStringResult.Should().BeEquivalentTo(expectedOutcome);
+ }
+
+}
\ No newline at end of file
diff --git a/MultiTerm.Core.Tests/MultiTerm.Protocols.Tests.csproj b/MultiTerm.Core.Tests/MultiTerm.Protocols.Tests.csproj
new file mode 100644
index 0000000..413d002
--- /dev/null
+++ b/MultiTerm.Core.Tests/MultiTerm.Protocols.Tests.csproj
@@ -0,0 +1,24 @@
+
+
+
+ net6.0
+ enable
+ enable
+
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/MultiTerm.Core.Tests/Usings.cs b/MultiTerm.Core.Tests/Usings.cs
new file mode 100644
index 0000000..cefced4
--- /dev/null
+++ b/MultiTerm.Core.Tests/Usings.cs
@@ -0,0 +1 @@
+global using NUnit.Framework;
\ No newline at end of file
diff --git a/MultiTerm.Core/ViewModel/ByteDataViewModel.cs b/MultiTerm.Core/ViewModel/ByteDataViewModel.cs
new file mode 100644
index 0000000..b5ef3fd
--- /dev/null
+++ b/MultiTerm.Core/ViewModel/ByteDataViewModel.cs
@@ -0,0 +1,53 @@
+using CommunityToolkit.Mvvm.ComponentModel;
+using MultiTerm.Protocols.Model;
+using System.Text;
+
+namespace MultiTerm.Core.ViewModel;
+
+public partial class ByteDataViewModel : ObservableObject, IDataViewModel
+{
+ ///
+ /// Object of data model.
+ ///
+ private readonly ExtendedByte data;
+
+ #region IDataViewModel Implementation
+
+ [ObservableProperty]
+ private int lineIdentifier;
+
+ [ObservableProperty]
+ private TimeOnly time;
+
+ [ObservableProperty]
+ private string displayStringChar = String.Empty;
+
+ [ObservableProperty]
+ private string displayStringHex = String.Empty;
+
+ [ObservableProperty]
+ private string displayStringBin = String.Empty;
+
+ #endregion
+
+ ///
+ /// Allows access to the low level data byte.
+ ///
+ public byte Byte => this.data.Byte;
+
+ ///
+ /// Instanciates new .
+ /// Initializes internal variables with data according to .
+ ///
+ /// data
+ /// identifies line in which this byte is located
+ public ByteDataViewModel(ExtendedByte extendedByte, int lineIdentifier)
+ {
+ this.data = extendedByte;
+ this.lineIdentifier = lineIdentifier;
+ this.DisplayStringChar = extendedByte.ToCharacterString();
+ this.DisplayStringHex = extendedByte.ToHexString();
+ this.DisplayStringBin = extendedByte.ToBinaryString();
+ this.Time = extendedByte.Time;
+ }
+}
diff --git a/MultiTerm.Core/ViewModel/CharacterDataViewModel.cs b/MultiTerm.Core/ViewModel/CharacterDataViewModel.cs
deleted file mode 100644
index 59f9d1e..0000000
--- a/MultiTerm.Core/ViewModel/CharacterDataViewModel.cs
+++ /dev/null
@@ -1,46 +0,0 @@
-using CommunityToolkit.Mvvm.ComponentModel;
-using MultiTerm.Protocols.Model;
-
-namespace MultiTerm.Core.ViewModel;
-
-public partial class CharacterDataViewModel : ObservableObject, IDataViewModel
-{
- ///
- /// Object of data model.
- ///
- private readonly ExtendedChar character;
-
- #region IDataViewModel Implementation
-
- [ObservableProperty]
- private int lineIdentifier;
-
- [ObservableProperty]
- private TimeOnly time;
-
- [ObservableProperty]
- private string displayString = String.Empty;
-
- [ObservableProperty]
- private string displayStringHex = String.Empty;
-
- [ObservableProperty]
- private string displayStringBin = String.Empty;
-
- #endregion
-
- ///
- /// Allows access to character of this instance.
- ///
- public char Character { get { return this.character.Character; } }
-
- public CharacterDataViewModel(ExtendedChar character, int lineIdentifier)
- {
- this.character = character;
- this.lineIdentifier = lineIdentifier;
- this.DisplayString = character.ToUtf16String();
- this.DisplayStringHex = character.ToHexString();
- this.DisplayStringBin = character.ToBinaryString();
- this.Time = character.Time;
- }
-}
diff --git a/MultiTerm.Core/ViewModel/CommunicationDataViewModel.cs b/MultiTerm.Core/ViewModel/CommunicationDataViewModel.cs
index 81e96ba..ca97217 100644
--- a/MultiTerm.Core/ViewModel/CommunicationDataViewModel.cs
+++ b/MultiTerm.Core/ViewModel/CommunicationDataViewModel.cs
@@ -4,26 +4,27 @@ using CommunityToolkit.Mvvm.ComponentModel;
using MultiTerm.Core.Types;
using MultiTerm.Protocols.Model;
using System.Collections.ObjectModel;
+using System.Text;
namespace MultiTerm.Core.ViewModel;
-public partial class CommunicationDataViewModel : ObservableObject, ICommunicationDataViewModel
+public partial class CommunicationDataViewModel : ObservableObject, ICommunicationDataViewModel
{
private readonly IContext uiContext;
private int dataCharacterCount = 0;
- private List? listOfPreviousCharacters = null;
+ private List? listOfPreviousCharacters = null;
#region ICommunicationDataViewModel Implementation
[ObservableProperty]
- private ObservableCollection data = new();
+ private ObservableCollection data = new();
[ObservableProperty]
private string dataAsString = string.Empty;
[ObservableProperty]
- private ObservableCollection? selected = new();
+ private ObservableCollection? selected = new();
[ObservableProperty]
NewlineSeparatorType newlineSeparator = NewlineSeparatorType.None;
@@ -42,29 +43,30 @@ public partial class CommunicationDataViewModel : ObservableObject, ICommunicati
// int counter = 0;
// int lineNumber = 1;
// //List listOfChars = new();
- // foreach (var character in exampleData)
+ // foreach (var dataByte in exampleData)
// {
- // if(++counter > 100 || character == '\n')
+ // if(++counter > 100 || dataByte == '\n')
// {
// //this.ReceivedData.Add();
// //listOfChars = new List();
// counter = 0;
// lineNumber += 1;
// }
- // var extdChar = new ExtendedChar(character);
+ // var extdChar = new ExtendedChar(dataByte);
// //listOfChars.Add(extdChar);
// this.ReceivedData.Add(new DataViewModel(extdChar, lineNumber));
// }
//}
}
- public void HandleNewData(IEnumerable newRawData)
+ public void HandleNewData(IEnumerable newRawData)
{
// update collection and string, invoke ui thread if necessary
ContextHelpers.InvokeIfNecessary(this.uiContext, (Action)delegate
{
- InsertNewNewCharactersIntoCollection(this.Data, ref this.dataCharacterCount, ref this.listOfPreviousCharacters, this.NewlineSeparator, newRawData);
- this.DataAsString = InsertNewCharactersIntoString(this.DataAsString, newRawData);
+ this.DataAsString = InsertNewNewCharactersIntoCollection(this.Data, this.DataAsString,
+ ref this.dataCharacterCount, ref this.listOfPreviousCharacters,
+ this.NewlineSeparator, newRawData);
});
}
@@ -76,51 +78,69 @@ public partial class CommunicationDataViewModel : ObservableObject, ICommunicati
// update collection, invoke ui thread if necessary
ContextHelpers.InvokeIfNecessary(this.uiContext, (Action)delegate
{
- this.Data = ReorderCollection(this.Data, value);
- this.DataAsString = ReorderString(this.Data, value);
+ var reorderedCollection = ReorderCollection(this.Data, value);
+ this.Data = reorderedCollection.Item1;
+ this.DataAsString = reorderedCollection.Item2;
+ });
+ }
+
+
+ public void Clear()
+ {
+ // update collection and string, invoke ui thread if necessary
+ ContextHelpers.InvokeIfNecessary(this.uiContext, (Action)delegate
+ {
+ this.DataAsString = string.Empty;
+ this.Data.Clear();
});
}
#region Collection Manipulation
///
- /// Function that reorders a given collection with item type using the given .
+ /// Function that reorders a given collection with item type using the given .
/// Reordered collection is returned, but LineIdentifier is also overwritten in the parameter.
///
/// items in this collection will be reordered
/// separator between lines
- /// reordered collection
- private static ObservableCollection ReorderCollection(ObservableCollection currentCollection, NewlineSeparatorType newlineSeparatorType)
+ /// reordered collection and string
+ private static Tuple, string> ReorderCollection(ObservableCollection currentCollection, NewlineSeparatorType newlineSeparatorType)
{
- ObservableCollection newCollection = new();
+ ObservableCollection newCollection = new();
+ StringBuilder stringBuilder = new();
+
+ // local vars
int lineCounter = 0;
- List? previousCharacters = null;
+ List? previousBytes = null;
// iterate through items
- foreach (CharacterDataViewModel item in currentCollection)
+ foreach (ByteDataViewModel item in currentCollection)
{
item.LineIdentifier = lineCounter;
newCollection.Add(item);
+ stringBuilder.Append(item.DisplayStringChar);
- switch (ShouldIntroduceNewlineAfterThisCharacter(item.Character, previousCharacters, newlineSeparatorType))
+ switch (ShouldIntroduceNewlineAfterThisByte(item.Byte, previousBytes, newlineSeparatorType))
{
- case IntroduceNewlineAfterThisCharacterResult.NoNewline:
- // a decision could be made, previousCharacters can be cleared
- if (previousCharacters != null) { previousCharacters = null; }
+ case ShouldIntroduceNewlineAfterThisByteResult.NoNewline:
+ // a decision could be made, previousBytes can be cleared
+ if (previousBytes != null) { previousBytes = null; }
// nothing to do
break;
- case IntroduceNewlineAfterThisCharacterResult.IntroduceNewline:
- // a decision could be made, previousCharacters can be cleared
- if (previousCharacters != null) { previousCharacters = null; }
- // increase line count and break
+ case ShouldIntroduceNewlineAfterThisByteResult.IntroduceNewline:
+ // a decision could be made, previousBytes can be cleared
+ if (previousBytes != null) { previousBytes = null; }
+ // increase line count
lineCounter++;
+ // append line in string
+ stringBuilder.AppendLine();
break;
- case IntroduceNewlineAfterThisCharacterResult.RequiresMoreCharacters:
- // first time that more characters are required => create new list
- previousCharacters ??= new List();
- // add current character to list
- previousCharacters.Add(item.Character);
+ case ShouldIntroduceNewlineAfterThisByteResult.RequiresMoreCharacters:
+ // first time that more bytes are required => create new list
+ previousBytes ??= new List();
+ // add current byte to list
+ previousBytes.Add(item.Byte);
break;
default:
@@ -128,65 +148,77 @@ public partial class CommunicationDataViewModel : ObservableObject, ICommunicati
}
}
- return newCollection;
+ return Tuple.Create(newCollection, stringBuilder.ToString());
}
///
- /// Function that handles a collection of new characters that should end up in the collection .
+ /// Function that handles a collection of new bytes that should end up in the collection .
/// In case a new line is required, according to the given , it is automatically introduced.
- /// Following parameters need to be referenced and stored outside: and .
+ /// Following parameters need to be referenced and stored outside: and .
///
- /// collection to add the characters to
+ /// collection to add the bytes to
+ /// collection as string
/// current line count
- /// list of previous character, newest at the last position of the list, null if nothing is stored
+ /// list of previous bytes, newest at the last position of the list, null if nothing is stored
/// separator between seperate lines
- /// characters to add to the
+ /// bytes to add to the
+ /// string representation of data
/// in case of any error
- private static void InsertNewNewCharactersIntoCollection(ObservableCollection dataCollection,
+ private static string InsertNewNewCharactersIntoCollection(
+ ObservableCollection dataCollection,
+ string dataCollectionAsString,
ref int collectionLineCounter,
- ref List? previousCharacters,
+ ref List? previousBytes,
NewlineSeparatorType newlineSeparatorType,
- IEnumerable newCharacters)
+ IEnumerable newBytes)
{
- // go through every character
- foreach (var newExtdChar in newCharacters)
+ StringBuilder stringBuilder = new();
+ stringBuilder.Append(dataCollectionAsString);
+
+ // go through every byte
+ foreach (ExtendedByte newByte in newBytes)
{
- // add to collection with the current counter, invoking UI context if necssary
+ // add to collection and string with the current counter, invoking UI context if necssary
var currentLineCounter = collectionLineCounter;
- dataCollection.Add(new CharacterDataViewModel(newExtdChar, currentLineCounter));
+ dataCollection.Add(new ByteDataViewModel(newByte, currentLineCounter));
+ stringBuilder.Append(newByte.ToCharacterString());
- switch (ShouldIntroduceNewlineAfterThisCharacter(newExtdChar.Character, previousCharacters, newlineSeparatorType))
+ switch (ShouldIntroduceNewlineAfterThisByte(newByte.Byte, previousBytes, newlineSeparatorType))
{
- case IntroduceNewlineAfterThisCharacterResult.NoNewline:
- // a decision could be made, previousCharacters can be cleared
- if (previousCharacters != null) { previousCharacters = null; }
+ case ShouldIntroduceNewlineAfterThisByteResult.NoNewline:
+ // a decision could be made, previousBytes can be cleared
+ if (previousBytes != null) { previousBytes = null; }
// nothing to do
break;
- case IntroduceNewlineAfterThisCharacterResult.IntroduceNewline:
- // a decision could be made, previousCharacters can be cleared
- if (previousCharacters != null) { previousCharacters = null; }
- // increase line count and break
+ case ShouldIntroduceNewlineAfterThisByteResult.IntroduceNewline:
+ // a decision could be made, previousBytes can be cleared
+ if (previousBytes != null) { previousBytes = null; }
+ // increase line count
collectionLineCounter++;
+ // append line in string
+ stringBuilder.AppendLine();
break;
- case IntroduceNewlineAfterThisCharacterResult.RequiresMoreCharacters:
- // first time that more characters are required => create new list
- previousCharacters ??= new List();
- // add current character to list
- previousCharacters.Add(newExtdChar.Character);
+ case ShouldIntroduceNewlineAfterThisByteResult.RequiresMoreCharacters:
+ // first time that more bytes are required => create new list
+ previousBytes ??= new List();
+ // add current byte to list
+ previousBytes.Add(newByte.Byte);
break;
default:
throw new Exception($"'{nameof(InsertNewNewCharactersIntoCollection)}()' failed because of error when checking if a newline should be introduced.");
}
}
+
+ return stringBuilder.ToString();
}
///
- /// Result type for
+ /// Result type for
///
- public enum IntroduceNewlineAfterThisCharacterResult
+ public enum ShouldIntroduceNewlineAfterThisByteResult
{
///
/// No newline is required.
@@ -194,7 +226,7 @@ public partial class CommunicationDataViewModel : ObservableObject, ICommunicati
NoNewline,
///
- /// A newline shall be introduced after this character.
+ /// A newline shall be introduced after this byte.
///
IntroduceNewline,
@@ -205,17 +237,17 @@ public partial class CommunicationDataViewModel : ObservableObject, ICommunicati
}
///
- /// Function to check wether a newline shall be introduced after the given character.
- /// Since some newline sequences will require multiple characters in correct order, a more complex handling is required, which is possible using this function.
+ /// Function to check wether a newline shall be introduced after the given .
+ /// Since some newline sequences will require multiple bytes in correct order, a more complex handling is required, which is possible using this function.
///
- /// the current character in the collection (or a single character)
- /// list of previous character, newest at the last position of the list, null if not required
+ /// the current dataByte in the collection (or a single byte)
+ /// list of previous bytes, newest at the last position of the list, null if not required
/// separator type
- /// complex result of type
+ /// enum result of type
/// if the handling for the is not implemented
- private static IntroduceNewlineAfterThisCharacterResult ShouldIntroduceNewlineAfterThisCharacter(char character, List? previousCharacters, NewlineSeparatorType newlineSeparatorType)
+ private static ShouldIntroduceNewlineAfterThisByteResult ShouldIntroduceNewlineAfterThisByte(byte dataByte, List? previousBytes, NewlineSeparatorType newlineSeparatorType)
{
- var result = IntroduceNewlineAfterThisCharacterResult.NoNewline;
+ var result = ShouldIntroduceNewlineAfterThisByteResult.NoNewline;
switch (newlineSeparatorType)
{
@@ -223,63 +255,41 @@ public partial class CommunicationDataViewModel : ObservableObject, ICommunicati
break;
case NewlineSeparatorType.CR:
- if (character == '\r')
+ if (dataByte == (byte)'\r')
{
- result = IntroduceNewlineAfterThisCharacterResult.IntroduceNewline;
+ result = ShouldIntroduceNewlineAfterThisByteResult.IntroduceNewline;
}
break;
case NewlineSeparatorType.LF:
- if (character == '\n')
+ if (dataByte == (byte)'\n')
{
- result = IntroduceNewlineAfterThisCharacterResult.IntroduceNewline;
+ result = ShouldIntroduceNewlineAfterThisByteResult.IntroduceNewline;
}
break;
case NewlineSeparatorType.CR_LF:
- if (character == '\r')
+ if (dataByte == (byte)'\r')
{
- result = IntroduceNewlineAfterThisCharacterResult.RequiresMoreCharacters;
+ result = ShouldIntroduceNewlineAfterThisByteResult.RequiresMoreCharacters;
}
- if (character == '\n')
+ if (dataByte == (byte)'\n')
{
- if (previousCharacters != null && previousCharacters.Last() == '\r')
+ if (previousBytes != null && previousBytes.Last() == (byte)'\r')
{
- result = IntroduceNewlineAfterThisCharacterResult.IntroduceNewline;
+ result = ShouldIntroduceNewlineAfterThisByteResult.IntroduceNewline;
}
}
break;
default:
- throw new NotImplementedException($"'{nameof(ShouldIntroduceNewlineAfterThisCharacter)}()' does not implement handling for {nameof(NewlineSeparatorType)} {newlineSeparatorType}");
+ throw new NotImplementedException($"'{nameof(ShouldIntroduceNewlineAfterThisByte)}()' does not implement handling for {nameof(NewlineSeparatorType)} {newlineSeparatorType}");
}
return result;
}
- #endregion
-
- #region String Manipulation
-
- // TODO Implement Line Handling
- private static string InsertNewCharactersIntoString(string dataAsString, IEnumerable newRawData)
- {
- string newDataAsString = dataAsString;
-
- foreach (ExtendedChar character in newRawData)
- {
- newDataAsString += character.Character;
- }
-
- return newDataAsString;
- }
-
- private static string ReorderString(ObservableCollection collection, NewlineSeparatorType value)
- {
- // Not yet implemented
- return "Not implemented";
- }
#endregion
}
diff --git a/MultiTerm.Core/ViewModel/ICommunicationDataViewModel.cs b/MultiTerm.Core/ViewModel/ICommunicationDataViewModel.cs
index 076a452..a5a6622 100644
--- a/MultiTerm.Core/ViewModel/ICommunicationDataViewModel.cs
+++ b/MultiTerm.Core/ViewModel/ICommunicationDataViewModel.cs
@@ -32,4 +32,9 @@ public interface ICommunicationDataViewModel where T_Data : IData
///
/// collection of new data to insert
void HandleNewData(IEnumerable data);
+
+ ///
+ /// Allows to clear the data.
+ ///
+ void Clear();
}
\ No newline at end of file
diff --git a/MultiTerm.Core/ViewModel/IDataViewModel.cs b/MultiTerm.Core/ViewModel/IDataViewModel.cs
index 7ba1c8f..50337a9 100644
--- a/MultiTerm.Core/ViewModel/IDataViewModel.cs
+++ b/MultiTerm.Core/ViewModel/IDataViewModel.cs
@@ -14,9 +14,9 @@ public interface IDataViewModel
TimeOnly Time { get; }
///
- /// Hosts a displayable string of the character (UTF-16 encoded).
+ /// Hosts a displayable string of the character (.NET: UTF-16 encoded).
///
- string DisplayString { get; }
+ string DisplayStringChar { get; }
///
/// Hosts a string of the character (hexadecimal format).
diff --git a/MultiTerm.Core/ViewModel/TerminalViewModel.cs b/MultiTerm.Core/ViewModel/TerminalViewModel.cs
index 105fa0f..0b25d36 100644
--- a/MultiTerm.Core/ViewModel/TerminalViewModel.cs
+++ b/MultiTerm.Core/ViewModel/TerminalViewModel.cs
@@ -62,13 +62,13 @@ public abstract partial class TerminalViewModel : ObservableObject, ITerminalVie
/// Holds communication data that was received via the communication protocol.
///
[ObservableProperty]
- private ICommunicationDataViewModel receivedData;
+ private ICommunicationDataViewModel receivedData;
///
/// Holds communication data that was sent via the communication protocol.
///
[ObservableProperty]
- private ICommunicationDataViewModel sentData;
+ private ICommunicationDataViewModel sentData;
///
/// Defines at which newline sequence the displayed data is wrapped. Defaults to none.
@@ -137,7 +137,7 @@ public abstract partial class TerminalViewModel : ObservableObject, ITerminalVie
// guard null
if (this.ReceivedData == null) { throw new NullReferenceException($"{nameof(CommunicationProtocol_ReceivedDataEvent)} found {nameof(this.ReceivedData)} to be null."); }
// handover data
- this.ReceivedData.HandleNewData(e.ReceivedCharacters);
+ this.ReceivedData.HandleNewData(e.ReceivedData);
}
private void CommunicationProtocol_SentDataEvent(object? sender, SentDataEventArgs e)
@@ -145,7 +145,7 @@ public abstract partial class TerminalViewModel : ObservableObject, ITerminalVie
// guard null
if (this.SentData == null) { throw new NullReferenceException($"{nameof(CommunicationProtocol_SentDataEvent)} found {nameof(this.SentData)} to be null."); }
// handover data
- this.SentData.HandleNewData(e.SentCharacters);
+ this.SentData.HandleNewData(e.SentData);
}
#endregion
diff --git a/MultiTerm.Protocols/Model/ExtendedByte.cs b/MultiTerm.Protocols/Model/ExtendedByte.cs
new file mode 100644
index 0000000..90b2f25
--- /dev/null
+++ b/MultiTerm.Protocols/Model/ExtendedByte.cs
@@ -0,0 +1,131 @@
+using CommunityToolkit.Mvvm.ComponentModel;
+using System.Text;
+
+namespace MultiTerm.Protocols.Model;
+
+///
+/// A class that represents a single and contains some additional information and methods.
+/// A time can be stored in combination with this using the property. E.g. to represent arrived or sent time.
+/// Several methods to display the in other formats are provided.
+///
+public partial class ExtendedByte
+{
+ ///
+ /// Data in the form of a byte.
+ ///
+ public byte Byte { 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 with a given .
+ /// Sets to now.
+ ///
+ /// data
+ public ExtendedByte(byte dataByte) : this(dataByte, TimeOnly.FromDateTime(DateTime.Now)) { }
+
+ ///
+ /// Creates an instance of with a given and .
+ ///
+ /// data
+ /// time
+ public ExtendedByte(byte dataByte, TimeOnly time)
+ {
+ this.Byte = dataByte;
+ this.Time = time;
+ }
+
+ ///
+ /// Returns this as ASCII encoded String.
+ ///
+ ///
+ public override string ToString()
+ {
+ return Encoding.ASCII.GetString(new byte[] { this.Byte });
+ }
+
+ ///
+ /// Returns displayable character as string.
+ /// ASCII control sequences are replaced with unicode control pictures.
+ ///
+ /// string with single character
+ public string ToCharacterString()
+ {
+ char character = (char)this.Byte;
+ string characterString;
+
+ // character is ASCII encoded and is a control sequence
+ if (char.IsAscii(character) && character <= '\x001F')
+ {
+ // conver to unicode Control Picture (see https://en.wikipedia.org/wiki/Control_Pictures)
+ characterString = ((char)('\u2400' + character)).ToString();
+ }
+ // else just convert using ASCII code
+ else if(char.IsAscii(character))
+ {
+ characterString = Encoding.ASCII.GetString(new byte[] { this.Byte });
+ }
+ else
+ {
+ characterString = "?";
+ }
+
+ return characterString;
+ }
+
+ ///
+ /// Returns displayable hex string.
+ ///
+ ///
+ public string ToHexString()
+ {
+ // hexadecimal converter for byte to string
+ static string hexConverter(byte ch) => Convert.ToHexString(new byte[] { ch });
+
+ // extract bytes from character and convert to correct format
+ return ConvertToString(new byte[] { this.Byte }, hexConverter, 2);
+ }
+
+ ///
+ /// Returns displayable binary string.
+ ///
+ ///
+ public string ToBinaryString()
+ {
+ // binary converter for byte to string
+ static string binaryConverter(byte ch) => Convert.ToString(ch, 2);
+
+ // extract bytes from character and convert to correct format
+ return ConvertToString(new byte[] { this.Byte }, binaryConverter, 8);
+ }
+
+ ///
+ /// Converts a to a string, using the given to convert a single byte to a character.
+ /// defines how many characters the result string should contain (the left side will be padded with zeroes).
+ ///
+ /// converte string
+ 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;
+ }
+}
diff --git a/MultiTerm.Protocols/Model/ExtendedChar.cs b/MultiTerm.Protocols/Model/ExtendedChar.cs
deleted file mode 100644
index 70aa18a..0000000
--- a/MultiTerm.Protocols/Model/ExtendedChar.cs
+++ /dev/null
@@ -1,156 +0,0 @@
-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;
- }
-}
diff --git a/MultiTerm.Protocols/ReceivedDataEventArgs.cs b/MultiTerm.Protocols/ReceivedDataEventArgs.cs
index 856185b..99ef028 100644
--- a/MultiTerm.Protocols/ReceivedDataEventArgs.cs
+++ b/MultiTerm.Protocols/ReceivedDataEventArgs.cs
@@ -4,10 +4,10 @@ namespace MultiTerm.Protocols;
public class ReceivedDataEventArgs : EventArgs
{
- public IEnumerable ReceivedCharacters { get; private set; }
+ public IEnumerable ReceivedData { get; private set; }
- public ReceivedDataEventArgs(IEnumerable receivedCharacters)
+ public ReceivedDataEventArgs(IEnumerable receivedData)
{
- this.ReceivedCharacters = receivedCharacters;
+ this.ReceivedData = receivedData;
}
}
diff --git a/MultiTerm.Protocols/SentDataEventArgs.cs b/MultiTerm.Protocols/SentDataEventArgs.cs
index ffa3c77..bb5b2d8 100644
--- a/MultiTerm.Protocols/SentDataEventArgs.cs
+++ b/MultiTerm.Protocols/SentDataEventArgs.cs
@@ -4,10 +4,10 @@ namespace MultiTerm.Protocols;
public class SentDataEventArgs : EventArgs
{
- public IEnumerable SentCharacters { get; private set; }
+ public IEnumerable SentData { get; private set; }
- public SentDataEventArgs(IEnumerable sentCharacters)
+ public SentDataEventArgs(IEnumerable sentData)
{
- this.SentCharacters = sentCharacters;
+ this.SentData = sentData;
}
}
\ No newline at end of file
diff --git a/MultiTerm.Protocols/Serial/SerialProtocol.cs b/MultiTerm.Protocols/Serial/SerialProtocol.cs
index ab5c2c7..2350239 100644
--- a/MultiTerm.Protocols/Serial/SerialProtocol.cs
+++ b/MultiTerm.Protocols/Serial/SerialProtocol.cs
@@ -76,14 +76,14 @@ public class SerialProtocol : CommunicationProtocol
while(ct.IsCancellationRequested == false)
{
// reads character based on configured encoding (here ASCII)
- int readCharacter = serialPort.ReadChar();
- if (readCharacter != -1) // -1 = timeout
+ int readByte = serialPort.ReadByte();
+ if (readByte != -1) // -1 = end of stream
{
// create extended char type
- var character = new ExtendedChar((char)readCharacter);
+ var character = new ExtendedByte((byte)readByte);
// report new data with event
- this.OnReceivedData(new ReceivedDataEventArgs(new ExtendedChar[] { character }));
+ this.OnReceivedData(new ReceivedDataEventArgs(new ExtendedByte[] { character }));
}
}
}
diff --git a/MultiTerm.Wpf.CustomControl/MultiFormatDataView/MultiFormatDataView.cs b/MultiTerm.Wpf.CustomControl/MultiFormatDataView/MultiFormatDataView.cs
index 031ac40..eb9d807 100644
--- a/MultiTerm.Wpf.CustomControl/MultiFormatDataView/MultiFormatDataView.cs
+++ b/MultiTerm.Wpf.CustomControl/MultiFormatDataView/MultiFormatDataView.cs
@@ -27,7 +27,7 @@ public class MultiFormatDataView : Control
#region Dependency Properties
public static readonly DependencyProperty DataSourceProperty =
DependencyProperty.Register("DataSource",
- typeof(ICommunicationDataViewModel), typeof(MultiFormatDataView),
+ typeof(ICommunicationDataViewModel), typeof(MultiFormatDataView),
new PropertyMetadata(null, OnDataSourcePropertyChanged));
public static readonly DependencyProperty SelectorItemsSourceProperty =
@@ -69,9 +69,9 @@ public class MultiFormatDataView : Control
/// .NET Property for DataSourceProperty.
///
[Bindable(true)]
- public ICommunicationDataViewModel DataSource
+ public ICommunicationDataViewModel DataSource
{
- get { return (ICommunicationDataViewModel)GetValue(DataSourceProperty); }
+ get { return (ICommunicationDataViewModel)GetValue(DataSourceProperty); }
set { SetValue(DataSourceProperty, value); }
}
@@ -195,12 +195,12 @@ public class MultiFormatDataView : Control
// manually create collection view
ICollectionView cv = CollectionViewSource.GetDefaultView(mfdv.DataSource.Data);
// add grouping
- PropertyGroupDescription groupDescription = new(nameof(CharacterDataViewModel.LineIdentifier));
+ PropertyGroupDescription groupDescription = new(nameof(ByteDataViewModel.LineIdentifier));
cv.GroupDescriptions.Add(groupDescription);
// add live grouping
if (cv is ICollectionViewLiveShaping cvLiveShaping && cvLiveShaping.CanChangeLiveGrouping)
{
- cvLiveShaping.LiveGroupingProperties.Add(nameof(CharacterDataViewModel.LineIdentifier));
+ cvLiveShaping.LiveGroupingProperties.Add(nameof(ByteDataViewModel.LineIdentifier));
cvLiveShaping.IsLiveGrouping = true;
}
// save collection view
@@ -247,7 +247,8 @@ public class MultiFormatDataView : Control
private void OnClearButtonClicked(object sender, RoutedEventArgs e)
{
// raise clear requested event
- this.DataSource.Data.Clear();
+ RoutedEventArgs args = new(ClearRequestedEvent);
+ RaiseEvent(args);
}
#region Selected Items handling
@@ -260,11 +261,11 @@ public class MultiFormatDataView : Control
if (this.tbCharOnlyView != null && this.tbCharOnlyView.SelectionLength > 0) { this.tbCharOnlyView.Select(0, 0); }
// otherwise update internal list
- foreach (CharacterDataViewModel item in e.RemovedItems)
+ foreach (ByteDataViewModel item in e.RemovedItems)
{
this.DataSource.Selected.Remove(item);
}
- foreach (CharacterDataViewModel item in e.AddedItems)
+ foreach (ByteDataViewModel item in e.AddedItems)
{
this.DataSource.Selected.Add(item);
}
@@ -272,7 +273,7 @@ public class MultiFormatDataView : Control
private void TextBoxCharOnlyView_SelectionChanged(object sender, RoutedEventArgs e)
{
- var newSelection = new ObservableCollection();
+ var newSelection = new ObservableCollection();
int selectionStartIndex = this.tbCharOnlyView!.SelectionStart;
// TEMP OLD
// extract text from the beginning to the start of the selected text
diff --git a/MultiTerm.Wpf.CustomControl/MultiFormatDataView/MultiFormatDataView.xaml b/MultiTerm.Wpf.CustomControl/MultiFormatDataView/MultiFormatDataView.xaml
index 019f419..45193bf 100644
--- a/MultiTerm.Wpf.CustomControl/MultiFormatDataView/MultiFormatDataView.xaml
+++ b/MultiTerm.Wpf.CustomControl/MultiFormatDataView/MultiFormatDataView.xaml
@@ -56,7 +56,7 @@
-