#ifndef DBCPARSER_H #define DBCPARSER_H #include #include #include #include #include #include #include #include #include #include #include /** * @brief DBC namespace */ namespace dbc { /** * @brief DBC source management class */ class CDbcSource { public: /** * @brief Default constructor */ CDbcSource() = default; /** * @brief Open and read the DBC source file. * @param[in] rpathDbcfile Reference to the DBC file path. */ CDbcSource(const std::filesystem::path& rpathDbcfile); /** * @brief Set DBC content. * @param[in] rssContent Reference to the DBC content. */ CDbcSource(const std::string& rssContent); /** * @brief Is a valid source? * @return Returns whether the source is valid (has content). */ bool IsValid() const; /** * @brief Get the currently assigned path. * @return The path to the source or an empty path when no path was assigned. */ const std::filesystem::path& Path() const; /** * @brief Return a reference to the complete content. * @return Reference to the content string. */ const std::string& Content() const; /** * @brief Return a pointer to the content at the current location. * @return Pointer to a character string starting at the current location. */ const char* ContentPtr() const; /** * @brief Return the character at the current location. * @return Character or '\0' when there is no character at the current location. */ char CurrentChar() const; /** * \{ * @brief Return the current position. * @return A reference to the position. */ const size_t& Pos() const; size_t& Pos(); /** * \} */ /** * @brief Reset the position to the beginning of the content. */ void ResetPos(); /** * @brief Does the current position point to the end of the content? * @return Returns whether the end of the content has been reached. */ bool IsEOF() const; /** * @brief A position lock structure, allowing to rollback to a specific position. */ struct SPosLock { /** * @brief Default constructor */ SPosLock() = default; /** * @brief Constructor * @param[in] rThis Reference to the source class. */ SPosLock(CDbcSource& rThis); /** * @brief Deleted copy constructor */ SPosLock(const SPosLock&) = delete; /** * @brief Move constructor. * @param[in] rsPosLock Reference to the SPosLock structure to move from. */ SPosLock(SPosLock&& rsPosLock) noexcept; /** * @brief Destructor */ ~SPosLock(); /** * @brief Deleted assignment operator. * @return Reference to this SPosLock structure. */ SPosLock& operator=(const SPosLock&) = delete; /** * @brief Move operator. * @param[in] rsPosLock Reference to the SPosLock structure to move from. * @return Reference to this SPosLock structure. */ SPosLock& operator=(SPosLock&& rsPosLock) noexcept; /** * @brief Accespt the current position; releases the lock. */ void Promote(); /** * @brief Rollback to the stored position and releases the lock. */ void Rollback(); private: CDbcSource* pSource = nullptr; ///< Pointer to the DBC source the lock is held on. size_t nStoredPos = 0; ///< The stored position that can be rolled back to. }; /** * @brief Create a position lock structure. * @return The position lock structure that allows a rollback. */ SPosLock CreatePosLock(); /** * @brief Calculate the line the current position is on. * @return The line number starting with 1 for the first line. */ size_t CalcLine() const; /** * @brief Calculate the column the current position is on. * @return The column number starting with 1 for the first column. */ size_t CalcColumn() const; private: std::filesystem::path m_pathFile; ///< DBC file location (if available). std::string m_ssContent; ///< DBC content string. size_t m_nPos = 0; ///< Current position. }; /** * @brief Parser exception class */ struct SDbcParserException : std::exception { /** * @brief Constructor supplying a reason for this exception. * @param[in] rSource Reference to the source causing the exception. * @param[in] rssReason Reference to the string containing the reason string. */ SDbcParserException(const CDbcSource& rSource, const std::string& rssReason) : source(rSource), ssMessage(rssReason) { CreateWhatString(); } /** * @brief Constructor supplying a reason for this exception. * @param[in] rssReason Reference to the string containing the reason string. */ SDbcParserException(const std::string& rssReason) : SDbcParserException(CDbcSource(), rssReason) {} /** * @brief Constructor supplying a reason containing parameters for this exception. * @details The constructor can be supplied a reason as well as zero or more parameters. The reason string can contain * placeholders that will be replaced by the parameter. The placeholder is identified with the percent '%' character following * a parameter index (starting at 1). If another character follows the percent character, this character will be added to the * message (e.g. the struing "%%" will result in a message containing "%"). If an index is supplied which is out of range, the * messages will include the "" at the location the parameter is supposed to be. * @tparam TParams Parameter types. * @param[in] rSource Reference to the source causing the exception. * @param[in] rssReason Reference to the string containing the reason string. * @param[in] rgtParams Parameter pack containing the parameters. */ template SDbcParserException(const CDbcSource& rSource, const std::string& rssReason, TParams... rgtParams) : source(rSource) { std::vector vecArgs; BuildParamList(vecArgs, rgtParams...); size_t nPos = 0; while (nPos < rssReason.size() && nPos != std::string::npos) { char c = rssReason[nPos++]; switch (c) { case '%': // Escaped { std::string ssNumber; while (c = rssReason[nPos++], std::isdigit(c)) ssNumber += c; if (!ssNumber.empty()) { size_t nIndex = static_cast(std::atoll(ssNumber.c_str())); if (nIndex && nIndex - 1 < vecArgs.size()) ssMessage += vecArgs[nIndex - 1]; else ssMessage += ""; } if (c) ssMessage += c; break; } default: ssMessage += c; break; } } CreateWhatString(); } /** * @brief Constructor supplying a reason containing parameters for this exception. * @details The constructor can be supplied a reason as well as zero or more parameters. The reason string can contain * placeholders that will be replaced by the parameter. The placeholder is identified with the percent '%' character following * a parameter index (starting at 1). If another character follows the percent character, this character will be added to the * message (e.g. the struing "%%" will result in a message containing "%"). If an index is supplied which is out of range, the * messages will include the "" at the location the parameter is supposed to be. * @tparam TParams Parameter types. * @param[in] rssReason Reference to the string containing the reason string. * @param[in] rgtParams Parameter pack containing the parameters. */ template SDbcParserException(const std::string& rssReason, TParams... rgtParams) : SDbcParserException(CDbcSource(), rssReason, rgtParams...) {} /** * @brief Return the reason text of this exception. * @return The reason text. */ virtual const char* what() const noexcept override { return ssWhat.c_str(); } /** * @brief Get the source attached to the exception. * @return Reference to the source. */ const CDbcSource& Source() const { return source; } /** * @brief Set the source attached to the exception. * @param[in] rSource Reference to the source to assign. */ void Source(const CDbcSource& rSource) { source = rSource; CreateWhatString(); } private: /** * @brief Build the parameter list - default function without any parameters. Does nothing. * \verbatim * @param[in] rvecParams Reference to the parameter list. * \endverbatim */ void BuildParamList(std::vector& /*rvecParams*/) {} /** * @brief Build the parameter list - add the parameters to the supplied vector. * @tparam TParam The first parameter type in the parameter list. * @tparam TParams The leftover parameter types in the parameter list. * @param[in] rvecParams Reference to the parameter list. * @param[in] tParam The first parameter. * @param[in] rgtParams Parameter pack containing the leftover parameter. */ template void BuildParamList(std::vector& rvecParams, TParam tParam, TParams... rgtParams) { std::stringstream sstream; sstream << tParam; rvecParams.push_back(std::move(sstream.str())); BuildParamList(rvecParams, rgtParams...); } /** * @brief Create what-string */ void CreateWhatString() { std::stringstream sstream; if (source.IsValid()) sstream << source.Path().generic_u8string() << "[" << source.CalcLine() << ", " << source.CalcColumn() << "]: "; sstream << ssMessage; ssWhat = std::move(sstream.str()); } CDbcSource source; ///< The source with location that might have caused the exception. std::string ssMessage; ///< The message this exception represents (resolves parameters). std::string ssWhat; ///< String containing source and message information to be returned by what() function. }; /** * @brief Value description type. */ using TValDescMap = std::map; /** * @brief Attribute definition. */ struct SAttributeDef { /** * @brief Attribute type */ enum class EType { integer, ///< Integer attribute hex_integer, ///< Hexadecimal integer attribute floating_point, ///< Floating point attribute string, ///< String attribute enumerator ///< Enumerator attribute }; /** * @brief Default constructor * @param[in] eTypeParam The attribute type (this cannot be changed any more). */ SAttributeDef(EType eTypeParam); /** * @brief Destructor */ ~SAttributeDef(); /** * @brief Copy constructor * @param[in] rAttrDef Reference to the attribute definition to copy from. */ SAttributeDef(const SAttributeDef& rAttrDef); /** * @brief Move constructor * @param[in] rAttrDef Reference to the attribute definition to move from. */ SAttributeDef(SAttributeDef&& rAttrDef); /** * @brief Assignment operator * @param[in] rAttrDef Reference to the attribute definition to assign from. * @return Reference to this attribute definition. */ SAttributeDef& operator=(const SAttributeDef& rAttrDef); /** * @brief Move operator * @param[in] rAttrDef Reference to the attribute definition to move from. * @return Reference to this attribute definition. */ SAttributeDef& operator=(SAttributeDef&& rAttrDef); /** * @brief Object type this attribute is aiming for */ enum class EObjectType { global, ///< Global attribute definition (independent) node, ///< Node specific attribute definition message, ///< Message specific attribute definition signal, ///< Signal specific attribute definition envvar, ///< Environment variable specific attribute definition }; EObjectType eObjType = EObjectType::global; ///< Object type std::string ssName; ///< Attribute name const EType eType; ///< Type of the attribute /// Unnamed union based on the attribute definition type union { struct { int32_t iMinimum; ///< Minimum value for integer attribute int32_t iMaximum; ///< Maximum value for integer attribute int32_t iDefault; ///< Default value for integer attribute } sIntValues; ///< Integer value structure struct { uint32_t uiMinimum; ///< Minimum value for hexadecimal attribute uint32_t uiMaximum; ///< Maximum value for hexadecimal attribute uint32_t uiDefault; ///< Default value for hexadecimal attribute } sHexValues; ///< Hexadecimal value structure struct { double dMinimum; ///< Minimum value for floating point attribute double dMaximum; ///< Maximum value for floating point attribute double dDefault; ///< Default value for floating point attribute } sFltValues; ///< Floating point value structure struct { std::string ssDefault; ///< Default value for string attribute } sStringValues; ///< String value structure struct { std::vector vecEnumValues; ///< Values for enumerator attribute std::string ssDefault; ///< Default value for enumerator attribute } sEnumValues; ///< Enumerator value structure }; }; /** * @brief Attribute definition shaed pointer. */ using TAttributeDefPtr = std::shared_ptr; /** * @brief Attribute value */ struct SAttributeValue { /** * @brief Constructor * @param[in] ptrAttrDefParam Reference to the attribute definition. */ SAttributeValue(TAttributeDefPtr& ptrAttrDefParam); /** * @brief Destructor */ ~SAttributeValue(); /** * @brief Copy constructor * @param[in] rAttrVal Reference to the attribute value to copy from. */ SAttributeValue(const SAttributeValue& rAttrVal); /** * @brief Move constructor * @param[in] rAttrVal Reference to the attribute value to move from. */ SAttributeValue(SAttributeValue&& rAttrVal); /** * @brief Assignment operator * @param[in] rAttrVal Reference to the attribute value to assign from. * @return Reference to this attribute value. */ SAttributeValue& operator=(const SAttributeValue& rAttrVal); /** * @brief Move operator * @param[in] rAttrVal Reference to the attribute value to move from. * @return Reference to this attribute value. */ SAttributeValue& operator=(SAttributeValue&& rAttrVal); TAttributeDefPtr ptrAttrDef; ///< Shared pointer to the attribute definition /// Unnamed union based on the attribute definition type. union { int32_t iValue; ///< Value for integer attribute uint32_t uiValue; ///< Value for hexadecimal attribute double dValue; ///< Value for floating point attribute std::string ssValue; ///< Value for string and enumerator attribute }; }; /** * @brief Node definition */ struct SNodeDef { std::string ssName; ///< Node name std::vector vecComments; ///< Comments std::vector vecAttributes; ///< Attribute values. }; /** * @brief Signal type definition. */ struct SSignalTypeBase { uint32_t uiSize = 0; ///< Size of the signal /** * @brief Signal byte order */ enum class EByteOrder { big_endian, ///< Big endian byte order little_endian, ///< Little endian byte order }; EByteOrder eByteOrder = EByteOrder::big_endian; ///< Signal's byte order /** * @brief Value type */ enum class EValueType { signed_integer, ///< Signed integer unsigned_integer, ///< Unsigned integer ieee_float, ///< IEEE float ieee_double, ///< IEEE double }; EValueType eValType = EValueType::signed_integer; ///< Value type double dFactor = 1.0; ///< Factor value: physical_value = raw_value * factor + offset double dOffset = 0.0; ///< Offset value double dMinimum = 0.0; ///< Minimum value double dMaximum = 0.0; ///< Maximum value std::string ssUnit; ///< Unit }; /** * @brief Signal type definition base */ struct SSignalDef : SSignalTypeBase { uint32_t uiMsgId = 0u; ///< Message ID this signal belongs to std::string ssName; ///< Signal name /** * @brief Type of signal */ enum class EMultiplexBitmask : uint32_t { normal = 0, ///< Not part of multiplexing mltplx_switch = 1, ///< Multiplexor signal mltplx_val = 2, ///< Multiplexed signal }; int32_t iMltplxCase = 0ll; ///< For multiplexed signals: case value. Valid when ///< uiMultiplexBitmask has bit mltplx_val set. uint32_t uiMultiplexBitmask = 0u; ///< Signal type uint32_t uiStartBit = 0; ///< Start bit std::vector vecReceivers; ///< Vector containing receivers TValDescMap mapValueDescriptions; ///< Value descriptions std::string ssSignalTypeDef; ///< When available, the type definition of the signal ///< (overriding the existing definition). std::vector vecComments; ///< Comments std::vector vecAttributes; ///< Attribute values. /** * @brief Extended multiplex information */ struct SExtendedMultiplex { SSignalDef& rsMultiplexor; ///< Multiplexor signal std::vector> vecRanges; ///< Ranges of values that validates this signal }; std::vector vecExtMultiplex; ///< Extended multiplexing information }; /** * @brief Signal type definition */ struct SSignalTypeDef : SSignalTypeBase { std::string ssName; ///< Signal type definition name double dDefaultValue; ///< Default value std::string ssValueTable; ///< Value table with signal value descriptions }; /** * @brief Signal group definition; signals within a message that should be updated together. */ struct SSignalGroupDef { std::string ssName; ///< Signal group name uint32_t uiRepetitions = 0; ///< Amount of repetitions. std::vector vecSignals; ///< Signal definition names. }; /** * @brief Message definition */ struct SMessageDef { std::string ssName; ///< Message name. uint32_t uiId = 0; ///< Message ID (covers standard and extended ID). uint32_t uiSize = 0; ///< Size of the message. std::vector vecTransmitters; ///< Transmitter node names or "Vector__XXX". std::vector vecSignals; ///< Vector with signals. std::map mapSigGroups; ///< Map containing signal groups std::vector vecComments; ///< Comments std::vector vecAttributes; ///< Attribute values. }; /** * @brief Message definition shared pointer. */ using TMessageDefPtr = std::shared_ptr; /** * @brief Environment variable definition */ struct SEnvVarDef { std::string ssName; ///< Variable name /** * @brief Type of the variable */ enum class EType { integer, ///< The variable is an integer number floating_point, ///< The variable is a floating point number string, ///< The variable is a string data, ///< The variable is a data type }; EType eType = EType::integer; ///< Variable type double dMinimum = 0.0; ///< Minimum value double dMaximum = 0.0; ///< Maximum value std::string ssUnit; ///< Unit double dInitVal = 0.0; ///< Maximum value uint32_t uiId = 0u; ///< Variable ID (obsolete) /** * @brief Access type if the variable */ enum class EAccessType { unrestricted, ///< Unrestricted access read, ///< Read access write, ///< Write access readwrite, ///< Read+write access }; EAccessType eAccess = EAccessType::unrestricted; ///< Access type std::vector vecNodes; ///< Access nodes TValDescMap mapValueDescriptions; ///< Value descriptions uint32_t uiDataSize = 0; ///< Data size in bytes (when variable is data type) std::vector vecComments; ///< Comments std::vector vecAttributes; ///< Attribute values. }; /** * @brief DBC parser class allowing access to the defined data structures. */ class CDbcParser { public: /** * @brief Default constructor. * @param[in] bNoDefaultDef When set, no default definitions should be made. */ CDbcParser(bool bNoDefaultDef = false); /** * @brief Parse the DBC content. The current content will be concatenated to the already existing content. * @param[in] rSource Reference to the DBC source. The position within the source will be updated. */ void Parse(CDbcSource& rSource); /** * @brief Clears the DBC information. Allowing new content to be added. */ void Clear(); /** * @brief Return a reference to the list of sources. * @return The reference to the vector containing the sources. */ const std::vector& GetSources() const; /** * @brief Get the vector containing the version strings of all parsed DBC sources. * @return Reference to the vector containing the version strings. */ const std::vector& GetVersions() const; /** * @brief Has a node been defined? * @param[in] rssNodeDefName Reference to the string containing the name of the node. * @return Returns 'true' when a node has been defined; 'false' otherwise. */ bool HasNodeDef(const std::string& rssNodeDefName) const; /** * @brief Get the vector containing the node definitions of all parsed DBC sources. * @return Vector containing the node definition strings. */ const std::vector GetNodeDefNames() const; /** * @brief Get the node definition with the supplied name. * @param[in] rssNodeDefName Reference to the string containing the name of the node. * @return Pair of the node and a boolean indicating whether the node exists. */ std::pair GetNodeDef(const std::string& rssNodeDefName) const; /** * @brief Is the value table with the supplied name defined? * @param[in] rssName Reference to the table name string. * @return Returns 'true' when the table with the supplied name has been defined; 'false' otherwise. */ bool HasValueTable(const std::string& rssName) const; /** * @brief Is the value within the value table with the supplied table name defined? * @param[in] rssTableName Reference to the table name string. * @param[in] uiValue Value within the table. * @return Returns 'true' when the value within the table has been defined; 'false' otherwise. */ bool HasValue(const std::string& rssTableName, uint32_t uiValue) const; /** * @brief Get the value within the value table with the supplied table name defined? * @param[in] rssTableName Reference to the table name string. * @param[in] uiValue Value within the table. * @return Returns the string when the value within the table has been defined; an empty string otherwise. */ std::string GetValue(const std::string& rssTableName, uint32_t uiValue) const; /** * @brief Get a vector with all the value tables defined. * @return Vector with value table names. */ std::vector GetValueTableNames() const; /** * @brief Get a vector with all values for a value table. * @param[in] rssTableName Reference to the table name string. * @return Pair of a vector with values and a boolean indicating whether the table exists. */ std::pair, bool> GetValues(const std::string& rssTableName) const; /** * @brief Has a message been defined? * @param[in] rssName Reference to the string containing the name of the message. * @return Returns 'true' when a message has been defined; 'false' otherwise. */ bool HasMsgDef(const std::string& rssName) const; /** * @brief Has a message been defined? * @param[in] uiRawId ID of the message (covers both standard and extended ID). * @return Returns 'true' when a message has been defined; 'false' otherwise. */ bool HasMsgDef(uint32_t uiRawId) const; /** * @brief Has a message been defined (lookup with standard ID)? * @param[in] uiStdId ID of the message (max 11 bits). * @return Returns 'true' when a message has been defined; 'false' otherwise. */ bool HasMsgDefStdId(uint32_t uiStdId) const; /** * @brief Has a message been defined (lookup with extended ID)? * @param[in] uiExtId ID of the message (max 29 bits). * @return Returns 'true' when a message has been defined; 'false' otherwise. */ bool HasMsgDefExtId(uint32_t uiExtId) const; /** * @brief Get the currently stored message IDs. * @return Vector containing the raw message IDs (covering both standard and extended IDs). */ std::vector GetMessageIDs() const; /** * @brief Get the message definition. * @param[in] rssName Reference to the string containing the name of the message. * @return Returns a pair containing the message and a boolean. If the message was found, the boolean is 'true'; otherwise the * boolean was 'false' and an empty message was returned. */ std::pair GetMsgDef(const std::string& rssName) const; /** * @brief Get the message ID from a raw ID. * @param[in] uiRawId ID of the message (covers both standard and extended ID). * @return Returns a pair with the message ID and a boolean indicating whether the ID is extended or not. */ static std::pair ExtractMsgId(uint32_t uiRawId); /** * @brief Compose a raw ID from a message ID. * @param[in] uiMsgId The ID of the message. * @param[in] bExtended When set, the message ID is an extended ID (29 bits); otherwise it is a standard ID (11 bits). * @return Returns the raw ID. */ static uint32_t ComposeRawId(uint32_t uiMsgId, bool bExtended); /** * @brief Get the message definition. * @param[in] uiRawId ID of the message (covers both standard and extended ID). * @return Returns a pair containing the message and a boolean. If the message was found, the boolean is 'true'; otherwise the * boolean was 'false' and an empty message was returned. */ std::pair GetMsgDef(uint32_t uiRawId) const; /** * @brief Get the message definition (lookup with standard ID)? * @param[in] uiStdId ID of the message (max 11 bits). * @return Returns a pair containing the message and a boolean. If the message was found, the boolean is 'true'; otherwise the * boolean was 'false' and an empty message was returned. */ std::pair GetMsgDefStdId(uint32_t uiStdId) const; /** * @brief Get the message definition (lookup with extended ID)? * @param[in] uiExtId ID of the message (max 29 bits). * @return Returns 'true' when a message has been defined; 'false' otherwise. */ std::pair GetMsgDefExtId(uint32_t uiExtId) const; /** * @brief Has a signal been defined? * @param[in] rssMsgName Reference to the string containing the name of the message. * @param[in] rssSignalName Reference to the string containing the name of the signal. * @return Returns 'true' when a signal has been defined; 'false' otherwise. * */ bool HasSignalDef(const std::string & rssMsgName, const std::string & rssSignalName) const; /** * @brief Has a signal been defined? * @param[in] uiRawMsgId ID of the message (covers both standard and extended ID). * @param[in] rssSignalName Reference to the string containing the name of the signal. * @return Returns 'true' when a signal has been defined; 'false' otherwise. */ bool HasSignalDef(uint32_t uiRawMsgId, const std::string & rssSignalName) const; /** * @brief Has a signal been defined? * @param[in] uiStdMsgId ID of the message (max 11 bits). * @param[in] rssSignalName Reference to the string containing the name of the signal. * @return Returns 'true' when a signal has been defined; 'false' otherwise. */ bool HasSignalDefStdId(uint32_t uiStdMsgId, const std::string & rssSignalName) const; /** * @brief Has a signal been defined? * @param[in] uiExtMsgId ID of the message (max 29 bits). * @param[in] rssSignalName Reference to the string containing the name of the signal. * @return Returns 'true' when a signal has been defined; 'false' otherwise. */ bool HasSignalDefExtId(uint32_t uiExtMsgId, const std::string & rssSignalName) const; /** * @brief Get the currently stored signal names for the supplied message. * @param[in] uiRawMsgId ID of the message (covers both standard and extended ID). * @return Vector containing the signal names. */ std::vector GetSignalNames(uint32_t uiRawMsgId) const; /** * @brief Get the message definition. * @param[in] rssMsgName Reference to the string containing the name of the message. * @param[in] rssSignalName Reference to the string containing the name of the signal. * @return Returns a pair containing the message and a boolean. If the message was found, the boolean is 'true'; otherwise the * boolean was 'false' and an empty message was returned. */ std::pair GetSignalDef(const std::string & rssMsgName, const std::string & rssSignalName) const; /** * @brief Get the message definition. * @param[in] uiRawMsgId ID of the message (covers both standard and extended ID). * @param[in] rssSignalName Reference to the string containing the name of the signal. * @return Returns a pair containing the message and a boolean. If the message was found, the boolean is 'true'; otherwise the * boolean was 'false' and an empty message was returned. */ std::pair GetSignalDef(uint32_t uiRawMsgId, const std::string & rssSignalName) const; /** * @brief Get the message definition. * @param[in] uiStdMsgId ID of the message (max 11 bits). * @param[in] rssSignalName Reference to the string containing the name of the signal. * @return Returns a pair containing the message and a boolean. If the message was found, the boolean is 'true'; otherwise the * boolean was 'false' and an empty message was returned. */ std::pair GetSignalDefStdId(uint32_t uiStdMsgId, const std::string & rssSignalName) const; /** * @brief Get the message definition. * @param[in] uiExtMsgId ID of the message (max 29 bits). * @param[in] rssSignalName Reference to the string containing the name of the signal. * @return Returns a pair containing the message and a boolean. If the message was found, the boolean is 'true'; otherwise the * boolean was 'false' and an empty message was returned. */ std::pair GetSignalDefExtId(uint32_t uiExtMsgId, const std::string & rssSignalName) const; /** * Get a vector with the environment variable names. * @return Vector with name strings. */ std::vector GetEnvVarNames() const; /** * @brief Get the environment variable definition. * @param[in] rssVarName Reference to the string containing the name of the environment variable. * @return Returns a pair containing the variable and a boolean. If the message was found, the boolean is 'true'; otherwise the * boolean is 'false' and an empty variable is returned. */ std::pair GetEnvVarDef(const std::string & rssVarName) const; /** * @brief Get a vector with the names of the signal type definitions. * @return Vector with name strings. */ std::vector GetSignalTypeDefNames() const; /** * @brief Get the signal type definition belonging to the provided definition name. * @param[in] rssSignalTypeDefName Reference to the string containing the name of the signal type definition to return. * @return Returns a pair containing the signal type definition and a boolean. If the type definition was found, the boolean is * 'true'; otherwise the boolean is 'false' and an empty type definition is returned. */ std::pair GetSignalTypeDef(const std::string& rssSignalTypeDefName) const; /** * @brief Get a vector with the names of the signal groups definitions. * @param[in] uiRawMsgId ID of the message (covers both standard and extended ID). * @return Vector with name strings. */ std::vector GetSignalGroupDefNames(uint32_t uiRawMsgId) const; /** * @brief Get the signal group definition belonging to the provided name. * @param[in] uiRawMsgId ID of the message (covers both standard and extended ID). * @param[in] rssSignalGroupDefName Reference to the string containing the name of the signal group definition to return. * @return Returns a pair containing the signal group definition and a boolean. If the group definition was found, the boolean * is 'true'; otherwise the boolean is 'false' and an empty group definition is returned. */ std::pair GetSignalGroupDef(uint32_t uiRawMsgId, const std::string& rssSignalGroupDefName) const; /** * @brief Get the global DBC file comments. * @return Reference to the vector with comment strings. */ const std::vector& GetComments() const; /** * @brief Get a vector with the names of the global attribute definitions. * @return Vector with name strings. */ std::vector GetAttributeDefNames() const; /** * @brief Get the attribute definition belonging to the provided name. * @param[in] rssAttributeDefName Reference to the string containing the name of the attribute definition to return. * @return Returns a pair containing the attribute definition and a boolean. If the attribute definition was found, the boolean * is 'true'; otherwise the boolean is 'false' and an empty attribute definition is returned. */ std::pair GetAttributeDef(const std::string& rssAttributeDefName) const; /** * @brief Get global attributes. * @return Reference to the vector with attribute values. */ const std::vector& GetAttributes() const; private: /** * @brief Skip whitespace and comments by updating the current source position. * @param[in] rSource Reference to the DBC source. The position within the source will be updated. */ static void SkipWhitespace(CDbcSource& rSource); /** * @brief Get an unsigned integer and update the current source position. * @param[in] rSource Reference to the DBC source. The position within the source will be updated. * @return Pair containing the integer, if available, and a boolean indicating the presence of an integer. */ static std::pair GetUInt(CDbcSource& rSource); /** * @brief Get a signed integer and update the current source position. * @param[in] rSource Reference to the DBC source. The position within the source will be updated. * @return Pair containing the integer, if available, and a boolean indicating the presence of an integer. */ static std::pair GetInt(CDbcSource& rSource); /** * @brief Get a double value and update the current source position. * @param[in] rSource Reference to the DBC source. The position within the source will be updated. * @return Pair containing the double, if available, and a boolean indicating the presence of a double. */ static std::pair GetDouble(CDbcSource & rSource); /** * @brief Expect a character and update the current source position. * @param[in] c The character to expect. * @param[in] rSource Reference to the DBC source. The position within the source will be updated. * @return Returns whether the character was found. */ static bool ExpectChar(char c, CDbcSource& rSource); /** * @brief Get the and update the current source position. A string starts with a quote and ends with a quote can contain any * printable character except quote '"' and back-slash '\'. * @param[in] rSource Reference to the DBC source. The position within the source will be updated. * @return Pair containing the string, if available, and a boolean indicating the presence of a string. */ static std::pair GetString(CDbcSource& rSource); /** * @brief Get an identifier and update the current source position. An identifier starts with an alphanumerical character or * underscore and is followed by zero or more alphanumerical character or underscores as well as digits. * @param[in] rSource Reference to the DBC source. The position within the source will be updated. * @return The identifier that was read or empty when there was no identifier. */ static std::string GetIdentifier(CDbcSource& rSource); /** * @brief A DBC identifier is an identifier that is not a keyword. * @param[in] rssIdentifier Reference to the identifier string. * @return Returns whether the supplied identifier is not a keyword. */ static bool IsDbcIdentifier(const std::string& rssIdentifier); /** * @brief Read the DBC version string. * @param[in] rSource Reference to the DBC source. The position within the source will be updated. */ void ReadVersion(CDbcSource& rSource); /** * @brief Read the new symbols used in this DBC file. * @param[in] rSource Reference to the DBC source. The position within the source will be updated. */ void ReadNewSymbols(CDbcSource& rSource); /** * @brief Read the bit timing definition. * @param[in] rSource Reference to the DBC source. The position within the source will be updated. */ void ReadBitTiming(CDbcSource& rSource); /** * @brief Read the node definitions. * @param[in] rSource Reference to the DBC source. The position within the source will be updated. */ void ReadNodeDef(CDbcSource& rSource); /** * @brief Read the global value table. * @param[in] rSource Reference to the DBC source. The position within the source will be updated. */ void ReadValTable(CDbcSource& rSource); /** * @brief Read the message definitions. * @param[in] rSource Reference to the DBC source. The position within the source will be updated. */ void ReadMessageDef(CDbcSource& rSource); /** * @brief Read the signal type definition (base part). * @param[in] rSource Reference to the DBC source. The position within the source will be updated. * @param[in, out] rsSignalTypeDefBase Reference to the signal type def. */ void ReadSignalTypeDefBase(CDbcSource& rSource, SSignalTypeBase& rsSignalTypeDefBase); /** * @brief Read the signal definitions. * @param[in] rSource Reference to the DBC source. The position within the source will be updated. * @param[in, out] rsMsgDef Reference to the message definition for this signal. */ void ReadSignalDef(CDbcSource& rSource, SMessageDef& rsMsgDef); /** * @brief Read the signal value type definition. * @param[in] rSource Reference to the DBC source. The position within the source will be updated. */ void ReadSignalValueTypeDef(CDbcSource& rSource); /** * @brief Read the message transmitters. * @param[in] rSource Reference to the DBC source. The position within the source will be updated. */ void ReadMessageTransmitters(CDbcSource& rSource); /** * @brief Read the value descriptions (for signals and environment variables). * @param[in] rSource Reference to the DBC source. The position within the source will be updated. */ void ReadValueDescriptions(CDbcSource& rSource); /** * @brief Read the environment variable definition. * @param[in] rSource Reference to the DBC source. The position within the source will be updated. */ void ReadEnvVarDef(CDbcSource& rSource); /** * @brief Read the environment variable data. * @param[in] rSource Reference to the DBC source. The position within the source will be updated. */ void ReadEnvVarData(CDbcSource& rSource); /** * @brief Read the signal type definition. * @param[in] rSource Reference to the DBC source. The position within the source will be updated. */ void ReadSignalTypeDef(CDbcSource& rSource); /** * @brief Read the signal group definition. * @param[in] rSource Reference to the DBC source. The position within the source will be updated. */ void ReadSignalGroupDef(CDbcSource& rSource); /** * @brief Read the comment definitions. * @param[in] rSource Reference to the DBC source. The position within the source will be updated. */ void ReadCommentDef(CDbcSource& rSource); /** * @brief Read user attribute definitions. * @param[in] rSource Reference to the DBC source. The position within the source will be updated. */ void ReadAttrDef(CDbcSource& rSource); /** * @brief Read user attribute default definitions. * @param[in] rSource Reference to the DBC source. The position within the source will be updated. */ void ReadAttrDefaultDef(CDbcSource& rSource); /** * @brief Read user attributes. * @param[in] rSource Reference to the DBC source. The position within the source will be updated. */ void ReadAttributes(CDbcSource& rSource); /** * @brief Read the signal multiplex definition. * @param[in] rSource Reference to the DBC source. The position within the source will be updated. */ void ReadSignalMultiplexDef(CDbcSource& rSource); std::vector m_vecSources; ///< Vector containing the DBC sources. std::vector m_vecVersions; ///< Vector containing the versions of the parsed ///< files. std::map m_mapNodes; ///< Set containing all the nodes. std::map m_mapValueTables; ///< Value tables. std::map m_mapMsgDefByName; ///< Message definitions sorted by name. std::map m_mapMsgDefById; ///< Message definitions sorted by ID. std::map m_mapEnvVars; ///< Map containing the environment variables. std::map m_mapSigTypeDefs; ///< Map containing the signal type definitions. std::vector m_vecComments; ///< Global comments std::vector m_vecAttributes; ///< Vector containing the global attribute values. uint32_t m_uiIndepMsgId = 0xffffffff; ///< Current ID for Vector independent message. std::map m_mapAttrDefs; ///< Map containing the attribute definitions. }; } // namespace dbc #endif // !defined DBCPARSER_H