99#include < libdbc/utils/utils.hpp>
1010#include < regex>
1111#include < string>
12+ #include < unordered_map>
1213#include < vector>
1314
1415namespace Libdbc {
@@ -17,6 +18,7 @@ const auto floatPattern = "(-?\\d+\\.?(\\d+)?)"; // Can be negative
1718
1819const auto signalIdentifierPattern = " (SG_)" ;
1920const auto namePattern = " (\\ w+)" ;
21+ const auto multiplexerPattern = " (?:\\ s(M|m\\ d+M?))?" ; // Optional: M = multiplexor, mN = multiplexed by value N, mNM = both
2022const auto bitStartPattern = " (\\ d+)" ; // Cannot be negative
2123const auto lengthPattern = " (\\ d+)" ; // Cannot be negative
2224const auto byteOrderPattern = " ([0-1])" ;
@@ -34,16 +36,17 @@ const auto receiverPattern = "([\\w\\,]+|Vector__XXX)*";
3436const auto whiteSpace = " \\ s" ;
3537
3638constexpr unsigned SIGNAL_NAME_GROUP = 2 ;
37- constexpr unsigned SIGNAL_START_BIT_GROUP = 3 ;
38- constexpr unsigned SIGNAL_SIZE_GROUP = 4 ;
39- constexpr unsigned SIGNAL_ENDIAN_GROUP = 5 ;
40- constexpr unsigned SIGNAL_SIGNED_GROUP = 6 ;
41- constexpr unsigned SIGNAL_FACTOR_GROUP = 7 ;
42- constexpr unsigned SIGNAL_OFFSET_GROUP = 9 ;
43- constexpr unsigned SIGNAL_MIN_GROUP = 11 ;
44- constexpr unsigned SIGNAL_MAX_GROUP = 13 ;
45- constexpr unsigned SIGNAL_UNIT_GROUP = 15 ;
46- constexpr unsigned SIGNAL_RECIEVER_GROUP = 16 ;
39+ constexpr unsigned SIGNAL_MULTIPLEXER_GROUP = 3 ;
40+ constexpr unsigned SIGNAL_START_BIT_GROUP = 4 ;
41+ constexpr unsigned SIGNAL_SIZE_GROUP = 5 ;
42+ constexpr unsigned SIGNAL_ENDIAN_GROUP = 6 ;
43+ constexpr unsigned SIGNAL_SIGNED_GROUP = 7 ;
44+ constexpr unsigned SIGNAL_FACTOR_GROUP = 8 ;
45+ constexpr unsigned SIGNAL_OFFSET_GROUP = 10 ;
46+ constexpr unsigned SIGNAL_MIN_GROUP = 12 ;
47+ constexpr unsigned SIGNAL_MAX_GROUP = 14 ;
48+ constexpr unsigned SIGNAL_UNIT_GROUP = 16 ;
49+ constexpr unsigned SIGNAL_RECIEVER_GROUP = 17 ;
4750
4851constexpr unsigned MESSAGE_ID_GROUP = 2 ;
4952constexpr unsigned MESSAGE_NAME_GROUP = 3 ;
@@ -63,11 +66,9 @@ DbcParser::DbcParser()
6366 , node_re(" ^(BU_:)\\ s?((?:[\\ w]+?\\ s?)*)?" )
6467 , message_re(" ^(BO_)\\ s(\\ d+)\\ s(\\ w+)\\ :\\ s(\\ d+)\\ s(\\ w+|Vector__XXX)" )
6568 , value_re(" ^(VAL_)\\ s(\\ d+)\\ s(\\ w+)((?:\\ s(\\ d+)\\ s\" ([^\" ]*)\" )+)\\ s;$" )
66- ,
67- // NOTE: No multiplex support yet
68- signal_re(std::string(" ^" ) + whiteSpace + signalIdentifierPattern + whiteSpace + namePattern + whiteSpace + "\\:" + whiteSpace + bitStartPattern + "\\|"
69- + lengthPattern + "\\@" + byteOrderPattern + signPattern + whiteSpace + offsetScalePattern + whiteSpace + minMaxPattern + whiteSpace + unitPattern
70- + whiteSpace + receiverPattern) {
69+ , signal_re(std::string(" ^" ) + whiteSpace + signalIdentifierPattern + whiteSpace + namePattern + multiplexerPattern + whiteSpace + "\\:" + whiteSpace
70+ + bitStartPattern + "\\|" + lengthPattern + "\\@" + byteOrderPattern + signPattern + whiteSpace + offsetScalePattern + whiteSpace
71+ + minMaxPattern + whiteSpace + unitPattern + whiteSpace + receiverPattern) {
7172}
7273
7374void DbcParser::parse_file (std::istream& stream) {
@@ -128,6 +129,16 @@ Message::ParseSignalsStatus DbcParser::parse_message(const uint32_t message_id,
128129 return Message::ParseSignalsStatus::ErrorUnknownID;
129130}
130131
132+ Message::ParseSignalsStatus
133+ DbcParser::parse_message (const uint32_t message_id, const std::vector<uint8_t >& data, std::unordered_map<std::string, double >& out_values) {
134+ for (const auto & message : messages) {
135+ if (message.id () == message_id) {
136+ return message.parse_signals (data, out_values);
137+ }
138+ }
139+ return Message::ParseSignalsStatus::ErrorUnknownID;
140+ }
141+
131142void DbcParser::parse_dbc_header (std::istream& file_stream) {
132143 std::string line;
133144 std::smatch match;
@@ -183,7 +194,11 @@ void DbcParser::parse_dbc_messages(const std::vector<std::string>& lines) {
183194
184195 if (std::regex_search (line, match, signal_re) && !messages.empty ()) {
185196 std::string name = match.str (SIGNAL_NAME_GROUP );
186- bool is_multiplexed = false ; // No support yet
197+ // Multiplexer indicator: "M", "mN" or "mNM" (extended multiplexing)
198+ std::string multiplexer = match.str (SIGNAL_MULTIPLEXER_GROUP );
199+ bool is_multiplexed = !multiplexer.empty () && multiplexer.front () == ' m' ;
200+ bool is_multiplexor = !multiplexer.empty () && multiplexer.back () == ' M' ;
201+ uint32_t multiplexer_value = is_multiplexed ? static_cast <uint32_t >(std::stoul (multiplexer.substr (1 ))) : 0 ;
187202 uint32_t start_bit = static_cast <uint32_t >(std::stoul (match.str (SIGNAL_START_BIT_GROUP )));
188203 uint32_t size = static_cast <uint32_t >(std::stoul (match.str (SIGNAL_SIZE_GROUP )));
189204 bool is_bigendian = (std::stoul (match.str (SIGNAL_ENDIAN_GROUP )) == 0 );
@@ -200,6 +215,8 @@ void DbcParser::parse_dbc_messages(const std::vector<std::string>& lines) {
200215 Utils::String::split (match.str (SIGNAL_RECIEVER_GROUP ), receivers, ' ,' );
201216
202217 Signal sig (name, is_multiplexed, start_bit, size, is_bigendian, is_signed, factor, offset, min, max, unit, receivers);
218+ sig.is_multiplexor = is_multiplexor;
219+ sig.multiplexer_value = multiplexer_value;
203220 messages.back ().append_signal (sig);
204221 continue ;
205222 }
0 commit comments