Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for keyword BO_TX_BU_ #87

Merged
merged 2 commits into from
Sep 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
231 changes: 231 additions & 0 deletions DbcParserLib.Tests/ExtraMessageTransmitterLineParserTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,231 @@
using DbcParserLib.Observers;
using NUnit.Framework;
using System.Linq;

namespace DbcParserLib.Tests
{
[TestFixture]
public class ExtraMessageTransmitterLineParserTests
{
[Test]
public void ParseOneExtraTransmitters()
{
var dbcString = @"
BO_ 200 TestMessage: 1 TestTransmitter
SG_ Test : 0|8@1+ (0.1,0) [0|0] """" DBG

BO_TX_BU_ 200 : Transmitter2;";

var failureObserver = new SimpleFailureObserver();
Parser.SetParsingFailuresObserver(failureObserver);
var dbc = Parser.Parse(dbcString);
var errorList = failureObserver.GetErrorList();

Assert.Multiple(() =>
{
Assert.That(errorList, Has.Count.EqualTo(0));
Assert.That(dbc.Messages.Count(), Is.EqualTo(1));
Assert.That(dbc.Messages.SelectMany(m => m.Signals).Count(), Is.EqualTo(1));
Assert.That(dbc.Messages.First().AdditionalTransmitters.Count, Is.EqualTo(1));
Assert.That(dbc.Messages.First().AdditionalTransmitters.First(), Is.EqualTo("Transmitter2"));
});
}

[Test]
public void ParseTwoExtraTransmitters()
{
var dbcString = @"
BO_ 200 TestMessage: 1 TestTransmitter
SG_ Test : 0|8@1+ (0.1,0) [0|0] """" DBG

BO_TX_BU_ 200 : Transmitter2,Transmitter3;";


var failureObserver = new SimpleFailureObserver();
Parser.SetParsingFailuresObserver(failureObserver);
var dbc = Parser.Parse(dbcString);
var errorList = failureObserver.GetErrorList();

Assert.Multiple(() =>
{
Assert.That(errorList, Has.Count.EqualTo(0));
Assert.That(dbc.Messages.Count(), Is.EqualTo(1));
Assert.That(dbc.Messages.SelectMany(m => m.Signals).Count(), Is.EqualTo(1));
Assert.That(dbc.Messages.First().AdditionalTransmitters.Count, Is.EqualTo(2));
Assert.That(dbc.Messages.First().AdditionalTransmitters.First(), Is.EqualTo("Transmitter2"));
Assert.That(dbc.Messages.First().AdditionalTransmitters.Last(), Is.EqualTo("Transmitter3"));
});
}

[Test]
public void MissingLineTerminationParsingErrorIsObserved()
{
var dbcString = @"BO_TX_BU_ 200 : Transmitter2";

var failureObserver = new SimpleFailureObserver();
Parser.SetParsingFailuresObserver(failureObserver);
var dbc = Parser.Parse(dbcString);
var errorList = failureObserver.GetErrorList();

Assert.That(errorList, Has.Count.EqualTo(1));
}

[Test]
public void LineTerminationWithLeadingSpace()
{
var dbcString = @"
BO_ 200 TestMessage: 1 TestTransmitter
SG_ Test : 0|8@1+ (0.1,0) [0|0] """" DBG

BO_TX_BU_ 200 : Transmitter2 ;";

var failureObserver = new SimpleFailureObserver();
Parser.SetParsingFailuresObserver(failureObserver);
var dbc = Parser.Parse(dbcString);
var errorList = failureObserver.GetErrorList();

Assert.Multiple(() =>
{
Assert.That(errorList, Has.Count.EqualTo(0));
Assert.That(dbc.Messages.Count(), Is.EqualTo(1));
Assert.That(dbc.Messages.SelectMany(m => m.Signals).Count(), Is.EqualTo(1));
Assert.That(dbc.Messages.First().AdditionalTransmitters.Count, Is.EqualTo(1));
Assert.That(dbc.Messages.First().AdditionalTransmitters.First(), Is.EqualTo("Transmitter2"));
});
}

[Test]
public void LineTerminationWithLeadingSpaceMultiDefinition()
{
var dbcString = @"
BO_ 200 TestMessage: 1 TestTransmitter
SG_ Test : 0|8@1+ (0.1,0) [0|0] """" DBG

BO_TX_BU_ 200 : Transmitter2, Transmitter3 ;";

var failureObserver = new SimpleFailureObserver();
Parser.SetParsingFailuresObserver(failureObserver);
var dbc = Parser.Parse(dbcString);
var errorList = failureObserver.GetErrorList();

Assert.Multiple(() =>
{
Assert.That(errorList, Has.Count.EqualTo(0));
Assert.That(dbc.Messages.Count(), Is.EqualTo(1));
Assert.That(dbc.Messages.SelectMany(m => m.Signals).Count(), Is.EqualTo(1));
Assert.That(dbc.Messages.First().AdditionalTransmitters.Count, Is.EqualTo(2));
Assert.That(dbc.Messages.First().AdditionalTransmitters.First(), Is.EqualTo("Transmitter2"));
Assert.That(dbc.Messages.First().AdditionalTransmitters.Last(), Is.EqualTo("Transmitter3"));
});
}

[Test]
public void ParseTwoExtraTransmittersLessSpaces()
{
var dbcString = @"
BO_ 200 TestMessage: 1 TestTransmitter
SG_ Test : 0|8@1+ (0.1,0) [0|0] """" DBG

BO_TX_BU_ 200:Transmitter2,Transmitter3;";


var failureObserver = new SimpleFailureObserver();
Parser.SetParsingFailuresObserver(failureObserver);
var dbc = Parser.Parse(dbcString);
var errorList = failureObserver.GetErrorList();

Assert.Multiple(() =>
{
Assert.That(errorList, Has.Count.EqualTo(0));
Assert.That(dbc.Messages.Count(), Is.EqualTo(1));
Assert.That(dbc.Messages.SelectMany(m => m.Signals).Count(), Is.EqualTo(1));
Assert.That(dbc.Messages.First().AdditionalTransmitters.Count, Is.EqualTo(2));
Assert.That(dbc.Messages.First().AdditionalTransmitters.First(), Is.EqualTo("Transmitter2"));
Assert.That(dbc.Messages.First().AdditionalTransmitters.Last(), Is.EqualTo("Transmitter3"));
});
}

[Test]
public void ParseTwoExtraTransmittersMoreSpaces()
{
var dbcString = @"
BO_ 200 TestMessage: 1 TestTransmitter
SG_ Test : 0|8@1+ (0.1,0) [0|0] """" DBG

BO_TX_BU_ 200 : Transmitter2 , Transmitter3 ;";


var failureObserver = new SimpleFailureObserver();
Parser.SetParsingFailuresObserver(failureObserver);
var dbc = Parser.Parse(dbcString);
var errorList = failureObserver.GetErrorList();

Assert.Multiple(() =>
{
Assert.That(errorList, Has.Count.EqualTo(0));
Assert.That(dbc.Messages.Count(), Is.EqualTo(1));
Assert.That(dbc.Messages.SelectMany(m => m.Signals).Count(), Is.EqualTo(1));
Assert.That(dbc.Messages.First().AdditionalTransmitters.Count, Is.EqualTo(2));
Assert.That(dbc.Messages.First().AdditionalTransmitters.First(), Is.EqualTo("Transmitter2"));
Assert.That(dbc.Messages.First().AdditionalTransmitters.Last(), Is.EqualTo("Transmitter3"));
});
}

[Test]
public void ParsingErrorIsObserved()
{
var dbcString = @"BO_TX_BU_ 200 ; Transmitter2, Transmitter3;";

var failureObserver = new SimpleFailureObserver();
Parser.SetParsingFailuresObserver(failureObserver);
var dbc = Parser.Parse(dbcString);
var errorList = failureObserver.GetErrorList();

Assert.That(errorList, Has.Count.EqualTo(1));
}

[Test]
public void ParseExtraTransmittersDuplicateErrorIsObserved()
{
var dbcString = @"
BO_ 200 TestMessage: 1 TestTransmitter
SG_ Test : 0|8@1+ (0.1,0) [0|0] """" DBG

BO_TX_BU_ 200 : Transmitter2 , Transmitter2 ;";


var failureObserver = new SimpleFailureObserver();
Parser.SetParsingFailuresObserver(failureObserver);
var dbc = Parser.Parse(dbcString);
var errorList = failureObserver.GetErrorList();

Assert.Multiple(() =>
{
Assert.That(errorList, Has.Count.EqualTo(1));
Assert.That(dbc.Messages.Count(), Is.EqualTo(1));
Assert.That(dbc.Messages.SelectMany(m => m.Signals).Count(), Is.EqualTo(1));
Assert.That(dbc.Messages.First().AdditionalTransmitters.Count, Is.EqualTo(1));
Assert.That(dbc.Messages.First().AdditionalTransmitters.First(), Is.EqualTo("Transmitter2"));
});
}

public void ParseExtraTransmittersMessageNotFoundErrorIsObserved()
{
var dbcString = @"
BO_ 200 TestMessage: 1 TestTransmitter
SG_ Test : 0|8@1+ (0.1,0) [0|0] """" DBG

BO_TX_BU_ 201 : Transmitter2, Transmitter3 ;";

var failureObserver = new SimpleFailureObserver();
Parser.SetParsingFailuresObserver(failureObserver);
var dbc = Parser.Parse(dbcString);
var errorList = failureObserver.GetErrorList();

Assert.Multiple(() =>
{
Assert.That(errorList, Has.Count.EqualTo(1));
});
}
}
}
12 changes: 12 additions & 0 deletions DbcParserLib/DbcBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,18 @@ public void AddMessageCustomProperty(string propertyName, uint messageId, string
m_observer.PropertyNameNotFound(propertyName);
}

public void AddMessageAdditionalTransmitters(uint messageId, string[] additonalTransmitters)
{
if (m_messages.TryGetValue(messageId, out var message))
{
message.AdditionalTransmitters = additonalTransmitters;
}
else
{
m_observer.MessageIdNotFound(messageId);
}
}

public void AddSignalCustomProperty(string propertyName, uint messageId, string signalName, string value, bool isNumeric)
{
if (m_customProperties[CustomPropertyObjectType.Signal].TryGetValue(propertyName, out var customProperty))
Expand Down
1 change: 1 addition & 0 deletions DbcParserLib/IDbcBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ internal interface IDbcBuilder
void AddGlobalCustomProperty(string propertyName, string value, bool isNumeric);
void AddEnvironmentVariableCustomProperty(string propertyName, string variableName, string value, bool isNumeric);
void AddMessageCustomProperty(string propertyName, uint messageId, string value, bool isNumeric);
void AddMessageAdditionalTransmitters(uint messageId, string[] additonalTransmitters);
void AddSignalCustomProperty(string propertyName, uint messageId, string signalName, string value, bool isNumeric);
void AddEnvironmentVariable(string variableName, EnvironmentVariable environmentVariable);
void AddEnvironmentVariableComment(string variableName, string comment);
Expand Down
3 changes: 3 additions & 0 deletions DbcParserLib/Model/Message.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ internal class ImmutableMessage
public string Name { get; }
public ushort DLC { get; }
public string Transmitter { get; }
public IReadOnlyCollection<string> AdditionalTransmitters { get; }
public string Comment { get; }
public int CycleTime { get; }
public IReadOnlyList<ImmutableSignal> Signals { get; }
Expand All @@ -23,6 +24,7 @@ internal ImmutableMessage(Message message, IReadOnlyList<ImmutableSignal> signal
Name = message.Name;
DLC = message.DLC;
Transmitter = message.Transmitter;
AdditionalTransmitters = message.AdditionalTransmitters;
Comment = message.Comment;
CycleTime = cycleTime;
Signals = signals;
Expand All @@ -39,6 +41,7 @@ public class Message
public string Name;
public ushort DLC;
public string Transmitter;
public string[] AdditionalTransmitters;
public string Comment;

public List<Signal> Signals = new List<Signal>();
Expand Down
2 changes: 2 additions & 0 deletions DbcParserLib/Observers/IParseFailureObserver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ public interface IParseFailureObserver
void TableMapNameNotFound(string tableName);
void PropertyValueOutOfBound(string propertyName, string value);
void PropertyValueOutOfIndex(string propertyName, string index);
void ExtraMessageTransmittersSyntaxError();
void ExtraMessageTransmittersDuplicate(uint messageId, string duplicateTransmitter);
void UnknownLine();
void NoMessageFound();
void Clear();
Expand Down
8 changes: 8 additions & 0 deletions DbcParserLib/Observers/SilentFailureObserver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,14 @@ public void PropertyValueOutOfIndex(string propertyName, string index)
{
}

public void ExtraMessageTransmittersSyntaxError()
{
}

public void ExtraMessageTransmittersDuplicate(uint messageId, string duplicateTransmitter)
{
}

public void UnknownLine()
{
}
Expand Down
10 changes: 10 additions & 0 deletions DbcParserLib/Observers/SimpleFailureObserver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,16 @@ public void PropertyValueOutOfIndex(string propertyName, string index)
AddError($"Out of index value [{index}] for '{propertyName}' property");
}

public void ExtraMessageTransmittersSyntaxError()
{
AddError("[BO_TX_BU_] Extra message transmitters syntax error");
}

public void ExtraMessageTransmittersDuplicate(uint messageId, string duplicateTransmitter)
{
AddError($"Duplicate additional transmitter '{duplicateTransmitter}' in message '{messageId}'");
}

public void UnknownLine()
{
AddError("Unknown syntax");
Expand Down
1 change: 1 addition & 0 deletions DbcParserLib/Parser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ private static void CreateLineParsers()
new PropertiesLineParser(m_parseObserver),
new EnvironmentVariableLineParser(m_parseObserver),
new EnvironmentDataVariableLineParser(m_parseObserver),
new ExtraMessageTransmitterLineParser(m_parseObserver),
new UnknownLineParser(m_parseObserver) // Used as a catch all
};
}
Expand Down
57 changes: 57 additions & 0 deletions DbcParserLib/Parsers/ExtraMessageTransmitterLineParser.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
using DbcParserLib.Observers;
using System.Collections.Generic;
using System.Globalization;
using System.Text.RegularExpressions;

namespace DbcParserLib.Parsers
{
internal class ExtraMessageTransmitterLineParser : ILineParser
{
private const string MessageId = "Id";
private const string TransmitterGroup = "Transmitter";
private const string ExtraMessageTransmitterLineStarter = "BO_TX_BU_ ";

private readonly string m_extraTransmitterRegex = $@"BO_TX_BU_ (?<{MessageId}>\d+)\s*:\s*(?<{TransmitterGroup}>(\s*(?:[a-zA-Z_][\w]*)\s*(?:,)?)+);";

private readonly IParseFailureObserver m_observer;

public ExtraMessageTransmitterLineParser(IParseFailureObserver observer)
{
m_observer = observer;
}

public bool TryParse(string line, IDbcBuilder builder, INextLineProvider nextLineProvider)
{
if (line.TrimStart().StartsWith(ExtraMessageTransmitterLineStarter) == false)
{
return false;
}

var match = Regex.Match(line, m_extraTransmitterRegex);
if (match.Success)
{
var messageId = uint.Parse(match.Groups[MessageId].Value, CultureInfo.InvariantCulture);
var transmitters = new List<string>();

foreach (var transmitter in match.Groups[TransmitterGroup].Value.Trim().Split(','))
{
var transmitterClean = transmitter.Trim();
if (transmitters.Contains(transmitterClean))
{
m_observer.ExtraMessageTransmittersDuplicate(messageId, transmitterClean);
continue;
}
transmitters.Add(transmitterClean);
}

builder.AddMessageAdditionalTransmitters(messageId, transmitters.ToArray());
}
else
{
m_observer.ExtraMessageTransmittersSyntaxError();
}

return true;
}
}
}
Loading