From c883ba3ab620cc1811a5addfef70d5d065163671 Mon Sep 17 00:00:00 2001 From: Federico Panzani Date: Thu, 2 Nov 2023 16:29:29 +0000 Subject: [PATCH 1/5] Removed ValueTable and IsSigned obsolete properties --- DbcParserLib.Tests/DbcBuilderTests.cs | 49 +++++++++-------- DbcParserLib.Tests/ParserTests.cs | 54 ++++++++----------- DbcParserLib.Tests/SignalLineParserTests.cs | 8 +-- .../ValueTableLineParserTests.cs | 16 +++--- DbcParserLib/DbcBuilder.cs | 10 ++-- DbcParserLib/IDbcBuilder.cs | 4 +- DbcParserLib/Model/Signal.cs | 53 ++++-------------- .../Parsers/ValueTableDefinitionLineParser.cs | 2 +- DbcParserLib/Parsers/ValueTableLineParser.cs | 2 +- Demo/Form1.cs | 2 +- README.md | 4 +- 11 files changed, 77 insertions(+), 127 deletions(-) diff --git a/DbcParserLib.Tests/DbcBuilderTests.cs b/DbcParserLib.Tests/DbcBuilderTests.cs index 887922e..892e850 100644 --- a/DbcParserLib.Tests/DbcBuilderTests.cs +++ b/DbcParserLib.Tests/DbcBuilderTests.cs @@ -266,7 +266,7 @@ public void TableValuesAreAddedToSignal() builder.AddSignal(signal); var testValuesDict = new Dictionary() { { 1, "fake" } }; - builder.LinkTableValuesToSignal(234, "name1", testValuesDict, "1 fake"); + builder.LinkTableValuesToSignal(234, "name1", testValuesDict); var dbc = builder.Build(); Assert.IsEmpty(dbc.Nodes); @@ -274,7 +274,8 @@ public void TableValuesAreAddedToSignal() Assert.AreEqual(234, dbc.Messages.First().ID); Assert.AreEqual("name1", dbc.Messages.First().Signals.First().Name); Assert.AreEqual(testValuesDict, dbc.Messages.First().Signals.First().ValueTableMap); - Assert.AreEqual("1 fake", dbc.Messages.First().Signals.First().ValueTable); + Assert.AreEqual(1, dbc.Messages.First().Signals.First().ValueTableMap.Keys.First()); + Assert.AreEqual("fake", dbc.Messages.First().Signals.First().ValueTableMap.Values.First()); } [Test] @@ -287,7 +288,7 @@ public void TableValuesWithExtendedMessageIdAreAddedToSignal() builder.AddSignal(signal); var testValuesDict = new Dictionary() { { 1, "fake" } }; - builder.LinkTableValuesToSignal(2566896411, "name1", testValuesDict, "1 fake"); + builder.LinkTableValuesToSignal(2566896411, "name1", testValuesDict); var dbc = builder.Build(); Assert.IsEmpty(dbc.Nodes); @@ -295,7 +296,8 @@ public void TableValuesWithExtendedMessageIdAreAddedToSignal() Assert.AreEqual(message.ID, dbc.Messages.First().ID); Assert.AreEqual("name1", dbc.Messages.First().Signals.First().Name); Assert.AreEqual(testValuesDict, dbc.Messages.First().Signals.First().ValueTableMap); - Assert.AreEqual("1 fake", dbc.Messages.First().Signals.First().ValueTable); + Assert.AreEqual(1, dbc.Messages.First().Signals.First().ValueTableMap.Keys.First()); + Assert.AreEqual("fake", dbc.Messages.First().Signals.First().ValueTableMap.Values.First()); } [Test] @@ -308,15 +310,14 @@ public void TableValueIsNotAddedToMissingSignalMessageId() builder.AddSignal(signal); var testValuesDict = new Dictionary() { { 1, "fake" } }; - builder.LinkTableValuesToSignal(235, "name1", testValuesDict, "1 fake"); + builder.LinkTableValuesToSignal(235, "name1", testValuesDict); var dbc = builder.Build(); Assert.IsEmpty(dbc.Nodes); Assert.AreEqual(1, dbc.Messages.Count()); Assert.AreEqual(234, dbc.Messages.First().ID); Assert.AreEqual("name1", dbc.Messages.First().Signals.First().Name); - Assert.IsNull(dbc.Messages.First().Signals.First().ValueTableMap); - Assert.IsNull(dbc.Messages.First().Signals.First().ValueTable); + Assert.IsEmpty(dbc.Messages.First().Signals.First().ValueTableMap); } [Test] @@ -329,15 +330,14 @@ public void TableValueIsNotAddedToMissingSignalName() builder.AddSignal(signal); var testValuesDict = new Dictionary() { { 1, "fake" } }; - builder.LinkTableValuesToSignal(234, "name2", testValuesDict, "1 fake"); + builder.LinkTableValuesToSignal(234, "name2", testValuesDict); var dbc = builder.Build(); Assert.IsEmpty(dbc.Nodes); Assert.AreEqual(1, dbc.Messages.Count()); Assert.AreEqual(234, dbc.Messages.First().ID); Assert.AreEqual("name1", dbc.Messages.First().Signals.First().Name); - Assert.IsNull(dbc.Messages.First().Signals.First().ValueTableMap); - Assert.IsNull(dbc.Messages.First().Signals.First().ValueTable); + Assert.IsEmpty(dbc.Messages.First().Signals.First().ValueTableMap); } [Test] @@ -350,7 +350,7 @@ public void NamedTableValuesAreAddedToSignal() builder.AddSignal(signal); var testValuesDict = new Dictionary() { { 1, "fake" } }; - builder.AddNamedValueTable("aTableName", testValuesDict, "1 fake"); + builder.AddNamedValueTable("aTableName", testValuesDict); builder.LinkNamedTableToSignal(234, "name1", "aTableName"); var dbc = builder.Build(); @@ -360,7 +360,8 @@ public void NamedTableValuesAreAddedToSignal() Assert.AreEqual(234, dbc.Messages.First().ID); Assert.AreEqual("name1", dbc.Messages.First().Signals.First().Name); Assert.AreEqual(testValuesDict, dbc.Messages.First().Signals.First().ValueTableMap); - Assert.AreEqual("1 fake", dbc.Messages.First().Signals.First().ValueTable); + Assert.AreEqual(1, dbc.Messages.First().Signals.First().ValueTableMap.Keys.First()); + Assert.AreEqual("fake", dbc.Messages.First().Signals.First().ValueTableMap.Values.First()); } [Test] @@ -373,7 +374,7 @@ public void NamedTableValueIsNotAddedToMissingSignalMessageId() builder.AddSignal(signal); var testValuesDict = new Dictionary() { { 1, "fake" } }; - builder.AddNamedValueTable("aTableName", testValuesDict, "1 fake"); + builder.AddNamedValueTable("aTableName", testValuesDict); builder.LinkNamedTableToSignal(235, "name1", "aTableName"); var dbc = builder.Build(); @@ -382,8 +383,7 @@ public void NamedTableValueIsNotAddedToMissingSignalMessageId() Assert.AreEqual(1, dbc.Messages.Count()); Assert.AreEqual(234, dbc.Messages.First().ID); Assert.AreEqual("name1", dbc.Messages.First().Signals.First().Name); - Assert.IsNull(dbc.Messages.First().Signals.First().ValueTableMap); - Assert.IsNull(dbc.Messages.First().Signals.First().ValueTable); + Assert.IsEmpty(dbc.Messages.First().Signals.First().ValueTableMap); } [Test] @@ -396,7 +396,7 @@ public void NamedTableValueIsNotAddedToMissingSignalName() builder.AddSignal(signal); var testValuesDict = new Dictionary() { { 1, "fake" } }; - builder.AddNamedValueTable("aTableName", testValuesDict, "1 fake"); + builder.AddNamedValueTable("aTableName", testValuesDict); builder.LinkNamedTableToSignal(234, "name2", "aTableName"); var dbc = builder.Build(); @@ -405,8 +405,7 @@ public void NamedTableValueIsNotAddedToMissingSignalName() Assert.AreEqual(1, dbc.Messages.Count()); Assert.AreEqual(234, dbc.Messages.First().ID); Assert.AreEqual("name1", dbc.Messages.First().Signals.First().Name); - Assert.IsNull(dbc.Messages.First().Signals.First().ValueTableMap); - Assert.IsNull(dbc.Messages.First().Signals.First().ValueTable); + Assert.IsEmpty(dbc.Messages.First().Signals.First().ValueTableMap); } [Test] @@ -425,7 +424,7 @@ public void NamedTableValueIsNotAddedIfTableNameDoesNotExist() Assert.AreEqual(1, dbc.Messages.Count()); Assert.AreEqual(234, dbc.Messages.First().ID); Assert.AreEqual("name1", dbc.Messages.First().Signals.First().Name); - Assert.IsNull(dbc.Messages.First().Signals.First().ValueTable); + Assert.IsEmpty(dbc.Messages.First().Signals.First().ValueTableMap); } [Test] @@ -434,9 +433,9 @@ public void NamedTableValueThatAreNotUsedDoNotHarmOnBuild() var testValuesDict = new Dictionary() { { 1, "fake" } }; var builder = new DbcBuilder(new SilentFailureObserver()); - builder.AddNamedValueTable("aTableName", testValuesDict, "1 fake"); - builder.AddNamedValueTable("aTableName2", testValuesDict, "1 fake"); - builder.AddNamedValueTable("aTableName3", testValuesDict, "1 fake"); + builder.AddNamedValueTable("aTableName", testValuesDict); + builder.AddNamedValueTable("aTableName2", testValuesDict); + builder.AddNamedValueTable("aTableName3", testValuesDict); var dbc = builder.Build(); Assert.IsEmpty(dbc.Nodes); @@ -449,9 +448,9 @@ public void NamedTablesWithSameNameAreManaged() var testValuesDict = new Dictionary() { { 1, "fake" } }; var builder = new DbcBuilder(new SilentFailureObserver()); - builder.AddNamedValueTable("aTableName", testValuesDict, "1 fake"); - builder.AddNamedValueTable("aTableName", testValuesDict, "1 fake"); - builder.AddNamedValueTable("aTableName", testValuesDict, "1 fake"); + builder.AddNamedValueTable("aTableName", testValuesDict); + builder.AddNamedValueTable("aTableName", testValuesDict); + builder.AddNamedValueTable("aTableName", testValuesDict); var dbc = builder.Build(); Assert.IsEmpty(dbc.Nodes); diff --git a/DbcParserLib.Tests/ParserTests.cs b/DbcParserLib.Tests/ParserTests.cs index 681536d..2d79f18 100644 --- a/DbcParserLib.Tests/ParserTests.cs +++ b/DbcParserLib.Tests/ParserTests.cs @@ -1,7 +1,7 @@ using System; +using System.Collections.Generic; using NUnit.Framework; using System.Linq; -using System.IO; using DbcParserLib.Model; namespace DbcParserLib.Tests @@ -71,7 +71,7 @@ public void CheckSignalPropertiesTest() var signal = targetMessage.Signals.FirstOrDefault(x => x.Name.Equals("UI_camBlockBlurThreshold")); Assert.IsNotNull(signal); - Assert.AreEqual(0, signal.IsSigned); + Assert.AreEqual(DbcValueType.Unsigned, signal.ValueType); Assert.AreEqual(11, signal.StartBit); Assert.AreEqual(6, signal.Length); Assert.AreEqual(0.01587, signal.Factor); @@ -93,7 +93,7 @@ public void CheckOtherSignalPropertiesTest() var signal = targetMessage.Signals.FirstOrDefault(x => x.Name.Equals("DI_torqueMotor")); Assert.IsNotNull(signal); - Assert.AreEqual(1, signal.IsSigned); + Assert.AreEqual(DbcValueType.Signed, signal.ValueType); Assert.AreEqual("Nm", signal.Unit); Assert.AreEqual(13, signal.Length); Assert.AreEqual(0.25, signal.Factor); @@ -103,34 +103,6 @@ public void CheckOtherSignalPropertiesTest() Assert.AreEqual(1, signal.Receiver.Length); } - [Test] - public void CheckTableValuesSignalPropertiesTest() - { - var dbc = Parser.ParseFromPath(MainDbcFilePath); - - var targetMessage = dbc.Messages.FirstOrDefault(x => x.ID == 264); - Assert.IsNotNull(targetMessage); - - Assert.AreEqual(7, targetMessage.Signals.Count); - - var signal = targetMessage.Signals.FirstOrDefault(x => x.Name.Equals("DI_soptState")); - Assert.IsNotNull(signal); - Assert.IsFalse(string.IsNullOrWhiteSpace(signal.ValueTable)); - Assert.AreEqual(132, signal.ValueTable.Length); - - var lineCount = 0; - using (var reader = new StringReader(signal.ValueTable)) - { - while (reader.Peek() > -1) - { - reader.ReadLine(); - ++lineCount; - } - } - - Assert.AreEqual(6, lineCount); - } - [Test] public void SignalCommentIsProperlyAppliedWhenMultipleSignalsShareSameNameTest() { @@ -253,6 +225,14 @@ public void NamedValTableIsAppliedTest() VAL_ 1043 withNamedTable DI_aebLockState ; "; + var expectedValueTableMap = new Dictionary() + { + { 3, "\"AEB_LOCK_STATE_SNA\"" }, + { 2, "\"AEB_LOCK_STATE_UNUSED\"" }, + { 1, "\"AEB_LOCK_STATE_UNLOCKED\"" }, + { 0, "\"AEB_LOCK_STATE_LOCKED\""} + }; + var dbc = Parser.Parse(dbcString); Assert.AreEqual(1, dbc.Messages.Count()); @@ -260,7 +240,7 @@ public void NamedValTableIsAppliedTest() var signal = dbc.Messages.Single().Signals.Single(); Assert.IsNotNull(signal); - Assert.AreEqual(107, signal.ValueTable.Length); + Assert.AreEqual(expectedValueTableMap, signal.ValueTableMap); } [Test] @@ -273,6 +253,14 @@ public void ExplicitValTableIsAppliedTest() VAL_ 1043 withNamedTable 3 ""AEB_LOCK_STATE_SNA"" 2 ""AEB_LOCK_STATE_UNUSED"" 1 ""AEB_LOCK_STATE_UNLOCKED"" 0 ""AEB_LOCK_STATE_LOCKED"" ;"; + var expectedValueTableMap = new Dictionary() + { + { 3, "\"AEB_LOCK_STATE_SNA\"" }, + { 2, "\"AEB_LOCK_STATE_UNUSED\"" }, + { 1, "\"AEB_LOCK_STATE_UNLOCKED\"" }, + { 0, "\"AEB_LOCK_STATE_LOCKED\""} + }; + var dbc = Parser.Parse(dbcString); Assert.AreEqual(1, dbc.Messages.Count()); @@ -280,7 +268,7 @@ public void ExplicitValTableIsAppliedTest() var signal = dbc.Messages.Single().Signals.Single(); Assert.IsNotNull(signal); - Assert.AreEqual(107, signal.ValueTable.Length); + Assert.AreEqual(expectedValueTableMap, signal.ValueTableMap); } [Test] diff --git a/DbcParserLib.Tests/SignalLineParserTests.cs b/DbcParserLib.Tests/SignalLineParserTests.cs index bce25fc..ea8e6d3 100644 --- a/DbcParserLib.Tests/SignalLineParserTests.cs +++ b/DbcParserLib.Tests/SignalLineParserTests.cs @@ -70,7 +70,7 @@ public void FullLineIsParsed() Assert.AreEqual(28, signal.StartBit); Assert.AreEqual(29, signal.Length); Assert.AreEqual(1, signal.ByteOrder); - Assert.AreEqual(1, signal.IsSigned); + Assert.AreEqual(DbcValueType.Signed, signal.ValueType); Assert.AreEqual(1E-006, signal.Factor); Assert.AreEqual(0, signal.Offset); Assert.AreEqual(-10, signal.Minimum); @@ -98,7 +98,7 @@ public void FullLineMultiplexedIsParsed() Assert.AreEqual(28, signal.StartBit); Assert.AreEqual(29, signal.Length); Assert.AreEqual(1, signal.ByteOrder); - Assert.AreEqual(1, signal.IsSigned); + Assert.AreEqual(DbcValueType.Signed, signal.ValueType); Assert.AreEqual(1E-006, signal.Factor); Assert.AreEqual(0, signal.Offset); Assert.AreEqual(-10, signal.Minimum); @@ -126,7 +126,7 @@ public void FullLineMultipleReceiversIsParsed() Assert.AreEqual(28, signal.StartBit); Assert.AreEqual(29, signal.Length); Assert.AreEqual(1, signal.ByteOrder); - Assert.AreEqual(1, signal.IsSigned); + Assert.AreEqual(DbcValueType.Signed, signal.ValueType); Assert.AreEqual(1E-006, signal.Factor); Assert.AreEqual(0, signal.Offset); Assert.AreEqual(-10, signal.Minimum); @@ -155,7 +155,7 @@ public void FullLineMultipleReceiversWithSpacesIsParsed() Assert.AreEqual(28, signal.StartBit); Assert.AreEqual(29, signal.Length); Assert.AreEqual(1, signal.ByteOrder); - Assert.AreEqual(1, signal.IsSigned); + Assert.AreEqual(DbcValueType.Signed, signal.ValueType); Assert.AreEqual(1E-006, signal.Factor); Assert.AreEqual(0, signal.Offset); Assert.AreEqual(-10, signal.Minimum); diff --git a/DbcParserLib.Tests/ValueTableLineParserTests.cs b/DbcParserLib.Tests/ValueTableLineParserTests.cs index bf38e64..fd21abc 100644 --- a/DbcParserLib.Tests/ValueTableLineParserTests.cs +++ b/DbcParserLib.Tests/ValueTableLineParserTests.cs @@ -136,8 +136,7 @@ public void ValueTableDefinitionIsParsedAndCallsBuilder() { var dbcBuilderMock = m_repository.Create(); dbcBuilderMock.Setup(builder => builder.AddNamedValueTable("DI_aebLockState", - new Dictionary() { { 3, @"""AEB_LOCK_STATE_SNA""" }, { 2, @"""AEB_LOCK_STATE_UNUSED""" }, { 1, @"""AEB_LOCK_STATE_UNLOCKED""" }, { 0, @"""AEB_LOCK_STATE_LOCKED""" } }, - Helpers.ConvertToMultiLine(@"3 ""AEB_LOCK_STATE_SNA"" 2 ""AEB_LOCK_STATE_UNUSED"" 1 ""AEB_LOCK_STATE_UNLOCKED"" 0 ""AEB_LOCK_STATE_LOCKED""".SplitBySpace(), 0))); + new Dictionary() { { 3, @"""AEB_LOCK_STATE_SNA""" }, { 2, @"""AEB_LOCK_STATE_UNUSED""" }, { 1, @"""AEB_LOCK_STATE_UNLOCKED""" }, { 0, @"""AEB_LOCK_STATE_LOCKED""" } })); var valueTableLineParsers = CreateParser(); var nextLineProviderMock = m_repository.Create(); @@ -173,8 +172,7 @@ public void ValueTableWithMapDefinitionIsParsedAndLinkedToChannel() { 2, @"""AEB_LOCK_STATE_UNUSED""" }, { 1, @"""AEB_LOCK_STATE_UNLOCKED""" }, { 0, @"""AEB_LOCK_STATE_LOCKED""" } - }, - multiline + } )); var valueTableLineParsers = CreateParser(); var nextLineProviderMock = m_repository.Create(); @@ -194,9 +192,8 @@ public void ValueTableDefinitionWithSpacesInValuesIsParsed(string line) dbcBuilderMock.Setup( builder => builder.AddNamedValueTable( "TableName", - It.IsAny>(), - It.IsAny() - )).Callback, string>((_, dict, _) => + It.IsAny>())) + .Callback>((_, dict) => { finalDict = new Dictionary(dict); }); @@ -220,9 +217,8 @@ public void ValueTableWithSpacesInValuesIsParsed(string line) builder => builder.LinkTableValuesToSignal( 869, "qGearboxOil", - It.IsAny>(), - It.IsAny() - )).Callback, string>((_, _, dict, _) => + It.IsAny>())) + .Callback>((_, _, dict) => { finalDict = new Dictionary(dict); }); diff --git a/DbcParserLib/DbcBuilder.cs b/DbcParserLib/DbcBuilder.cs index 207cb80..93dd72e 100644 --- a/DbcParserLib/DbcBuilder.cs +++ b/DbcParserLib/DbcBuilder.cs @@ -8,7 +8,6 @@ namespace DbcParserLib internal class ValuesTable { public IReadOnlyDictionary ValueTableMap { get; set; } - public string ValueTable { get; set; } } internal class DbcBuilder : IDbcBuilder @@ -263,7 +262,7 @@ public void AddNodeEnvironmentVariable(string nodeName, string variableName) m_observer.NodeNameNotFound(nodeName); } - public void AddNamedValueTable(string name, IReadOnlyDictionary dictValues, string stringValues) + public void AddNamedValueTable(string name, IReadOnlyDictionary dictValues) { if(m_namedTablesMap.TryGetValue(name, out _)) m_observer.DuplicatedValueTableName(name); @@ -272,16 +271,15 @@ public void AddNamedValueTable(string name, IReadOnlyDictionary dic m_namedTablesMap[name] = new ValuesTable() { ValueTableMap = dictValues, - ValueTable = stringValues }; } } - public void LinkTableValuesToSignal(uint messageId, string signalName, IReadOnlyDictionary dictValues, string stringValues) + public void LinkTableValuesToSignal(uint messageId, string signalName, IReadOnlyDictionary dictValues) { if (TryGetValueMessageSignal(messageId, signalName, out var signal)) { - signal.SetValueTable(dictValues, stringValues); + signal.ValueTableMap = dictValues; } else m_observer.SignalNameNotFound(messageId, signalName); @@ -301,7 +299,7 @@ public void LinkNamedTableToSignal(uint messageId, string signalName, string tab { if (m_namedTablesMap.TryGetValue(tableName, out var valuesTable)) { - LinkTableValuesToSignal(messageId, signalName, valuesTable.ValueTableMap, valuesTable.ValueTable); + LinkTableValuesToSignal(messageId, signalName, valuesTable.ValueTableMap); } else m_observer.TableMapNameNotFound(tableName); diff --git a/DbcParserLib/IDbcBuilder.cs b/DbcParserLib/IDbcBuilder.cs index e9bfa48..66dcd7b 100644 --- a/DbcParserLib/IDbcBuilder.cs +++ b/DbcParserLib/IDbcBuilder.cs @@ -7,14 +7,14 @@ internal interface IDbcBuilder { void AddMessage(Message message); void AddMessageComment(uint messageId, string comment); - void AddNamedValueTable(string name, IReadOnlyDictionary dictValues, string stringValues); + void AddNamedValueTable(string name, IReadOnlyDictionary dictValues); void AddNode(Node node); void AddNodeComment(string nodeName, string comment); void AddSignal(Signal signal); void AddSignalComment(uint messageId, string signalName, string comment); void AddSignalValueType(uint messageId, string signalName, DbcValueType valueType); void LinkNamedTableToSignal(uint messageId, string signalName, string tableName); - void LinkTableValuesToSignal(uint messageId, string signalName, IReadOnlyDictionary dictValues, string stringValues); + void LinkTableValuesToSignal(uint messageId, string signalName, IReadOnlyDictionary dictValues); void LinkTableValuesToEnvironmentVariable(string variableName, IReadOnlyDictionary dictValues); void AddCustomProperty(CustomPropertyObjectType objectType, CustomPropertyDefinition customProperty); void AddCustomPropertyDefaultValue(string propertyName, string value, bool isNumeric); diff --git a/DbcParserLib/Model/Signal.cs b/DbcParserLib/Model/Signal.cs index a7930f4..d84f7e2 100644 --- a/DbcParserLib/Model/Signal.cs +++ b/DbcParserLib/Model/Signal.cs @@ -1,5 +1,4 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; namespace DbcParserLib.Model { @@ -10,10 +9,7 @@ internal class ImmutableSignal public ushort StartBit { get; } public ushort Length { get; } public byte ByteOrder { get; } - [Obsolete("Please use ValueType instead. IsSigned will be removed in future releases")] - public byte IsSigned { get; } public DbcValueType ValueType { get; } - public double InitialValue { get; } public double Factor { get; } public bool IsInteger { get; } @@ -22,8 +18,6 @@ internal class ImmutableSignal public double Maximum { get; } public string Unit { get; } public string[] Receiver { get; } - [Obsolete("Please use ValueTableMap instead. ValueTable will be removed in future releases")] - public string ValueTable { get; } public IReadOnlyDictionary ValueTableMap { get; } public string Comment { get; } public string Multiplexing { get; } @@ -36,7 +30,6 @@ internal ImmutableSignal(Signal signal) StartBit = signal.StartBit; Length = signal.Length; ByteOrder = signal.ByteOrder; - IsSigned = signal.IsSigned; ValueType = signal.ValueType; InitialValue = signal.InitialValue; Factor = signal.Factor; @@ -46,45 +39,21 @@ internal ImmutableSignal(Signal signal) Maximum = signal.Maximum; Unit = signal.Unit; Receiver = signal.Receiver; - ValueTable = signal.ValueTable; ValueTableMap = signal.ValueTableMap; Comment = signal.Comment; Multiplexing = signal.Multiplexing; - //TODO: remove explicit cast (CustomProperty in Signal class should be Dictionary instead IDictionary) - CustomProperties = (IReadOnlyDictionary)signal.CustomProperties; + CustomProperties = signal.CustomProperties; } } public class Signal { - private DbcValueType m_valueType = DbcValueType.Signed; - public uint ID; public string Name; public ushort StartBit; public ushort Length; public byte ByteOrder = 1; - [Obsolete("Please use ValueType instead. IsSigned will be removed in future releases")] - public byte IsSigned { get; private set; } = 1; - public DbcValueType ValueType - { - get => m_valueType; - set - { - m_valueType = value; - IsSigned = (byte)(value == DbcValueType.Unsigned ? 0 : 1); - } - } - - public double InitialValue - { - get - { - this.InitialValue(out var initialValue); - return initialValue; - } - } - + public DbcValueType ValueType = DbcValueType.Signed; public double Factor = 1; public bool IsInteger = false; public double Offset; @@ -92,17 +61,17 @@ public double InitialValue public double Maximum; public string Unit; public string[] Receiver; - [Obsolete("Please use ValueTableMap instead. ValueTable will be removed in future releases")] - public string ValueTable { get; private set; } - public IReadOnlyDictionary ValueTableMap { get; private set; } + public IReadOnlyDictionary ValueTableMap = new Dictionary(); public string Comment; public string Multiplexing; - public readonly IDictionary CustomProperties = new Dictionary(); - - internal void SetValueTable(IReadOnlyDictionary dictValues, string stringValues) + public readonly Dictionary CustomProperties = new Dictionary(); + public double InitialValue { - ValueTableMap = dictValues; - ValueTable = stringValues; + get + { + this.InitialValue(out var initialValue); + return initialValue; + } } internal ImmutableSignal CreateSignal() diff --git a/DbcParserLib/Parsers/ValueTableDefinitionLineParser.cs b/DbcParserLib/Parsers/ValueTableDefinitionLineParser.cs index e043be3..cf8f470 100644 --- a/DbcParserLib/Parsers/ValueTableDefinitionLineParser.cs +++ b/DbcParserLib/Parsers/ValueTableDefinitionLineParser.cs @@ -29,7 +29,7 @@ public bool TryParse(string line, IDbcBuilder builder, INextLineProvider nextLin { var valueTable = Regex.Replace(match.Groups[2].Value.TrimStart(), ValueTableNewLineRegex, ValueTableNewLineRegexReplace); var valueTableDictionary = valueTable.ToDictionary(); - builder.AddNamedValueTable(match.Groups[1].Value, valueTableDictionary, valueTable); + builder.AddNamedValueTable(match.Groups[1].Value, valueTableDictionary); } else m_observer.ValueTableDefinitionSyntaxError(); diff --git a/DbcParserLib/Parsers/ValueTableLineParser.cs b/DbcParserLib/Parsers/ValueTableLineParser.cs index 3859d41..af2d633 100644 --- a/DbcParserLib/Parsers/ValueTableLineParser.cs +++ b/DbcParserLib/Parsers/ValueTableLineParser.cs @@ -40,7 +40,7 @@ public bool TryParse(string line, IDbcBuilder builder, INextLineProvider nextLin if (match.Groups[3].Value != "") builder.LinkTableValuesToEnvironmentVariable(match.Groups[3].Value, valueTableDictionary); else - builder.LinkTableValuesToSignal(uint.Parse(match.Groups[1].Value), match.Groups[2].Value, valueTableDictionary, valueTable); + builder.LinkTableValuesToSignal(uint.Parse(match.Groups[1].Value), match.Groups[2].Value, valueTableDictionary); return true; } diff --git a/Demo/Form1.cs b/Demo/Form1.cs index a7540a7..df4e63b 100644 --- a/Demo/Form1.cs +++ b/Demo/Form1.cs @@ -152,7 +152,7 @@ public void PopulateView(Dbc dbc) { foreach (var sig in msg.Signals) { - dtSignals.Rows.Add("0x" + sig.ID.ToString("X"), sig.Name, sig.StartBit, sig.Length, sig.ByteOrder, sig.IsSigned, sig.InitialValue, sig.Factor, sig.Offset, sig.Minimum, sig.Maximum, sig.Unit, sig.ValueTable, sig.Comment); + dtSignals.Rows.Add("0x" + sig.ID.ToString("X"), sig.Name, sig.StartBit, sig.Length, sig.ByteOrder, sig.ValueType, sig.InitialValue, sig.Factor, sig.Offset, sig.Minimum, sig.Maximum, sig.Unit, sig.ValueTableMap, sig.Comment); int rowIdx = dtSignals.Rows.Count - 1; int colIdx = dtSignals.Columns.IndexOf(msg.Transmitter); diff --git a/README.md b/README.md index 36f6b49..697dbcc 100644 --- a/README.md +++ b/README.md @@ -136,8 +136,8 @@ Below you can find a list of obsolete stuff that are going to be removed in the | Class | Property/Method | Obsolete | Removed | Replaced by | Comment | | -------- | ------- | ------- | ------- | ------- | ------- | -| Signal | IsSigned | v1.3.0 | planned in **1.4.3** | `ValueType` | Byte property replaced by `DbcValueType` property which provides
more informations about signal type | -| Signal | ValueTable | v1.3.0 | planned in **1.4.3** | `ValueTableMap` | String property replaced by a `IDictionary` property | +| Signal | IsSigned | v1.3.0 | **v1.4.3** | `ValueType` | Byte property replaced by `DbcValueType` property which provides
more informations about signal type | +| Signal | ValueTable | v1.3.0 | **v1.4.3** | `ValueTableMap` | String property replaced by a `IDictionary` property | | Signal | ToPairs() | v1.3.0 | **v1.4.2** | - | Extension method used to convert ValueTable into ValueTableMap | | Message | CycleTime | v1.4.2 | planned in **1.4.4** | `bool CycleTime(out int cycleTime)` | CycleTime is no more a message property (replaced by an extension method) | From 5b500d22cce497dcbda9eca5403e09bd4e228cc2 Mon Sep 17 00:00:00 2001 From: Federico Panzani Date: Fri, 3 Nov 2023 09:23:13 +0000 Subject: [PATCH 2/5] Added FSM to parse ValueTable string into dictionary. Added some tests. --- DbcParserLib.Tests/ExtensionMethodsTests.cs | 87 ++++++++++++++- DbcParserLib.Tests/ParserTests.cs | 16 +-- .../ValueTableLineParserTests.cs | 10 +- DbcParserLib/ExtensionsAndHelpers.cs | 103 ++++++++++++++---- .../Parsers/ValueTableDefinitionLineParser.cs | 7 +- DbcParserLib/Parsers/ValueTableLineParser.cs | 16 +-- 6 files changed, 191 insertions(+), 48 deletions(-) diff --git a/DbcParserLib.Tests/ExtensionMethodsTests.cs b/DbcParserLib.Tests/ExtensionMethodsTests.cs index 6eaffed..d5097c8 100644 --- a/DbcParserLib.Tests/ExtensionMethodsTests.cs +++ b/DbcParserLib.Tests/ExtensionMethodsTests.cs @@ -1,4 +1,5 @@ -using NUnit.Framework; +using System.Collections.Generic; +using NUnit.Framework; using DbcParserLib.Model; namespace DbcParserLib.Tests @@ -133,5 +134,89 @@ public void EmptyMessageIsNotMultiplexedTest() var message = new Message(); Assert.IsFalse(message.IsMultiplexed()); } + + [TestCase("1 \"First\" 2 \"Second\" 3 \"Third\"")] + [TestCase("1 \"First with spaces\" 2 \" Second \" 3 \"T h i r d\"")] + [TestCase("1 \"First with spaces\" 2 \" \" 3 \"\"")] + public void FsmNoErrorTest(string text) + { + var operation = text.TryParseToDict(out _); + Assert.IsTrue(operation); + } + + [TestCase("1 \"First 2 \"Second\" 3 \"Third\"")] + [TestCase("1 First 2 \"Second\" 3 \"Third\"")] + [TestCase("1 \"First\" 2 Second\" 3 \"Third\"")] + [TestCase("One \"First with spaces\" 2 \" Second \"")] + [TestCase("1 \"First\" 2 Second\" 3 \"Third\" 4")] + [TestCase("1 \"First\" 2 Second\" 3 \"Third")] + [TestCase("1 \"First\", 2 Second\", 3 \"Third")] + public void FsmWithErrorTest(string text) + { + var operation = text.TryParseToDict(out _); + Assert.IsFalse(operation); + } + + [Test] + public void FsmNoSpacesParsedTest() + { + var text = "1 \"First\" 2 \"Second\" 3 \"Third\""; + var operation = text.TryParseToDict(out var dict); + var expectedDict = new Dictionary() + { + { 1, "First" }, + { 2, "Second" }, + { 3, "Third" } + }; + + Assert.IsTrue(operation); + Assert.AreEqual(expectedDict, dict); + } + + [Test] + public void FsmWithSpacesParsedTest() + { + var text = "1 \"First with spaces\" 2 \" Second \" 3 \" T h i r d \""; + var operation = text.TryParseToDict(out var dict); + var expectedDict = new Dictionary() + { + { 1, "First with spaces" }, + { 2, " Second " }, + { 3, " T h i r d " } + }; + + Assert.IsTrue(operation); + Assert.AreEqual(expectedDict, dict); + } + + [Test] + public void FsmWithEmptyStringParsedTest() + { + var text = "1 \"\" 2 \" \""; + var operation = text.TryParseToDict(out var dict); + var expectedDict = new Dictionary() + { + { 1, "" }, + { 2, " " } + }; + + Assert.IsTrue(operation); + Assert.AreEqual(expectedDict, dict); + } + + [Test] + public void FsmErrorTest() + { + var text = "1 \"First with spaces\" 2 \" Second \" 3 T h i r d \""; + var operation = text.TryParseToDict(out var dict); + var expectedDict = new Dictionary() + { + { 1, "First with spaces" }, + { 2, " Second " } + }; + + Assert.IsFalse(operation); + Assert.AreEqual(expectedDict, dict); + } } } \ No newline at end of file diff --git a/DbcParserLib.Tests/ParserTests.cs b/DbcParserLib.Tests/ParserTests.cs index 2d79f18..60c9ee6 100644 --- a/DbcParserLib.Tests/ParserTests.cs +++ b/DbcParserLib.Tests/ParserTests.cs @@ -227,10 +227,10 @@ public void NamedValTableIsAppliedTest() var expectedValueTableMap = new Dictionary() { - { 3, "\"AEB_LOCK_STATE_SNA\"" }, - { 2, "\"AEB_LOCK_STATE_UNUSED\"" }, - { 1, "\"AEB_LOCK_STATE_UNLOCKED\"" }, - { 0, "\"AEB_LOCK_STATE_LOCKED\""} + { 3, "AEB_LOCK_STATE_SNA" }, + { 2, "AEB_LOCK_STATE_UNUSED" }, + { 1, "AEB_LOCK_STATE_UNLOCKED" }, + { 0, "AEB_LOCK_STATE_LOCKED"} }; var dbc = Parser.Parse(dbcString); @@ -255,10 +255,10 @@ public void ExplicitValTableIsAppliedTest() var expectedValueTableMap = new Dictionary() { - { 3, "\"AEB_LOCK_STATE_SNA\"" }, - { 2, "\"AEB_LOCK_STATE_UNUSED\"" }, - { 1, "\"AEB_LOCK_STATE_UNLOCKED\"" }, - { 0, "\"AEB_LOCK_STATE_LOCKED\""} + { 3, "AEB_LOCK_STATE_SNA" }, + { 2, "AEB_LOCK_STATE_UNUSED" }, + { 1, "AEB_LOCK_STATE_UNLOCKED" }, + { 0, "AEB_LOCK_STATE_LOCKED"} }; var dbc = Parser.Parse(dbcString); diff --git a/DbcParserLib.Tests/ValueTableLineParserTests.cs b/DbcParserLib.Tests/ValueTableLineParserTests.cs index fd21abc..9248619 100644 --- a/DbcParserLib.Tests/ValueTableLineParserTests.cs +++ b/DbcParserLib.Tests/ValueTableLineParserTests.cs @@ -136,7 +136,7 @@ public void ValueTableDefinitionIsParsedAndCallsBuilder() { var dbcBuilderMock = m_repository.Create(); dbcBuilderMock.Setup(builder => builder.AddNamedValueTable("DI_aebLockState", - new Dictionary() { { 3, @"""AEB_LOCK_STATE_SNA""" }, { 2, @"""AEB_LOCK_STATE_UNUSED""" }, { 1, @"""AEB_LOCK_STATE_UNLOCKED""" }, { 0, @"""AEB_LOCK_STATE_LOCKED""" } })); + new Dictionary() { { 3, "AEB_LOCK_STATE_SNA" }, { 2, "AEB_LOCK_STATE_UNUSED" }, { 1, "AEB_LOCK_STATE_UNLOCKED" }, { 0, "AEB_LOCK_STATE_LOCKED" } })); var valueTableLineParsers = CreateParser(); var nextLineProviderMock = m_repository.Create(); @@ -168,10 +168,10 @@ public void ValueTableWithMapDefinitionIsParsedAndLinkedToChannel() "channelName", new Dictionary { - { 3, @"""AEB_LOCK_STATE_SNA""" }, - { 2, @"""AEB_LOCK_STATE_UNUSED""" }, - { 1, @"""AEB_LOCK_STATE_UNLOCKED""" }, - { 0, @"""AEB_LOCK_STATE_LOCKED""" } + { 3, "AEB_LOCK_STATE_SNA" }, + { 2, "AEB_LOCK_STATE_UNUSED" }, + { 1, "AEB_LOCK_STATE_UNLOCKED" }, + { 0, "AEB_LOCK_STATE_LOCKED" } } )); var valueTableLineParsers = CreateParser(); diff --git a/DbcParserLib/ExtensionsAndHelpers.cs b/DbcParserLib/ExtensionsAndHelpers.cs index 8466063..0f7b1bc 100644 --- a/DbcParserLib/ExtensionsAndHelpers.cs +++ b/DbcParserLib/ExtensionsAndHelpers.cs @@ -1,7 +1,6 @@ -using System.IO; +using System; using System.Linq; using System.Collections.Generic; -using System.Text.RegularExpressions; using DbcParserLib.Model; namespace DbcParserLib @@ -70,29 +69,10 @@ internal static void AdjustExtendedId(this Message message) } } - internal static IReadOnlyDictionary ToDictionary(this string records) + internal static bool TryParseToDict(this string records, out IReadOnlyDictionary dict) { - const string valueTableValueRegex = @"(-?\d+)\s+(""[^""]*"")"; - var dict = new Dictionary(); - - if (string.IsNullOrWhiteSpace(records)) - return dict; - - using (var reader = new StringReader(records)) - { - while (reader.Peek() > -1) - { - var line = reader.ReadLine(); - - if (string.IsNullOrWhiteSpace(line)) - continue; - - var match = Regex.Match(line, valueTableValueRegex); - if (match.Success) - dict[int.Parse(match.Groups[1].Value)] = match.Groups[2].Value; - } - } - return dict; + var stateMachine = new StringToDictionaryStateMachine(); + return stateMachine.ParseString(records, out dict); } public static bool CycleTime(this Message message, out int cycleTime) @@ -136,5 +116,80 @@ internal static bool InitialValue(this Signal signal, out double initialValue) else return false; } + + } + + internal class StringToDictionaryStateMachine + { + private readonly Func[,] m_fsm; + private Dictionary m_dictionary = new Dictionary(); + private int m_currentKey; + + public StringToDictionaryStateMachine() + { + m_fsm = new Func[2, 4] { + //Start //FoundQuotes //NotFound //End, + {ParseKey, ParseValue, Error, End }, //FindingIndex + {DoNothing, ParseKey, Error, DoNothing }, //FindingValue + }; + } + + private enum States { FindingIndex, FindingValue }; + private States State { get; set; } + private enum Events { Start, FoundQuotes, NotFound, End}; + + public bool ParseString(string text, out IReadOnlyDictionary dictionary) + { + State = States.FindingIndex; + dictionary = m_dictionary = new Dictionary(); + return ProcessEvent(text, Events.Start); + } + + private bool ParseKey(string text) + { + State = States.FindingIndex; + + var splitIndex = text.IndexOf("\"", StringComparison.InvariantCulture); + if(splitIndex < 0) + return ProcessEvent(text, Events.End); + + var index = text.Substring(0, splitIndex); + text = text.Substring(splitIndex + 1); + return ProcessEvent(text, int.TryParse(index, out m_currentKey) ? Events.FoundQuotes : Events.NotFound); + } + + private bool ParseValue(string text) + { + State = States.FindingValue; + + var splitIndex = text.IndexOf("\"", StringComparison.InvariantCulture); + if (splitIndex == -1) + return ProcessEvent(text, Events.NotFound); + + var value = text.Substring(0, splitIndex); + text = text.Substring(splitIndex + 1); + m_dictionary[m_currentKey] = value; + return ProcessEvent(text, Events.FoundQuotes); + } + + private bool ProcessEvent(string text, Events theEvent) + { + return m_fsm[(int)State, (int)theEvent].Invoke(text); + } + + private static bool Error(string text) + { + return false; + } + + private static bool End(string text) + { + return true; + } + + private static bool DoNothing(string text) + { + return true; + } } } \ No newline at end of file diff --git a/DbcParserLib/Parsers/ValueTableDefinitionLineParser.cs b/DbcParserLib/Parsers/ValueTableDefinitionLineParser.cs index cf8f470..89697bf 100644 --- a/DbcParserLib/Parsers/ValueTableDefinitionLineParser.cs +++ b/DbcParserLib/Parsers/ValueTableDefinitionLineParser.cs @@ -27,9 +27,10 @@ public bool TryParse(string line, IDbcBuilder builder, INextLineProvider nextLin var match = Regex.Match(cleanLine, ValueTableDefinitionParsingRegex); if (match.Success) { - var valueTable = Regex.Replace(match.Groups[2].Value.TrimStart(), ValueTableNewLineRegex, ValueTableNewLineRegexReplace); - var valueTableDictionary = valueTable.ToDictionary(); - builder.AddNamedValueTable(match.Groups[1].Value, valueTableDictionary); + if(match.Groups[2].Value.TryParseToDict(out var valueTableDictionary)) + builder.AddNamedValueTable(match.Groups[1].Value, valueTableDictionary); + else + m_observer.ValueTableDefinitionSyntaxError(); } else m_observer.ValueTableDefinitionSyntaxError(); diff --git a/DbcParserLib/Parsers/ValueTableLineParser.cs b/DbcParserLib/Parsers/ValueTableLineParser.cs index af2d633..30297ef 100644 --- a/DbcParserLib/Parsers/ValueTableLineParser.cs +++ b/DbcParserLib/Parsers/ValueTableLineParser.cs @@ -35,13 +35,15 @@ public bool TryParse(string line, IDbcBuilder builder, INextLineProvider nextLin match = Regex.Match(cleanLine, ValueTableParsingRegex); if (match.Success) { - var valueTable = Regex.Replace(match.Groups[4].Value.TrimStart(), ValueTableNewLineRegex, ValueTableNewLineRegexReplace); - var valueTableDictionary = valueTable.ToDictionary(); - if (match.Groups[3].Value != "") - builder.LinkTableValuesToEnvironmentVariable(match.Groups[3].Value, valueTableDictionary); - else - builder.LinkTableValuesToSignal(uint.Parse(match.Groups[1].Value), match.Groups[2].Value, valueTableDictionary); - return true; + if (match.Groups[4].Value.TryParseToDict(out var valueTableDictionary)) + { + if (match.Groups[3].Value != "") + builder.LinkTableValuesToEnvironmentVariable(match.Groups[3].Value, valueTableDictionary); + else + builder.LinkTableValuesToSignal(uint.Parse(match.Groups[1].Value), match.Groups[2].Value, + valueTableDictionary); + return true; + } } m_observer.ValueTableSyntaxError(); From 742b96f21b5318bbbf7dc3d2cb477d95f8fb34a9 Mon Sep 17 00:00:00 2001 From: Federico Panzani Date: Fri, 3 Nov 2023 09:50:56 +0000 Subject: [PATCH 3/5] Updated Demo application to correctly display ValueTableMap dictionary --- DbcParserLib.Tests/ExtensionMethodsTests.cs | 16 ++++++++++++++++ Demo/Form1.cs | 3 ++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/DbcParserLib.Tests/ExtensionMethodsTests.cs b/DbcParserLib.Tests/ExtensionMethodsTests.cs index d5097c8..2dff666 100644 --- a/DbcParserLib.Tests/ExtensionMethodsTests.cs +++ b/DbcParserLib.Tests/ExtensionMethodsTests.cs @@ -138,6 +138,7 @@ public void EmptyMessageIsNotMultiplexedTest() [TestCase("1 \"First\" 2 \"Second\" 3 \"Third\"")] [TestCase("1 \"First with spaces\" 2 \" Second \" 3 \"T h i r d\"")] [TestCase("1 \"First with spaces\" 2 \" \" 3 \"\"")] + [TestCase("1 \"1\" 2 \" 2 \" 3 \" 3\"")] public void FsmNoErrorTest(string text) { var operation = text.TryParseToDict(out _); @@ -204,6 +205,21 @@ public void FsmWithEmptyStringParsedTest() Assert.AreEqual(expectedDict, dict); } + [Test] + public void FsmWithIntegerStringParsedTest() + { + var text = "1 \"1\" 2 \"2\""; + var operation = text.TryParseToDict(out var dict); + var expectedDict = new Dictionary() + { + { 1, "1" }, + { 2, "2" } + }; + + Assert.IsTrue(operation); + Assert.AreEqual(expectedDict, dict); + } + [Test] public void FsmErrorTest() { diff --git a/Demo/Form1.cs b/Demo/Form1.cs index df4e63b..33d78ed 100644 --- a/Demo/Form1.cs +++ b/Demo/Form1.cs @@ -152,7 +152,8 @@ public void PopulateView(Dbc dbc) { foreach (var sig in msg.Signals) { - dtSignals.Rows.Add("0x" + sig.ID.ToString("X"), sig.Name, sig.StartBit, sig.Length, sig.ByteOrder, sig.ValueType, sig.InitialValue, sig.Factor, sig.Offset, sig.Minimum, sig.Maximum, sig.Unit, sig.ValueTableMap, sig.Comment); + var valueTableString = string.Join("\n", sig.ValueTableMap); + dtSignals.Rows.Add("0x" + sig.ID.ToString("X"), sig.Name, sig.StartBit, sig.Length, sig.ByteOrder, sig.ValueType, sig.InitialValue, sig.Factor, sig.Offset, sig.Minimum, sig.Maximum, sig.Unit, valueTableString, sig.Comment); int rowIdx = dtSignals.Rows.Count - 1; int colIdx = dtSignals.Columns.IndexOf(msg.Transmitter); From b85d15c3579e4770d7b9fac7fa89ee79cf50558f Mon Sep 17 00:00:00 2001 From: Federico Panzani Date: Mon, 6 Nov 2023 11:44:27 +0100 Subject: [PATCH 4/5] Simplified code Simplified FSM code --- DbcParserLib.Tests/ExtensionMethodsTests.cs | 7 +- DbcParserLib/ExtensionsAndHelpers.cs | 88 ++++++++------------- 2 files changed, 32 insertions(+), 63 deletions(-) diff --git a/DbcParserLib.Tests/ExtensionMethodsTests.cs b/DbcParserLib.Tests/ExtensionMethodsTests.cs index 2dff666..e2f4ad4 100644 --- a/DbcParserLib.Tests/ExtensionMethodsTests.cs +++ b/DbcParserLib.Tests/ExtensionMethodsTests.cs @@ -225,14 +225,9 @@ public void FsmErrorTest() { var text = "1 \"First with spaces\" 2 \" Second \" 3 T h i r d \""; var operation = text.TryParseToDict(out var dict); - var expectedDict = new Dictionary() - { - { 1, "First with spaces" }, - { 2, " Second " } - }; Assert.IsFalse(operation); - Assert.AreEqual(expectedDict, dict); + Assert.IsNull(dict); } } } \ No newline at end of file diff --git a/DbcParserLib/ExtensionsAndHelpers.cs b/DbcParserLib/ExtensionsAndHelpers.cs index 0f7b1bc..c8e9031 100644 --- a/DbcParserLib/ExtensionsAndHelpers.cs +++ b/DbcParserLib/ExtensionsAndHelpers.cs @@ -2,6 +2,7 @@ using System.Linq; using System.Collections.Generic; using DbcParserLib.Model; +using System.Text; namespace DbcParserLib { @@ -71,8 +72,7 @@ internal static void AdjustExtendedId(this Message message) internal static bool TryParseToDict(this string records, out IReadOnlyDictionary dict) { - var stateMachine = new StringToDictionaryStateMachine(); - return stateMachine.ParseString(records, out dict); + return StringToDictionaryParser.ParseString(records, out dict); } public static bool CycleTime(this Message message, out int cycleTime) @@ -119,77 +119,51 @@ internal static bool InitialValue(this Signal signal, out double initialValue) } - internal class StringToDictionaryStateMachine + internal class StringToDictionaryParser { - private readonly Func[,] m_fsm; - private Dictionary m_dictionary = new Dictionary(); - private int m_currentKey; + private IDictionary m_dictionary; + private int m_currentIndex; - public StringToDictionaryStateMachine() + private StringToDictionaryParser(IDictionary dict) { - m_fsm = new Func[2, 4] { - //Start //FoundQuotes //NotFound //End, - {ParseKey, ParseValue, Error, End }, //FindingIndex - {DoNothing, ParseKey, Error, DoNothing }, //FindingValue - }; + m_dictionary = dict; } - - private enum States { FindingIndex, FindingValue }; - private States State { get; set; } - private enum Events { Start, FoundQuotes, NotFound, End}; - public bool ParseString(string text, out IReadOnlyDictionary dictionary) + public static bool ParseString(string text, out IReadOnlyDictionary dictionary) { - State = States.FindingIndex; - dictionary = m_dictionary = new Dictionary(); - return ProcessEvent(text, Events.Start); + dictionary = null; + var internalDictionary = new Dictionary(); + var parser = new StringToDictionaryParser(internalDictionary); + if (parser.ParseKey(text)) + { + dictionary = internalDictionary; + return true; + } + return false; } private bool ParseKey(string text) { - State = States.FindingIndex; - - var splitIndex = text.IndexOf("\"", StringComparison.InvariantCulture); - if(splitIndex < 0) - return ProcessEvent(text, Events.End); - - var index = text.Substring(0, splitIndex); - text = text.Substring(splitIndex + 1); - return ProcessEvent(text, int.TryParse(index, out m_currentKey) ? Events.FoundQuotes : Events.NotFound); - } - - private bool ParseValue(string text) - { - State = States.FindingValue; - - var splitIndex = text.IndexOf("\"", StringComparison.InvariantCulture); - if (splitIndex == -1) - return ProcessEvent(text, Events.NotFound); - - var value = text.Substring(0, splitIndex); - text = text.Substring(splitIndex + 1); - m_dictionary[m_currentKey] = value; - return ProcessEvent(text, Events.FoundQuotes); - } + var index = text.IndexOf("\"", m_currentIndex, StringComparison.InvariantCulture); + if(index == -1) + return true; - private bool ProcessEvent(string text, Events theEvent) - { - return m_fsm[(int)State, (int)theEvent].Invoke(text); + var key = text.Substring(m_currentIndex, index - m_currentIndex); + m_currentIndex = index + 1; + return int.TryParse(key, out var intKey) ? ParseValue(text, intKey) : false; } - private static bool Error(string text) + private bool ParseValue(string text, int key) { - return false; - } + var index = text.IndexOf("\"", m_currentIndex, StringComparison.InvariantCulture); + if (index == -1) + return false; - private static bool End(string text) - { - return true; - } + var value = text.Substring(m_currentIndex, index - m_currentIndex); - private static bool DoNothing(string text) - { - return true; + m_dictionary[key] = value; + m_currentIndex = index +1; + return ParseKey(text); } } } \ No newline at end of file From bf0fc1072b922a1ff90ad03bce57c7e046fc853f Mon Sep 17 00:00:00 2001 From: Federico Panzani Date: Mon, 6 Nov 2023 12:58:08 +0100 Subject: [PATCH 5/5] Code cleanup --- DbcParserLib/ExtensionsAndHelpers.cs | 23 +++++++++---------- .../Parsers/ValueTableDefinitionLineParser.cs | 2 -- DbcParserLib/Parsers/ValueTableLineParser.cs | 2 -- 3 files changed, 11 insertions(+), 16 deletions(-) diff --git a/DbcParserLib/ExtensionsAndHelpers.cs b/DbcParserLib/ExtensionsAndHelpers.cs index c8e9031..0b0009b 100644 --- a/DbcParserLib/ExtensionsAndHelpers.cs +++ b/DbcParserLib/ExtensionsAndHelpers.cs @@ -122,7 +122,6 @@ internal static bool InitialValue(this Signal signal, out double initialValue) internal class StringToDictionaryParser { private IDictionary m_dictionary; - private int m_currentIndex; private StringToDictionaryParser(IDictionary dict) { @@ -134,7 +133,7 @@ public static bool ParseString(string text, out IReadOnlyDictionary dictionary = null; var internalDictionary = new Dictionary(); var parser = new StringToDictionaryParser(internalDictionary); - if (parser.ParseKey(text)) + if (parser.ParseKey(text, 0)) { dictionary = internalDictionary; return true; @@ -142,28 +141,28 @@ public static bool ParseString(string text, out IReadOnlyDictionary return false; } - private bool ParseKey(string text) + private bool ParseKey(string text, int offset) { - var index = text.IndexOf("\"", m_currentIndex, StringComparison.InvariantCulture); + var index = text.IndexOf("\"", offset, StringComparison.InvariantCulture); if(index == -1) return true; - var key = text.Substring(m_currentIndex, index - m_currentIndex); - m_currentIndex = index + 1; - return int.TryParse(key, out var intKey) ? ParseValue(text, intKey) : false; + var key = text.Substring(offset, index - offset); + offset = index + 1; + return int.TryParse(key, out var intKey) ? ParseValue(text, offset, intKey) : false; } - private bool ParseValue(string text, int key) + private bool ParseValue(string text, int offset, int key) { - var index = text.IndexOf("\"", m_currentIndex, StringComparison.InvariantCulture); + var index = text.IndexOf("\"", offset, StringComparison.InvariantCulture); if (index == -1) return false; - var value = text.Substring(m_currentIndex, index - m_currentIndex); + var value = text.Substring(offset, index - offset); m_dictionary[key] = value; - m_currentIndex = index +1; - return ParseKey(text); + offset = index +1; + return ParseKey(text, offset); } } } \ No newline at end of file diff --git a/DbcParserLib/Parsers/ValueTableDefinitionLineParser.cs b/DbcParserLib/Parsers/ValueTableDefinitionLineParser.cs index 89697bf..c55a89e 100644 --- a/DbcParserLib/Parsers/ValueTableDefinitionLineParser.cs +++ b/DbcParserLib/Parsers/ValueTableDefinitionLineParser.cs @@ -7,8 +7,6 @@ internal class ValueTableDefinitionLineParser : ILineParser { private const string ValueTableDefinitionLineStarter = "VAL_TABLE_ "; private const string ValueTableDefinitionParsingRegex = @"VAL_TABLE_\s+([a-zA-Z_][\w]*)\s+((?:\d+\s+(?:""[^""]*"")\s+)*)\s*;"; - private const string ValueTableNewLineRegex = @"(""[^""]*""\s+)"; - private const string ValueTableNewLineRegexReplace = "$1\n"; private readonly IParseFailureObserver m_observer; diff --git a/DbcParserLib/Parsers/ValueTableLineParser.cs b/DbcParserLib/Parsers/ValueTableLineParser.cs index 30297ef..967ae0b 100644 --- a/DbcParserLib/Parsers/ValueTableLineParser.cs +++ b/DbcParserLib/Parsers/ValueTableLineParser.cs @@ -8,8 +8,6 @@ internal class ValueTableLineParser : ILineParser private const string ValueTableLineStarter = "VAL_ "; private const string ValueTableLinkParsingRegex = @"VAL_\s+(\d+)\s+([a-zA-Z_][\w]*)\s+([a-zA-Z_][\w]*)\s*;"; private const string ValueTableParsingRegex = @"VAL_\s+(?:(?:(\d+)\s+([a-zA-Z_][\w]*))|([a-zA-Z_][\w]*))\s+((?:(?:-?\d+)\s+(?:""[^""]*"")\s+)*)\s*;"; - private const string ValueTableNewLineRegex = @"(""[^""]*""\s+)"; - private const string ValueTableNewLineRegexReplace = "$1\n"; private readonly IParseFailureObserver m_observer;