Program Listing for File dbcparser.h#
↰ Return to documentation for file (dbcparser\dbcparser.h)
#ifndef DBCPARSER_H
#define DBCPARSER_H
#include <filesystem>
#include <vector>
#include <string>
#include <fstream>
#include <sstream>
#include <cctype>
#include <cstdlib>
#include <utility>
#include <set>
#include <map>
#include <memory>
namespace dbc
{
class CDbcSource
{
public:
CDbcSource() = default;
CDbcSource(const std::filesystem::path& rpathDbcfile);
CDbcSource(const std::string& rssContent);
bool IsValid() const;
const std::filesystem::path& Path() const;
const std::string& Content() const;
const char* ContentPtr() const;
char CurrentChar() const;
const size_t& Pos() const;
size_t& Pos();
void ResetPos();
bool IsEOF() const;
struct SPosLock
{
SPosLock() = default;
SPosLock(CDbcSource& rThis);
SPosLock(const SPosLock&) = delete;
SPosLock(SPosLock&& rsPosLock) noexcept;
~SPosLock();
SPosLock& operator=(const SPosLock&) = delete;
SPosLock& operator=(SPosLock&& rsPosLock) noexcept;
void Promote();
void Rollback();
private:
CDbcSource* pSource = nullptr;
size_t nStoredPos = 0;
};
SPosLock CreatePosLock();
size_t CalcLine() const;
size_t CalcColumn() const;
private:
std::filesystem::path m_pathFile;
std::string m_ssContent;
size_t m_nPos = 0;
};
struct SDbcParserException : std::exception
{
SDbcParserException(const CDbcSource& rSource, const std::string& rssReason) :
source(rSource), ssMessage(rssReason)
{
CreateWhatString();
}
SDbcParserException(const std::string& rssReason) : SDbcParserException(CDbcSource(), rssReason)
{}
template <typename... TParams>
SDbcParserException(const CDbcSource& rSource, const std::string& rssReason, TParams... rgtParams) : source(rSource)
{
std::vector<std::string> 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<size_t>(std::atoll(ssNumber.c_str()));
if (nIndex && nIndex - 1 < vecArgs.size())
ssMessage += vecArgs[nIndex - 1];
else
ssMessage += "<unknown>";
}
if (c) ssMessage += c;
break;
}
default:
ssMessage += c;
break;
}
}
CreateWhatString();
}
template <typename... TParams>
SDbcParserException(const std::string& rssReason, TParams... rgtParams) :
SDbcParserException(CDbcSource(), rssReason, rgtParams...)
{}
virtual const char* what() const noexcept override
{
return ssWhat.c_str();
}
const CDbcSource& Source() const
{
return source;
}
void Source(const CDbcSource& rSource)
{
source = rSource;
CreateWhatString();
}
private:
void BuildParamList(std::vector<std::string>& /*rvecParams*/) {}
template <typename TParam, typename... TParams>
void BuildParamList(std::vector<std::string>& rvecParams, TParam tParam, TParams... rgtParams)
{
std::stringstream sstream;
sstream << tParam;
rvecParams.push_back(std::move(sstream.str()));
BuildParamList(rvecParams, rgtParams...);
}
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;
std::string ssMessage;
std::string ssWhat;
};
using TValDescMap = std::map<uint32_t, std::string>;
struct SAttributeDef
{
enum class EType
{
integer,
hex_integer,
floating_point,
string,
enumerator
};
SAttributeDef(EType eTypeParam);
~SAttributeDef();
SAttributeDef(const SAttributeDef& rAttrDef);
SAttributeDef(SAttributeDef&& rAttrDef);
SAttributeDef& operator=(const SAttributeDef& rAttrDef);
SAttributeDef& operator=(SAttributeDef&& rAttrDef);
enum class EObjectType
{
global,
node,
message,
signal,
envvar,
};
EObjectType eObjType = EObjectType::global;
std::string ssName;
const EType eType;
union
{
struct
{
int32_t iMinimum;
int32_t iMaximum;
int32_t iDefault;
} sIntValues;
struct
{
uint32_t uiMinimum;
uint32_t uiMaximum;
uint32_t uiDefault;
} sHexValues;
struct
{
double dMinimum;
double dMaximum;
double dDefault;
} sFltValues;
struct
{
std::string ssDefault;
} sStringValues;
struct
{
std::vector<std::string> vecEnumValues;
std::string ssDefault;
} sEnumValues;
};
};
using TAttributeDefPtr = std::shared_ptr<SAttributeDef>;
struct SAttributeValue
{
SAttributeValue(TAttributeDefPtr& ptrAttrDefParam);
~SAttributeValue();
SAttributeValue(const SAttributeValue& rAttrVal);
SAttributeValue(SAttributeValue&& rAttrVal);
SAttributeValue& operator=(const SAttributeValue& rAttrVal);
SAttributeValue& operator=(SAttributeValue&& rAttrVal);
TAttributeDefPtr ptrAttrDef;
union
{
int32_t iValue;
uint32_t uiValue;
double dValue;
std::string ssValue;
};
};
struct SNodeDef
{
std::string ssName;
std::vector<std::string> vecComments;
std::vector<SAttributeValue> vecAttributes;
};
struct SSignalTypeBase
{
uint32_t uiSize = 0;
enum class EByteOrder
{
big_endian,
little_endian,
};
EByteOrder eByteOrder = EByteOrder::big_endian;
enum class EValueType
{
signed_integer,
unsigned_integer,
ieee_float,
ieee_double,
};
EValueType eValType = EValueType::signed_integer;
double dFactor = 1.0;
double dOffset = 0.0;
double dMinimum = 0.0;
double dMaximum = 0.0;
std::string ssUnit;
};
struct SSignalDef : SSignalTypeBase
{
uint32_t uiMsgId = 0u;
std::string ssName;
enum class EMultiplexBitmask : uint32_t
{
normal = 0,
mltplx_switch = 1,
mltplx_val = 2,
};
int32_t iMltplxCase = 0ll;
uint32_t uiMultiplexBitmask = 0u;
uint32_t uiStartBit = 0;
std::vector<std::string> vecReceivers;
TValDescMap mapValueDescriptions;
std::string ssSignalTypeDef;
std::vector<std::string> vecComments;
std::vector<SAttributeValue> vecAttributes;
struct SExtendedMultiplex
{
SSignalDef& rsMultiplexor;
std::vector<std::pair<uint32_t, uint32_t>> vecRanges;
};
std::vector<SExtendedMultiplex> vecExtMultiplex;
};
struct SSignalTypeDef : SSignalTypeBase
{
std::string ssName;
double dDefaultValue;
std::string ssValueTable;
};
struct SSignalGroupDef
{
std::string ssName;
uint32_t uiRepetitions = 0;
std::vector<std::string> vecSignals;
};
struct SMessageDef
{
std::string ssName;
uint32_t uiId = 0;
uint32_t uiSize = 0;
std::vector<std::string> vecTransmitters;
std::vector<SSignalDef> vecSignals;
std::map<std::string, SSignalGroupDef> mapSigGroups;
std::vector<std::string> vecComments;
std::vector<SAttributeValue> vecAttributes;
};
using TMessageDefPtr = std::shared_ptr<SMessageDef>;
struct SEnvVarDef
{
std::string ssName;
enum class EType
{
integer,
floating_point,
string,
data,
};
EType eType = EType::integer;
double dMinimum = 0.0;
double dMaximum = 0.0;
std::string ssUnit;
double dInitVal = 0.0;
uint32_t uiId = 0u;
enum class EAccessType
{
unrestricted,
read,
write,
readwrite,
};
EAccessType eAccess = EAccessType::unrestricted;
std::vector<std::string> vecNodes;
TValDescMap mapValueDescriptions;
uint32_t uiDataSize = 0;
std::vector<std::string> vecComments;
std::vector<SAttributeValue> vecAttributes;
};
class CDbcParser
{
public:
CDbcParser(bool bNoDefaultDef = false);
void Parse(CDbcSource& rSource);
void Clear();
const std::vector<CDbcSource>& GetSources() const;
const std::vector<std::string>& GetVersions() const;
bool HasNodeDef(const std::string& rssNodeDefName) const;
const std::vector<std::string> GetNodeDefNames() const;
std::pair<SNodeDef, bool> GetNodeDef(const std::string& rssNodeDefName) const;
bool HasValueTable(const std::string& rssName) const;
bool HasValue(const std::string& rssTableName, uint32_t uiValue) const;
std::string GetValue(const std::string& rssTableName, uint32_t uiValue) const;
std::vector<std::string> GetValueTableNames() const;
std::pair<std::vector<uint32_t>, bool> GetValues(const std::string& rssTableName) const;
bool HasMsgDef(const std::string& rssName) const;
bool HasMsgDef(uint32_t uiRawId) const;
bool HasMsgDefStdId(uint32_t uiStdId) const;
bool HasMsgDefExtId(uint32_t uiExtId) const;
std::vector<uint32_t> GetMessageIDs() const;
std::pair<SMessageDef, bool> GetMsgDef(const std::string& rssName) const;
static std::pair<uint32_t, bool> ExtractMsgId(uint32_t uiRawId);
static uint32_t ComposeRawId(uint32_t uiMsgId, bool bExtended);
std::pair<SMessageDef, bool> GetMsgDef(uint32_t uiRawId) const;
std::pair<SMessageDef, bool> GetMsgDefStdId(uint32_t uiStdId) const;
std::pair<SMessageDef, bool> GetMsgDefExtId(uint32_t uiExtId) const;
bool HasSignalDef(const std::string & rssMsgName, const std::string & rssSignalName) const;
bool HasSignalDef(uint32_t uiRawMsgId, const std::string & rssSignalName) const;
bool HasSignalDefStdId(uint32_t uiStdMsgId, const std::string & rssSignalName) const;
bool HasSignalDefExtId(uint32_t uiExtMsgId, const std::string & rssSignalName) const;
std::vector<std::string> GetSignalNames(uint32_t uiRawMsgId) const;
std::pair<SSignalDef, bool> GetSignalDef(const std::string & rssMsgName, const std::string & rssSignalName) const;
std::pair<SSignalDef, bool> GetSignalDef(uint32_t uiRawMsgId, const std::string & rssSignalName) const;
std::pair<SSignalDef, bool> GetSignalDefStdId(uint32_t uiStdMsgId, const std::string & rssSignalName) const;
std::pair<SSignalDef, bool> GetSignalDefExtId(uint32_t uiExtMsgId, const std::string & rssSignalName) const;
std::vector<std::string> GetEnvVarNames() const;
std::pair<SEnvVarDef, bool> GetEnvVarDef(const std::string & rssVarName) const;
std::vector<std::string> GetSignalTypeDefNames() const;
std::pair<SSignalTypeDef, bool> GetSignalTypeDef(const std::string& rssSignalTypeDefName) const;
std::vector<std::string> GetSignalGroupDefNames(uint32_t uiRawMsgId) const;
std::pair<SSignalGroupDef, bool> GetSignalGroupDef(uint32_t uiRawMsgId, const std::string& rssSignalGroupDefName) const;
const std::vector<std::string>& GetComments() const;
std::vector<std::string> GetAttributeDefNames() const;
std::pair<SAttributeDef, bool> GetAttributeDef(const std::string& rssAttributeDefName) const;
const std::vector<SAttributeValue>& GetAttributes() const;
private:
static void SkipWhitespace(CDbcSource& rSource);
static std::pair<uint32_t, bool> GetUInt(CDbcSource& rSource);
static std::pair<int32_t, bool> GetInt(CDbcSource& rSource);
static std::pair<double, bool> GetDouble(CDbcSource & rSource);
static bool ExpectChar(char c, CDbcSource& rSource);
static std::pair<std::string, bool> GetString(CDbcSource& rSource);
static std::string GetIdentifier(CDbcSource& rSource);
static bool IsDbcIdentifier(const std::string& rssIdentifier);
void ReadVersion(CDbcSource& rSource);
void ReadNewSymbols(CDbcSource& rSource);
void ReadBitTiming(CDbcSource& rSource);
void ReadNodeDef(CDbcSource& rSource);
void ReadValTable(CDbcSource& rSource);
void ReadMessageDef(CDbcSource& rSource);
void ReadSignalTypeDefBase(CDbcSource& rSource, SSignalTypeBase& rsSignalTypeDefBase);
void ReadSignalDef(CDbcSource& rSource, SMessageDef& rsMsgDef);
void ReadSignalValueTypeDef(CDbcSource& rSource);
void ReadMessageTransmitters(CDbcSource& rSource);
void ReadValueDescriptions(CDbcSource& rSource);
void ReadEnvVarDef(CDbcSource& rSource);
void ReadEnvVarData(CDbcSource& rSource);
void ReadSignalTypeDef(CDbcSource& rSource);
void ReadSignalGroupDef(CDbcSource& rSource);
void ReadCommentDef(CDbcSource& rSource);
void ReadAttrDef(CDbcSource& rSource);
void ReadAttrDefaultDef(CDbcSource& rSource);
void ReadAttributes(CDbcSource& rSource);
void ReadSignalMultiplexDef(CDbcSource& rSource);
std::vector<CDbcSource> m_vecSources;
std::vector<std::string> m_vecVersions;
std::map<std::string, SNodeDef> m_mapNodes;
std::map<std::string, TValDescMap> m_mapValueTables;
std::map<std::string, TMessageDefPtr> m_mapMsgDefByName;
std::map<uint32_t, TMessageDefPtr> m_mapMsgDefById;
std::map<std::string, SEnvVarDef> m_mapEnvVars;
std::map<std::string, SSignalTypeDef> m_mapSigTypeDefs;
std::vector<std::string> m_vecComments;
std::vector<SAttributeValue> m_vecAttributes;
uint32_t m_uiIndepMsgId = 0xffffffff;
std::map<std::string, TAttributeDefPtr> m_mapAttrDefs;
};
} // namespace dbc
#endif // !defined DBCPARSER_H