diff --git a/DbcParserLib.Tests/PropertiesLineParserTests.cs b/DbcParserLib.Tests/PropertiesLineParserTests.cs index a33e113..546b5bf 100644 --- a/DbcParserLib.Tests/PropertiesLineParserTests.cs +++ b/DbcParserLib.Tests/PropertiesLineParserTests.cs @@ -157,7 +157,7 @@ public void EnumDefinitionCustomPropertyMoreWhiteSpaceIsParsedTest() } [Test] - public void MsgCycleTimePropertyIsParsedTest() + public void MsgCustomPropertyIsParsedTest() { var builder = new DbcBuilder(new SilentFailureObserver()); var message = new Message { ID = 2394947585 }; @@ -170,13 +170,11 @@ public void MsgCycleTimePropertyIsParsedTest() Assert.IsTrue(ParseLine(@"BA_ ""GenMsgCycleTime"" BO_ 2394947585 100;", msgCycleTimeLineParser, builder, nextLineProvider)); var dbc = builder.Build(); - Assert.AreEqual(true, dbc.Messages.First().CycleTime(out var cycleTime)); Assert.AreEqual(100, dbc.Messages.First().CycleTime); - Assert.AreEqual(100, cycleTime); } [Test] - public void SigInitialValueIntegerPropertyIsParsedTest() + public void SigCustomPropertyIsParsedTest() { var builder = new DbcBuilder(new SilentFailureObserver()); var message = new Message { ID = 2394947585 }; @@ -191,30 +189,7 @@ public void SigInitialValueIntegerPropertyIsParsedTest() Assert.IsTrue(ParseLine(@"BA_ ""GenSigStartValue"" SG_ 2394947585 sig_name 40;", sigInitialValueLineParser, builder, nextLineProvider)); var dbc = builder.Build(); - Assert.AreEqual(true, dbc.Messages.First().Signals.First().InitialValue(out var initialValue)); Assert.AreEqual(40, dbc.Messages.First().Signals.First().InitialValue); - Assert.AreEqual(40, initialValue); - } - - [Test] - public void SigInitialValueHexPropertyIsParsedTest() - { - var builder = new DbcBuilder(new SilentFailureObserver()); - var message = new Message { ID = 2394947585 }; - builder.AddMessage(message); - var signal = new Signal { Name = "sig_name" }; - builder.AddSignal(signal); - - var sigInitialValueLineParser = CreateParser(); - var nextLineProvider = new NextLineProvider(new StringReader(string.Empty)); - Assert.IsTrue(ParseLine(@"BA_DEF_ SG_ ""GenSigStartValue"" HEX 0 200;", sigInitialValueLineParser, builder, nextLineProvider)); - Assert.IsTrue(ParseLine(@"BA_DEF_DEF_ ""GenSigStartValue"" 150;", sigInitialValueLineParser, builder, nextLineProvider)); - Assert.IsTrue(ParseLine(@"BA_ ""GenSigStartValue"" SG_ 2394947585 sig_name 40;", sigInitialValueLineParser, builder, nextLineProvider)); - - var dbc = builder.Build(); - Assert.AreEqual(true, dbc.Messages.First().Signals.First().InitialValue(out var initialValue)); - Assert.AreEqual(40, dbc.Messages.First().Signals.First().InitialValue); - Assert.AreEqual(40, initialValue); } [Test] diff --git a/DbcParserLib/DbcBuilder.cs b/DbcParserLib/DbcBuilder.cs index 207cb80..2b344b0 100644 --- a/DbcParserLib/DbcBuilder.cs +++ b/DbcParserLib/DbcBuilder.cs @@ -103,9 +103,7 @@ public void AddNodeCustomProperty(string propertyName, string nodeName, string v if (node != null) { var property = new CustomProperty(customProperty); - if(!property.SetCustomPropertyValue(value, isNumeric)) - return; - + property.SetCustomPropertyValue(value, isNumeric); if(node.CustomProperties.TryGetValue(propertyName, out _)) m_observer.DuplicatedPropertyInNode(propertyName, node.Name); else @@ -125,9 +123,7 @@ public void AddEnvironmentVariableCustomProperty(string propertyName, string var if (m_environmentVariables.TryGetValue(variableName, out var envVariable)) { var property = new CustomProperty(customProperty); - if(!property.SetCustomPropertyValue(value, isNumeric)) - return; - + property.SetCustomPropertyValue(value, isNumeric); if(envVariable.CustomProperties.TryGetValue(propertyName, out _)) m_observer.DuplicatedPropertyInEnvironmentVariable(propertyName, envVariable.Name); else @@ -147,9 +143,7 @@ public void AddMessageCustomProperty(string propertyName, uint messageId, string if (m_messages.TryGetValue(messageId, out var message)) { var property = new CustomProperty(customProperty); - if(!property.SetCustomPropertyValue(value, isNumeric)) - return; - + property.SetCustomPropertyValue(value, isNumeric); if(message.CustomProperties.TryGetValue(propertyName, out _)) m_observer.DuplicatedPropertyInMessage(propertyName, message.ID); else @@ -169,9 +163,7 @@ public void AddSignalCustomProperty(string propertyName, uint messageId, string if (TryGetValueMessageSignal(messageId, signalName, out var signal)) { var property = new CustomProperty(customProperty); - if(!property.SetCustomPropertyValue(value, isNumeric)) - return; - + property.SetCustomPropertyValue(value, isNumeric); if(signal.CustomProperties.TryGetValue(propertyName, out _)) m_observer.DuplicatedPropertyInSignal(propertyName, signal.Name); else @@ -192,6 +184,14 @@ public void AddSignalComment(uint messageId, string signalName, string comment) m_observer.SignalNameNotFound(messageId, signalName); } + public void AddSignalInitialValue(uint messageId, string signalName, double initialValue) + { + if (TryGetValueMessageSignal(messageId, signalName, out var signal)) + signal.InitialValue = initialValue * signal.Factor + signal.Offset; + else + m_observer.SignalNameNotFound(messageId, signalName); + } + public void AddSignalValueType(uint messageId, string signalName, DbcValueType valueType) { if (TryGetValueMessageSignal(messageId, signalName, out var signal)) @@ -263,6 +263,16 @@ public void AddNodeEnvironmentVariable(string nodeName, string variableName) m_observer.NodeNameNotFound(nodeName); } + public void AddMessageCycleTime(uint messageId, int cycleTime) + { + if (m_messages.TryGetValue(messageId, out var message)) + { + message.CycleTime = cycleTime; + } + else + m_observer.MessageIdNotFound(messageId); + } + public void AddNamedValueTable(string name, IReadOnlyDictionary dictValues, string stringValues) { if(m_namedTablesMap.TryGetValue(name, out _)) diff --git a/DbcParserLib/ExtensionsAndHelpers.cs b/DbcParserLib/ExtensionsAndHelpers.cs index 0047e7e..700e0b1 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; namespace DbcParserLib { @@ -32,6 +33,12 @@ internal static ulong BitMask(this Signal signal) return (ulong.MaxValue >> (64 - signal.Length)); } + [Obsolete("Please use ValueTableMap instead. ToPairs() and ValueTable will be removed in future releases")] + public static IEnumerable> ToPairs(this Signal signal) + { + return signal.ValueTableMap; + } + private const string MultiplexorLabel = "M"; private const string MultiplexedLabel = "m"; @@ -92,47 +99,5 @@ internal static IReadOnlyDictionary ToDictionary(this string record } return dict; } - - public static bool CycleTime(this Message message, out int cycleTime) - { - cycleTime = 0; - - if (message.CustomProperties.TryGetValue("GenMsgCycleTime", out var property)) - { - cycleTime = property.IntegerCustomProperty.Value; - return true; - } - else - return false; - } - - internal static bool InitialValue(this Signal signal, out double initialValue) - { - initialValue = 0; - - if (signal.CustomProperties.TryGetValue("GenSigStartValue", out var property)) - { - double value = 0; - switch (property.CustomPropertyDefinition.DataType) - { - case CustomPropertyDataType.Float: - value = property.FloatCustomProperty.Value; - break; - case CustomPropertyDataType.Hex: - value = property.HexCustomProperty.Value; - break; - case CustomPropertyDataType.Integer: - value = property.IntegerCustomProperty.Value; - break; - default: - return false; - } - - initialValue = value * signal.Factor + signal.Offset; - return true; - } - else - return false; - } } } \ No newline at end of file diff --git a/DbcParserLib/IDbcBuilder.cs b/DbcParserLib/IDbcBuilder.cs index e9bfa48..2c16f5e 100644 --- a/DbcParserLib/IDbcBuilder.cs +++ b/DbcParserLib/IDbcBuilder.cs @@ -7,11 +7,13 @@ internal interface IDbcBuilder { void AddMessage(Message message); void AddMessageComment(uint messageId, string comment); + void AddMessageCycleTime(uint messageId, int cycleTime); void AddNamedValueTable(string name, IReadOnlyDictionary dictValues, string stringValues); void AddNode(Node node); void AddNodeComment(string nodeName, string comment); void AddSignal(Signal signal); void AddSignalComment(uint messageId, string signalName, string comment); + void AddSignalInitialValue(uint messageId, string signalName, double initialValue); 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); diff --git a/DbcParserLib/Model/CustomProperty.cs b/DbcParserLib/Model/CustomProperty.cs index c982a11..22d840c 100644 --- a/DbcParserLib/Model/CustomProperty.cs +++ b/DbcParserLib/Model/CustomProperty.cs @@ -14,13 +14,13 @@ public CustomProperty(CustomPropertyDefinition customPropertyDefinition) CustomPropertyDefinition = customPropertyDefinition; } - public bool SetCustomPropertyValue(string value, bool isNumeric) + public void SetCustomPropertyValue(string value, bool isNumeric) { switch (CustomPropertyDefinition.DataType) { case CustomPropertyDataType.Integer: if(!CustomPropertyDefinition.TryGetIntegerValue(value, isNumeric, out var integerValue)) - return false; + return; IntegerCustomProperty = new CustomPropertyValue() { @@ -30,7 +30,7 @@ public bool SetCustomPropertyValue(string value, bool isNumeric) case CustomPropertyDataType.Hex: if(!CustomPropertyDefinition.TryGetHexValue(value, isNumeric, out var hexValue)) - return false; + return; HexCustomProperty = new CustomPropertyValue() { @@ -40,7 +40,7 @@ public bool SetCustomPropertyValue(string value, bool isNumeric) case CustomPropertyDataType.Float: if(!CustomPropertyDefinition.TryGetFloatValue(value, isNumeric, out var floatValue)) - return false; + return; FloatCustomProperty = new CustomPropertyValue() { Value = floatValue @@ -49,7 +49,7 @@ public bool SetCustomPropertyValue(string value, bool isNumeric) case CustomPropertyDataType.String: if(!CustomPropertyDefinition.IsString(isNumeric)) - return false; + return; StringCustomProperty = new CustomPropertyValue() { Value = value @@ -58,7 +58,7 @@ public bool SetCustomPropertyValue(string value, bool isNumeric) case CustomPropertyDataType.Enum: if(!CustomPropertyDefinition.TryGetEnumValue(value, isNumeric, out var enumValue)) - return false; + return; EnumCustomProperty = new CustomPropertyValue() { @@ -66,7 +66,6 @@ public bool SetCustomPropertyValue(string value, bool isNumeric) }; break; } - return true; } public void SetCustomPropertyValueFromDefault() diff --git a/DbcParserLib/Model/CustomPropertyDefinition.cs b/DbcParserLib/Model/CustomPropertyDefinition.cs index 809f18f..92bc3c4 100644 --- a/DbcParserLib/Model/CustomPropertyDefinition.cs +++ b/DbcParserLib/Model/CustomPropertyDefinition.cs @@ -20,6 +20,7 @@ public CustomPropertyDefinition(IParseFailureObserver observer) m_observer = observer; } + public void SetCustomPropertyDefaultValue(string value, bool isNumeric) { switch (DataType) diff --git a/DbcParserLib/Model/Message.cs b/DbcParserLib/Model/Message.cs index 191260d..8c179c5 100644 --- a/DbcParserLib/Model/Message.cs +++ b/DbcParserLib/Model/Message.cs @@ -1,5 +1,4 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; namespace DbcParserLib.Model { @@ -38,16 +37,7 @@ public class Message public ushort DLC; public string Transmitter; public string Comment; - [Obsolete("Please use CycleTime(out int cycleTime) instead. CycleTime property will be removed and will be accessible only through extension method")] - public int CycleTime - { - get - { - this.CycleTime(out var cycleTime); - return cycleTime; - } - } - + public int CycleTime; public List Signals = new List(); public IDictionary CustomProperties = new Dictionary(); diff --git a/DbcParserLib/Model/Signal.cs b/DbcParserLib/Model/Signal.cs index a7930f4..d406cb5 100644 --- a/DbcParserLib/Model/Signal.cs +++ b/DbcParserLib/Model/Signal.cs @@ -57,7 +57,7 @@ internal ImmutableSignal(Signal signal) public class Signal { - private DbcValueType m_valueType = DbcValueType.Signed; + private DbcValueType m_ValueType = DbcValueType.Signed; public uint ID; public string Name; @@ -68,23 +68,17 @@ public class Signal public byte IsSigned { get; private set; } = 1; public DbcValueType ValueType { - get => m_valueType; - set + get { - m_valueType = value; - IsSigned = (byte)(value == DbcValueType.Unsigned ? 0 : 1); + return m_ValueType; } - } - - public double InitialValue - { - get + set { - this.InitialValue(out var initialValue); - return initialValue; + m_ValueType = value; + IsSigned = (byte)(value == DbcValueType.Unsigned ? 0 : 1); } } - + public double InitialValue; public double Factor = 1; public bool IsInteger = false; public double Offset; diff --git a/DbcParserLib/Parsers/PropertiesLineParser.cs b/DbcParserLib/Parsers/PropertiesLineParser.cs index 4a09bcb..b0b3b77 100644 --- a/DbcParserLib/Parsers/PropertiesLineParser.cs +++ b/DbcParserLib/Parsers/PropertiesLineParser.cs @@ -34,9 +34,17 @@ public bool TryParse(string line, IDbcBuilder builder, INextLineProvider nextLin else if (match.Groups[2].Value == "EV_") builder.AddEnvironmentVariableCustomProperty(match.Groups[1].Value, match.Groups[3].Value, stringValue, isNumeric); else if (match.Groups[4].Value == "BO_") + { builder.AddMessageCustomProperty(match.Groups[1].Value, uint.Parse(match.Groups[5].Value, CultureInfo.InvariantCulture), stringValue, isNumeric); + if (match.Groups[1].Value == "GenMsgCycleTime") + builder.AddMessageCycleTime(uint.Parse(match.Groups[5].Value, CultureInfo.InvariantCulture), int.Parse(match.Groups[9].Value, CultureInfo.InvariantCulture)); + } else if (match.Groups[6].Value == "SG_") + { builder.AddSignalCustomProperty(match.Groups[1].Value, uint.Parse(match.Groups[7].Value, CultureInfo.InvariantCulture), match.Groups[8].Value, stringValue, isNumeric); + if (match.Groups[1].Value == "GenSigStartValue") + builder.AddSignalInitialValue(uint.Parse(match.Groups[7].Value, CultureInfo.InvariantCulture), match.Groups[8].Value, double.Parse(match.Groups[9].Value, CultureInfo.InvariantCulture)); + } } else m_observer.PropertySyntaxError(); diff --git a/README.md b/README.md index 36f6b49..05071d1 100644 --- a/README.md +++ b/README.md @@ -40,30 +40,6 @@ var filteredSelection = dbc .ToArray(); ``` -### Parsing errors management -From **v1.4.0** parsing errors management has been introduced to inform users about syntax errors occurred during parsing procedure. -The `IParseFailureObserver` interface provides all methods to handle syntax errors, like: -- Generic syntax error (eg. `;`, `'`, `,` missing) -- Duplicated object definition (eg. messages with same ID; nodes, signals, custom properties with same name etc..) -- Object definition missing (eg. custom property is assigned before its declaration) -- Value consistency (eg. custom property value is out of bound with respect to min and max values defined in the property) - -The library comes with two different implementations: -1. `SilentFailureObserver`: the default one. It silently swallow errors when parsing -2. `SimpleFailureObserver`: simple observer that logs any error. Errors list can be retrieve through `GetErrorList()` method, like in the example below - -```cs -// Comment this two lines to remove errors parsing management (errors will be silent) -// You can provide your own IParseFailureObserver implementation to customize errors parsing management -var failureObserver = new SimpleFailureObserver(); -Parser.SetParsingFailuresObserver(failureObserver); - -var dbc = Parser.ParseFromPath(filePath); -var errors = failureObserver.GetErrorList(); -``` - -The user is free to create its own implementation to customize error management. - ## Packing/Unpacking signals ### Simple scenario @@ -127,22 +103,6 @@ if(message.IsMultiplexed()) // ... } ``` - -
- -# Obsolete stuff - -Below you can find a list of obsolete stuff that are going to be removed in the future releases. - -| 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 | 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) | - -
- # Useful references - [High level overview](https://docs.openvehicles.com/en/latest/components/vehicle_dbc/docs/dbc-primer.html) - [Very well done overview, many resources on that site](https://github.com/stefanhoelzl/CANpy/blob/master/docs/DBC_Specification.md)