/** * @file * * @copyright * @verbatim Copyright @ 2017 Audi Electronics Venture GmbH. All rights reserved. This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/. If it is not possible or desirable to put the notice in a particular file, then You may include the notice in a location (such as a LICENSE file in a relevant directory) where a recipient would be likely to look for such a notice. You may add additional accurate notices of copyright ownership. @endverbatim */ #include "ddlimporter.h" #include #include "a_util/result/error_def.h" #include "legacy_error_macros.h" #include "ddldescription.h" #include "ddlunit.h" #include "ddlbaseunit.h" #include "ddlprefix.h" #include "ddldatatype.h" #include "ddlenum.h" #include "ddlcomplex.h" #include "ddlstream.h" #include "ddlstreammetatype.h" #include "ddlheader.h" #include "ddlextdeclaration.h" #include "ddlrefunit.h" #include "ddlelement.h" #include "ddlstreamstruct.h" #include "ddlversion.h" namespace ddl { //define all needed error types and values locally _MAKE_RESULT(-2, ERR_UNKNOWN) _MAKE_RESULT(-4, ERR_POINTER) _MAKE_RESULT(-5, ERR_INVALID_ARG) _MAKE_RESULT(-15, ERR_RESOURCE_IN_USE) _MAKE_RESULT(-18, ERR_NO_CLASS) _MAKE_RESULT(-20, ERR_NOT_FOUND) _MAKE_RESULT(-27, ERR_OPEN_FAILED) _MAKE_RESULT(-36, ERR_UNKNOWN_FORMAT) _MAKE_RESULT(-37, ERR_NOT_INITIALIZED) /** * Iterator type for cDOMElementList */ typedef a_util::xml::DOMElementList::iterator tDOMElemIt; #define RETURN_IF_FAILED_AND_LOG_ERROR_STR_DDLIMPORTER(code, desc) \ { \ a_util::result::Result __err_code = code; \ if (isFailed(__err_code)){ _fnLogOutput(( desc ), LOG_LVL_ERROR, __FILE__, (uint32_t) __LINE__, (code)); \ ImporterMsg sError = {std::string(desc), importer_error}; \ _errors.push_back(sError); \ return (__err_code); }\ } DDLImporter::DDLImporter(bool bBasicCheck, bool bSorted) : _dom{}, _ddl_desc{}, _current_ref_ddl{}, _unknown_units{}, _unknown_structs{}, _unknown_stream_meta_types{}, _init_flag{}, _creation_level{1}, _full_check{}, _errors{}, _basic_check{bBasicCheck}, _merge_defaults{true}, _sorted{bSorted}, _prefere_reference{true} { } DDLImporter::DDLImporter(const a_util::filesystem::Path& strFile, bool bBasicCheck, bool bSorted) : DDLImporter(bBasicCheck, bSorted) { _init_flag = isOk(setFile(strFile)); } DDLImporter::DDLImporter(const char* strFile, bool bBasicCheck, bool bSorted) : DDLImporter(a_util::filesystem::Path(strFile), bBasicCheck, bSorted) { } DDLImporter::DDLImporter(int nCreationLevel, bool bBasicCheck, bool bSorted) : DDLImporter(bBasicCheck, bSorted) { _creation_level = nCreationLevel; } DDLImporter& DDLImporter::operator=(DDLImporter other) { swap(*this, other); return *this; } DDLImporter::DDLImporter(DDLImporter&& other) { swap(*this, other); } DDLImporter::~DDLImporter() { // The DDL object does not get deleted because the caller/user of this // object is responsible for it. _ddl_desc = NULL; _current_ref_ddl = NULL; _unknown_units.deleteAll(); _unknown_structs.deleteAll(); _unknown_stream_meta_types.deleteAll(); } void swap(DDLImporter& lhs, DDLImporter& rhs) noexcept { using std::swap; swap(lhs._basic_check, rhs._basic_check); swap(lhs._creation_level, rhs._creation_level); swap(lhs._current_ref_ddl, rhs._current_ref_ddl); swap(lhs._ddl_desc, rhs._ddl_desc); swap(lhs._dom, rhs._dom); swap(lhs._errors, rhs._errors); swap(lhs._full_check, rhs._full_check); swap(lhs._init_flag, rhs._init_flag); swap(lhs._merge_defaults, rhs._merge_defaults); swap(lhs._prefere_reference, rhs._prefere_reference); swap(lhs._sorted, rhs._sorted); swap(lhs._unknown_stream_meta_types, rhs._unknown_stream_meta_types); swap(lhs._unknown_structs, rhs._unknown_structs); swap(lhs._unknown_units, rhs._unknown_units); } std::string DDLImporter::getErrorDesc() const { // compatibility to cDDLChecker return getLastErrorDesc(); } std::string DDLImporter::getLastErrorDesc() const { // return description of most recently added error element for (ImporterMsgList::const_reverse_iterator itMsgs = _errors.rbegin(); _errors.rend() != itMsgs; ++itMsgs) { if (importer_error == itMsgs->severity) { return std::string(itMsgs->desc); } } return a_util::strings::empty_string; } void DDLImporter::printAllMessages(ImporterMsgSeverity eLeastSeverity /* = importer_info */) { for (ImporterMsgList::const_iterator itMsg = _errors.begin(); _errors.end() != itMsg; ++itMsg) { switch (itMsg->severity) { case importer_error: { LOG_ERROR(itMsg->desc.c_str()); break; } case importer_warning: { if (importer_error != eLeastSeverity) { LOG_WARNING(itMsg->desc.c_str()); } break; } case importer_info: { if (importer_info == eLeastSeverity) { LOG_INFO(itMsg->desc.c_str()); } break; } default: { LOG_ERROR("Unknown message severity detected."); break; } } } } ImporterMsgList DDLImporter::getAllMessages() const { return _errors; } DDLDescription * DDLImporter::getDDL() const { return _ddl_desc; } void DDLImporter::destroyDDL() { destroyDDL(_ddl_desc); _ddl_desc = NULL; // no DDL objects => no valid messages _errors.clear(); } void DDLImporter::destroyDDL(DDLDescription *poDDL) { delete poDDL; } a_util::result::Result DDLImporter::setFile(const a_util::filesystem::Path& strFile) { _init_flag = _dom.load(strFile); if (!_init_flag) { ImporterMsg sError = {_dom.getLastError(), importer_error }; _errors.push_back(sError); return ERR_OPEN_FAILED; } return a_util::result::SUCCESS; } a_util::result::Result DDLImporter::setXML(const std::string& strXML) { _init_flag = _dom.fromString(strXML); if (!_init_flag) { ImporterMsg sError = {_dom.getLastError(), importer_error}; _errors.push_back(sError); LOG_ERROR(_dom.getLastError().c_str()); return ERR_OPEN_FAILED; } return a_util::result::SUCCESS; } void DDLImporter::setCreationLevel(int const nLevel) { _creation_level = nLevel; } void DDLImporter::setFullCheckDescriptionMode(bool bFullCheck) { _full_check = bFullCheck; } void DDLImporter::setMergeDefaults(bool bMergeDefaults) { _merge_defaults = bMergeDefaults; } void DDLImporter::setPreferReferenceEntities(bool bPrefereReference) { _prefere_reference = bPrefereReference; } a_util::result::Result DDLImporter::createNew(const DDLVersion& requestedVersion /* = 0 */) { DDLVersion version = requestedVersion; if (version == DDLVersion::ddl_version_invalid) { version = DDLVersion::ddl_version_current; } if (!_init_flag) { return ERR_NOT_INITIALIZED; } // The DDL object does not get deleted because the caller/user of this // object is responsible for it. _ddl_desc = NULL; // build up new DDL if (_full_check) { if (isFailed(buildHeader()) && _ddl_desc == NULL) { _ddl_desc = new DDLDescription(new DDLHeader(), DDLUnitVec(_sorted), DDLBaseunitVec(_sorted), DDLPrefixVec(_sorted), DDLDTVec(_sorted), DDLComplexVec(_sorted), DDLStreamVec(_sorted), DDLEnumVec(_sorted), _merge_defaults); } buildUnits(); buildDatatypes(); buildEnums(); buildStructs(); buildStreams(); if (version >= DDLVersion::ddl_version_40) buildStreamMetaTypes(); // check if any error occurred during build up new DDL for (ImporterMsgList::const_iterator itMsg = _errors.begin(); _errors.end() != itMsg; ++itMsg) { if (itMsg->severity == importer_error) { return ERR_UNKNOWN_FORMAT; } } } else { RETURN_IF_FAILED(buildHeader()); RETURN_IF_FAILED(buildUnits()); RETURN_IF_FAILED(buildDatatypes()); RETURN_IF_FAILED(buildEnums()); RETURN_IF_FAILED(buildStructs()); RETURN_IF_FAILED(buildStreams()); if (version >= DDLVersion::ddl_version_40) RETURN_IF_FAILED(buildStreamMetaTypes()); } return a_util::result::SUCCESS; } a_util::result::Result DDLImporter::createPartial(const DDLDescription* poRefDDL, const DDLVersion& requestedVersion) { DDLVersion version = requestedVersion; if (!poRefDDL) { return ERR_POINTER; } if (!_init_flag) { return ERR_NOT_INITIALIZED; } _current_ref_ddl = poRefDDL; _ddl_desc = NULL; std::string strElementType = _dom.getRoot().getName(); if (strElementType == "adtf:ddl" || strElementType == "description" || strElementType == "units" || strElementType == "datatypes" || strElementType == "structs" || strElementType == "streams" || strElementType == "enums" || strElementType == "streammetatypes" || (strElementType != "datatype" && strElementType != "baseunit" && strElementType != "prefixes" && strElementType != "unit" && strElementType != "datatype" && strElementType != "struct" && strElementType != "stream" && strElementType != "enum" && strElementType != "streammetatype")) { a_util::xml::DOMElement oRoot = _dom.getRoot(); a_util::xml::DOMElement oTmpElement; bool bValidElementFound = false; bool bFoundEnums = false; //this is to detect 2.0 MediaDescriptions //i.e. the device-tb etc. uses enums!! and did not raise the version number at all!!! if (_dom.findNode("//enums", oTmpElement)) { bFoundEnums = true; if (version < DDLVersion::ddl_version_20) { version = DDLVersion::ddl_version_20; } } if (oRoot.findNode("header", oTmpElement)) { RETURN_IF_FAILED(buildHeader()); bValidElementFound = true; } else { _ddl_desc = DDLDescription::createDefault(version, _creation_level, _sorted); } //this is to detect 2.0 MediaDescriptions //i.e. the device-tb etc. uses enums!! and did not raise the version number at all!!!device-tb etc. uses enums!! and did not raise the version number at all!!! if (_ddl_desc && _ddl_desc->getHeader() && bFoundEnums) { if (_ddl_desc->getHeader()->getLanguageVersion() < DDLVersion::ddl_version_20) { _ddl_desc->getHeader()->setLanguageVersion(DDLVersion::ddl_version_20); } } if (_dom.findNode("//units", oTmpElement)) { RETURN_IF_FAILED(buildUnits()); bValidElementFound = true; } if (_dom.findNode("//datatypes", oTmpElement)) { RETURN_IF_FAILED(buildDatatypes()); bValidElementFound = true; } if (_dom.findNode("//enums", oTmpElement)) { RETURN_IF_FAILED(buildEnums()); bValidElementFound = true; } if (_dom.findNode("//structs", oTmpElement)) { RETURN_IF_FAILED(buildStructs()); bValidElementFound = true; } if (_dom.findNode("//streams", oTmpElement)) { RETURN_IF_FAILED(buildStreams()); bValidElementFound = true; } if (_dom.findNode("//streammetatypes", oTmpElement)) { RETURN_IF_FAILED(buildStreamMetaTypes()); bValidElementFound = true; } _current_ref_ddl = NULL; if (!bValidElementFound) { return ERR_UNKNOWN_FORMAT; } return a_util::result::SUCCESS; } // _current_ref_ddl = NULL; _ddl_desc = DDLDescription::createDefault(version, _creation_level, _sorted); DDLBaseunit * poBUTmp = NULL; if (strElementType == "baseunit") { RETURN_IF_FAILED(buildSingleBaseunit(&poBUTmp, _dom.getRoot())); _ddl_desc->addBaseunit(poBUTmp); return a_util::result::SUCCESS; } DDLPrefix * poPrefixTmp = NULL; if (strElementType == "prefixes") { RETURN_IF_FAILED(buildSinglePrefix(&poPrefixTmp, _dom.getRoot())); _ddl_desc->addPrefix(poPrefixTmp); return a_util::result::SUCCESS; } DDLUnit * poUnitTmp = NULL; if (strElementType == "unit") { RETURN_IF_FAILED(buildSingleUnit(&poUnitTmp, _dom.getRoot())); _ddl_desc->addUnit(poUnitTmp); return a_util::result::SUCCESS; } if (strElementType == "datatype") { DDLDataType * poDTTmp = NULL; RETURN_IF_FAILED(buildSingleDatatype(&poDTTmp, _dom.getRoot())); _ddl_desc->addDatatype(poDTTmp); return a_util::result::SUCCESS; } if (strElementType == "enum") { DDLEnum * poEnumTmp = NULL; RETURN_IF_FAILED(buildSingleEnum(&poEnumTmp, _dom.getRoot())); _ddl_desc->addEnum(poEnumTmp); return a_util::result::SUCCESS; } if (strElementType == "struct") { DDLComplex * poStructTmp = NULL; RETURN_IF_FAILED(buildSingleStruct(&poStructTmp, _dom.getRoot())); _ddl_desc->addStruct(poStructTmp); return a_util::result::SUCCESS; } if (strElementType == "stream") { DDLStream * poStreamTmp = NULL; RETURN_IF_FAILED(buildSingleStream(&poStreamTmp, _dom.getRoot())); _ddl_desc->addStream(poStreamTmp); return a_util::result::SUCCESS; } if (strElementType == "streammetatype") { RETURN_IF_FAILED(buildSingleStreamMetaType(_dom.getRoot(), _ddl_desc->getStreamMetaTypes())); return a_util::result::SUCCESS; } return ERR_UNKNOWN_FORMAT; } a_util::result::Result DDLImporter::buildHeader() { if (!_init_flag) { return ERR_NOT_INITIALIZED; } a_util::xml::DOMElement oHeaderElement; a_util::xml::DOMElement oTmpElement; a_util::result::Result nResult = a_util::result::SUCCESS; if (!_dom.findNode("//header", oHeaderElement)) { pushMessage(std::string("DDL does not contain a header."), importer_error); return ERR_OPEN_FAILED; } else { std::string strVersion = a_util::strings::empty_string; if (!oHeaderElement.findNode("language_version", oTmpElement)) { pushMessage(std::string("DDL does not contain a language_version in header"), importer_error); nResult = ERR_NOT_FOUND; if (false == _full_check) { return nResult; } } else { strVersion = oTmpElement.getData(); a_util::strings::trim(strVersion); } std::string strAuthor = a_util::strings::empty_string; if (!oHeaderElement.findNode("author", oTmpElement)) { pushMessage(std::string("DDL does not contain an author in header."), importer_error); nResult = ERR_NOT_FOUND; if (false == _full_check) { return nResult; } } else { strAuthor = oTmpElement.getData(); } a_util::datetime::Date sDateCreation(1900, 1, 1); if (!oHeaderElement.findNode("date_creation", oTmpElement)) { pushMessage(std::string("DDL does not contain a creation date in header."), importer_error); nResult = ERR_NOT_FOUND; if (false == _full_check) { return nResult; } } else { sDateCreation = DDLHeader::dateFromString(oTmpElement.getData()); } a_util::datetime::Date sDateChange(1900, 1, 1); if (!oHeaderElement.findNode("date_change", oTmpElement)) { pushMessage(std::string("DDL does not contain a change date in header."), importer_error); nResult = ERR_NOT_FOUND; if (false == _full_check) { return nResult; } } else { sDateChange = DDLHeader::dateFromString(oTmpElement.getData()); } std::string strDescription = a_util::strings::empty_string; if (!oHeaderElement.findNode("description", oTmpElement)) { pushMessage(std::string("DDL does not contain a description in header."), importer_error); nResult = ERR_NOT_FOUND; if (false == _full_check) { return nResult; } } else { strDescription = oTmpElement.getData(); } // do not continue with header, if any header property could not found (all properties are mandatory!) if (isFailed(nResult)) { DDLExtDeclarationVec vecExtDecls; _ddl_desc = new DDLDescription(new DDLHeader(DDLVersion::fromString(strVersion), strAuthor, sDateCreation, sDateChange, strDescription, vecExtDecls), DDLUnitVec(_sorted), DDLBaseunitVec(_sorted), DDLPrefixVec(_sorted), DDLDTVec(_sorted), DDLComplexVec(_sorted), DDLStreamVec(_sorted), DDLEnumVec(_sorted), _merge_defaults); return nResult; } a_util::xml::DOMElementList oExtDeclarations; oHeaderElement.findNodes("ext_declaration", oExtDeclarations); DDLExtDeclarationVec vecExtDecls; for (tDOMElemIt it = oExtDeclarations.begin(); oExtDeclarations.end() != it; ++it) { a_util::result::Result nRes; if (!it->hasAttribute("key")) { pushMessage(std::string("There is an external declaration without key in header."), importer_error); nRes = ERR_UNKNOWN_FORMAT; if (false == _full_check) { return nRes; } } else { if (!it->hasAttribute("value")) { pushMessage(a_util::strings::format("The external declaration with key '%s' has no value.", it->getAttribute("key").c_str()), importer_error); nRes = ERR_UNKNOWN_FORMAT; if (false == _full_check) { return nRes; } } } if (!it->hasAttribute("value")) { pushMessage(std::string("There is an external declaration without value in header."), importer_error); nRes = ERR_UNKNOWN_FORMAT; if (false == _full_check) { return nRes; } } if (isFailed(nRes)) { nResult = nRes; if (false == _full_check) { return nResult; } // do not create new DDLExtDeclaration, if any key property could not found (all properties are mandatory!) continue; } vecExtDecls.push_back(new DDLExtDeclaration(it->getAttribute("key"), it->getAttribute("value"))); } _ddl_desc = new DDLDescription(new DDLHeader(DDLVersion::fromString(strVersion), strAuthor, sDateCreation, sDateChange, strDescription, vecExtDecls), DDLUnitVec(_sorted), DDLBaseunitVec(_sorted), DDLPrefixVec(_sorted), DDLDTVec(_sorted), DDLComplexVec(_sorted), DDLStreamVec(_sorted), DDLEnumVec(_sorted), _merge_defaults); if (isFailed(nResult)) { return nResult; } } return a_util::result::SUCCESS; } a_util::result::Result DDLImporter::buildSingleBaseunit(DDLBaseunit ** ppoNewBU, const a_util::xml::DOMElement& oBUElement) { if (!ppoNewBU) { return ERR_POINTER; } *ppoNewBU = NULL; std::string name = oBUElement.getAttribute("name"); a_util::result::Result nResult = a_util::result::SUCCESS; if (!oBUElement.hasAttribute("name")) { pushMessage(a_util::strings::format("Attribute 'name' is missing in 'baseunit' tag."), importer_error); nResult = ERR_UNKNOWN_FORMAT; if (false == _full_check) { return nResult; } } if (!oBUElement.hasAttribute("symbol")) { if (!name.empty()) { pushMessage(a_util::strings::format("Attribute 'symbol' is missing in 'baseunit' tag '%s'.", name.c_str()), importer_error); } else { pushMessage(a_util::strings::format("Attribute 'symbol' is missing in 'baseunit' tag."), importer_error); } nResult = ERR_UNKNOWN_FORMAT; if (false == _full_check) { return nResult; } } if (!oBUElement.hasAttribute("description")) { if (!name.empty()) { pushMessage(a_util::strings::format("Attribute 'description' is missing in 'baseunit' tag '%s'.", name.c_str()), importer_error); } else { pushMessage(a_util::strings::format("Attribute 'description' is missing in 'baseunit' tag."), importer_error); } nResult = ERR_UNKNOWN_FORMAT; if (false == _full_check) { return nResult; } } // do not create new DDLBaseunit, if any base unit property could not found (all properties are mandatory!) if (isFailed(nResult)) { return nResult; } *ppoNewBU = new DDLBaseunit(oBUElement.getAttribute("name"), oBUElement.getAttribute("symbol"), oBUElement.getAttribute("description"), _creation_level); return a_util::result::SUCCESS; } a_util::result::Result DDLImporter::buildSinglePrefix(DDLPrefix ** ppoNewPrefix, const a_util::xml::DOMElement& oPrefixElement) { if (!ppoNewPrefix) { return ERR_POINTER; } *ppoNewPrefix = NULL; std::string name = oPrefixElement.getAttribute("name"); a_util::result::Result nResult = a_util::result::SUCCESS; if (!oPrefixElement.hasAttribute("name")) { pushMessage(a_util::strings::format("Attribute 'name' is missing in 'prefix' tag."), importer_error); nResult = ERR_UNKNOWN_FORMAT; if (false == _full_check) { return nResult; } } if (!oPrefixElement.hasAttribute("symbol")) { if (!name.empty()) { pushMessage(a_util::strings::format("Attribute 'symbol' is missing in 'prefix' tag '%s'.", name.c_str()), importer_error); } else { pushMessage(a_util::strings::format("Attribute 'symbol' is missing in 'prefix' tag."), importer_error); } nResult = ERR_UNKNOWN_FORMAT; if (false == _full_check) { return nResult; } } if (!oPrefixElement.hasAttribute("power")) { if (!name.empty()) { pushMessage(a_util::strings::format("Attribute 'power' is missing in 'prefix' tag '%s'.", name.c_str()), importer_error); } else { pushMessage(a_util::strings::format("Attribute 'power' is missing in 'prefix' tag."), importer_error); } nResult = ERR_UNKNOWN_FORMAT; if (false == _full_check) { return nResult; } } // do not create new DDLPrefix, if any prefix property could not found (all properties are mandatory!) if (isFailed(nResult)) { return nResult; } *ppoNewPrefix = new DDLPrefix(oPrefixElement.getAttribute("name"), oPrefixElement.getAttribute("symbol"), a_util::strings::toInt32(oPrefixElement.getAttribute("power")), _creation_level); return a_util::result::SUCCESS; } a_util::result::Result DDLImporter::buildSingleUnit(DDLUnit ** ppoNewUnit, const a_util::xml::DOMElement& oUnitElement) { if (!ppoNewUnit) { return ERR_POINTER; } *ppoNewUnit = NULL; DDLBaseunitVec vecDDLBaseunits = _ddl_desc->getBaseunits(); DDLPrefixVec vecDDLPrefixes = _ddl_desc->getPrefixes(); DDLUnitVec vecDDLUnits = _ddl_desc->getUnits(); DDLBaseunitVec vecDDLBaseunitRefs; DDLPrefixVec vecDDLPrefixeRefs; DDLUnitVec vecDDLUnitRefs; if (_current_ref_ddl != NULL) { vecDDLUnitRefs = _current_ref_ddl->getUnits(); vecDDLPrefixeRefs = _current_ref_ddl->getPrefixes(); vecDDLBaseunitRefs = _current_ref_ddl->getBaseunits(); } a_util::result::Result nResult = a_util::result::SUCCESS; std::string name = oUnitElement.getAttribute("name"); if (name.empty()) { pushMessage(a_util::strings::format("Attribute 'name' is missing in 'unit' tag."), importer_error); nResult = ERR_UNKNOWN_FORMAT; if (false == _full_check) { return nResult; } } a_util::xml::DOMElement oTmpElement; std::string strNumerator = a_util::strings::empty_string; if (!oUnitElement.findNode("numerator", oTmpElement)) { if (!name.empty()) { pushMessage(a_util::strings::format("Attribute 'numerator' is missing in 'unit' tag '%s'.", name.c_str()), importer_error); } else { pushMessage(a_util::strings::format("Attribute 'numerator' is missing in 'unit' tag."), importer_error); } nResult = ERR_UNKNOWN_FORMAT; if (false == _full_check) { return nResult; } } else { strNumerator = oTmpElement.getData(); } std::string strDenominator = a_util::strings::empty_string; if (!oUnitElement.findNode("denominator", oTmpElement)) { if (!name.empty()) { pushMessage(a_util::strings::format("Attribute 'denominator' is missing in 'unit' tag '%s'.", name.c_str()), importer_error); } else { pushMessage(a_util::strings::format("Attribute 'denominator' is missing in 'unit' tag."), importer_error); } nResult = ERR_UNKNOWN_FORMAT; if (false == _full_check) { return nResult; } } else { strDenominator = oTmpElement.getData(); } double fOffset = 0.0F; if (!oUnitElement.findNode("offset", oTmpElement)) { if (!name.empty()) { pushMessage(a_util::strings::format("Attribute 'offset' is missing in 'unit' tag '%s'.", name.c_str()), importer_error); } else { pushMessage(a_util::strings::format("Attribute 'offset' is missing in 'unit' tag."), importer_error); } nResult = ERR_UNKNOWN_FORMAT; if (false == _full_check) { return nResult; } } else { fOffset = static_cast (a_util::strings::toDouble(oTmpElement.getData())); } a_util::xml::DOMElementList oRefUnits; oUnitElement.findNodes("refUnit", oRefUnits); DDLRefUnitVec vecDDLRefUnits; a_util::result::Result nRes = a_util::result::SUCCESS; for (tDOMElemIt itRU = oRefUnits.begin(); oRefUnits.end() != itRU; ++itRU) { std::string strRefUnitName = a_util::strings::empty_string; if (itRU->hasAttribute("name")) { strRefUnitName = itRU->getAttribute("name"); } nRes = a_util::result::SUCCESS; if (!itRU->hasAttribute("name") || !itRU->hasAttribute("power") || !itRU->hasAttribute("prefix")) { std::transform(vecDDLRefUnits.begin(), vecDDLRefUnits.end(), vecDDLRefUnits.begin(), DDLDescription::deleteChild); if (!itRU->hasAttribute("name")) { pushMessage(a_util::strings::format("Attribute 'name' is missing in 'refUnit' tag."), importer_error); nRes = ERR_UNKNOWN_FORMAT; if (false == _full_check) { return nRes; } } if (!itRU->hasAttribute("power")) { if (!strRefUnitName.empty()) { pushMessage(a_util::strings::format("Attribute 'power' is missing in 'refUnit' tag '%s'.", strRefUnitName.c_str()), importer_error); } else { pushMessage(a_util::strings::format("Attribute 'power' is missing in 'refUnit' tag."), importer_error); } nRes = ERR_UNKNOWN_FORMAT; if (false == _full_check) { return nRes; } } if (!itRU->hasAttribute("prefix")) { if (!strRefUnitName.empty()) { pushMessage(a_util::strings::format("Attribute 'prefix' is missing in 'refUnit' tag '%s'.", strRefUnitName.c_str()), importer_error); } else { pushMessage(a_util::strings::format("Attribute 'prefix' is missing in 'refUnit' tag."), importer_error); } nRes = ERR_UNKNOWN_FORMAT; if (false == _full_check) { return nRes; } } if (isFailed(nRes)) { nResult = nRes; if (false == _full_check) { return nRes; } // do not continue with this ref unit, if any property could not found (all properties are mandatory!) continue; } } DDLPrefix* pPrefix = tryToFind(itRU->getAttribute("prefix"), vecDDLPrefixeRefs, vecDDLPrefixes ); if (pPrefix == NULL) { // not found in prefixes vector => not defined if (!name.empty() && !strRefUnitName.empty()) { pushMessage(a_util::strings::format("RefUnit '%s' in unit '%s' references to unknown prefix '%s'", strRefUnitName.c_str(), name.c_str(), itRU->getAttribute("prefix").c_str()), importer_error); } else if (!name.empty()) { pushMessage(a_util::strings::format("RefUnit in unit '%s' references to unknown prefix '%s'", name.c_str(), itRU->getAttribute("prefix").c_str()), importer_error); } else { pushMessage(a_util::strings::format("RefUnit in unit references to unknown prefix '%s'", itRU->getAttribute("prefix").c_str()), importer_error); } std::transform(vecDDLRefUnits.begin(), vecDDLRefUnits.end(), vecDDLRefUnits.begin(), DDLDescription::deleteChild); nRes = ERR_NO_CLASS; if (false == _full_check) { return nRes; } } std::string strAttr = itRU->getAttribute("name"); DDLBaseunit* pBaseUnit = tryToFind(strAttr, vecDDLBaseunitRefs, vecDDLBaseunits); if (pBaseUnit == NULL) { DDLUnit* pUnit = tryToFind(strAttr, vecDDLUnitRefs, vecDDLUnits); if (pUnit == NULL) { pUnit = tryToFind(strAttr, _unknown_units, vecDDLUnits); if (pUnit == NULL) { // => create placeholder object, mark Unit object // as unknown, and continue pUnit = new DDLUnit(strAttr, "1", "1", 0.0f); _unknown_units.insert(pUnit); vecDDLRefUnits.push_back(new DDLRefUnit(pUnit, a_util::strings::toInt32(itRU->getAttribute("power")), pPrefix)); } else { // already marked as unknown vecDDLRefUnits.push_back(new DDLRefUnit(pUnit, a_util::strings::toInt32(itRU->getAttribute("power")), pPrefix)); } } else { // known Unit vecDDLRefUnits.push_back(new DDLRefUnit(pUnit, a_util::strings::toInt32(itRU->getAttribute("power")), pPrefix)); } } else { vecDDLRefUnits.push_back(new DDLRefUnit(pBaseUnit, a_util::strings::toInt32(itRU->getAttribute("power")), pPrefix)); } if (isFailed(nRes)) { nResult = nRes; if (false == _full_check) { return nResult; } } } // do not create new DDLUnit, if any unit property could not found (all properties are mandatory!) if (isFailed(nResult)) { return nResult; } DDLUnitIt itUnknown = std::find_if(_unknown_units.begin(), _unknown_units.end(), DDLCompareFunctor<>(name)); if (_unknown_units.end() == itUnknown) { // create new object *ppoNewUnit = new DDLUnit(name, strNumerator, strDenominator, fOffset, DDLRefUnitVec(), _creation_level); } else { // use placeholder object (*itUnknown)->create(name, strNumerator, strDenominator, fOffset, DDLRefUnitVec(), _creation_level); *ppoNewUnit = *itUnknown; // unmark object _unknown_units.erase(itUnknown); } (*ppoNewUnit)->setRefUnits(vecDDLRefUnits); return a_util::result::SUCCESS; } a_util::result::Result DDLImporter::buildUnits() { if (!_init_flag) { return ERR_NOT_INITIALIZED; } a_util::xml::DOMElement oUnits; if (!_dom.findNode("//units", oUnits)) { // as units are not supported in ADTF => no error pushMessage(std::string("DDL does not contain the 'units' element."), importer_warning); return a_util::result::SUCCESS; } else { a_util::result::Result nResult = a_util::result::SUCCESS; // build up base-unit objects a_util::xml::DOMElementList oBaseunits; if (!oUnits.findNodes("baseunit", oBaseunits)) { // no error } else { DDLBaseunitVec vecDDLBaseunits(_sorted); a_util::result::Result nRes = a_util::result::SUCCESS; for (tDOMElemIt itBU = oBaseunits.begin(); oBaseunits.end() != itBU; ++itBU) { DDLBaseunit * poBUTmp = NULL; nRes = buildSingleBaseunit(&poBUTmp, *itBU); if (isFailed(nRes)) { vecDDLBaseunits.deleteAll(); nResult = nRes; if (false == _full_check) { return nResult; } continue; } if (_basic_check && vecDDLBaseunits.find(poBUTmp->getName())) { pushMessage(a_util::strings::format("The baseunit '%s' is specified more than once.", poBUTmp->getName().c_str()), importer_error); nResult = ERR_RESOURCE_IN_USE; if (false == _full_check) { return nResult; } } vecDDLBaseunits.insert(poBUTmp); } _ddl_desc->refBaseunits(vecDDLBaseunits); } // build up prefix objects a_util::xml::DOMElementList oPrefixes; if (!oUnits.findNodes("prefixes", oPrefixes)) { // => no error } else { DDLPrefixVec vecDDLPrefixes(_sorted); a_util::result::Result nRes = a_util::result::SUCCESS; for (tDOMElemIt itP = oPrefixes.begin(); oPrefixes.end() != itP; ++itP) { DDLPrefix * poPrefixTmp = NULL; nRes = buildSinglePrefix(&poPrefixTmp, *itP); if (isFailed(nRes)) { vecDDLPrefixes.deleteAll(); nResult = nRes; if (false == _full_check) { return nResult; } continue; } if (_basic_check && vecDDLPrefixes.find(poPrefixTmp->getName())) { pushMessage(a_util::strings::format("The prefix '%s' is specified more than once.", poPrefixTmp->getName().c_str()), importer_error); nResult = ERR_RESOURCE_IN_USE; if (false == _full_check) { return nResult; } } vecDDLPrefixes.insert(poPrefixTmp); } _ddl_desc->refPrefixes(vecDDLPrefixes); } // build up unit objects a_util::xml::DOMElementList oUnitList; if (!oUnits.findNodes("unit", oUnitList)) { // => no error } else { DDLUnitVec vecDDLUnits(_sorted); a_util::result::Result nRes = a_util::result::SUCCESS; _ddl_desc->cloneUnits(vecDDLUnits); for (tDOMElemIt itU = oUnitList.begin(); oUnitList.end() != itU; ++itU) { DDLUnit * poUnitTmp = NULL; nRes = buildSingleUnit(&poUnitTmp, *itU); if (isFailed(nRes)) { nResult = nRes; if (false == _full_check) { return nResult; } continue; } if (_basic_check && _ddl_desc->getUnitByName(poUnitTmp->getName())) { pushMessage(a_util::strings::format("The unit '%s' is specified more than once.", poUnitTmp->getName().c_str()), importer_error); nResult = ERR_RESOURCE_IN_USE; if (false == _full_check) { return nResult; } } _ddl_desc->addUnit(poUnitTmp); } } for (DDLUnitIt itUnknown = _unknown_units.begin(); _unknown_units.end() != itUnknown; ++itUnknown) { pushMessage(a_util::strings::format("The unit '%s' was referenced but not specified.", (*itUnknown)->getName().c_str()), importer_error); nResult = ERR_UNKNOWN; if (false == _full_check) { return nResult; } } if (!_unknown_units.empty()) { std::stringstream logUnspecifiedStructs; logUnspecifiedStructs<< "The following units are unknown in this description: "; for (DDLUnitIt itUnknown = _unknown_units.begin(); _unknown_units.end() != itUnknown; ++itUnknown) { logUnspecifiedStructs << " " << (*itUnknown)->getName(); if (false == _full_check) { logUnspecifiedStructs << "."; pushMessage(logUnspecifiedStructs.str(), importer_error); nResult = ERR_UNKNOWN; return nResult; } logUnspecifiedStructs << ","; } logUnspecifiedStructs.seekp(-1, logUnspecifiedStructs.cur); logUnspecifiedStructs << "."; pushMessage(logUnspecifiedStructs.str(), importer_error); nResult = ERR_UNKNOWN; } if (isFailed(nResult)) { return nResult; } } return a_util::result::SUCCESS; } a_util::result::Result DDLImporter::buildSingleDatatype(DDLDataType ** ppoNewDatatype, const a_util::xml::DOMElement& oDTElement) { if (!ppoNewDatatype) { return ERR_POINTER; } *ppoNewDatatype = NULL; a_util::result::Result nResult = a_util::result::SUCCESS; if (!oDTElement.hasAttribute("size")) { pushMessage(a_util::strings::format("Attribute 'size' is missing in 'datatype' tag."), importer_error); nResult = ERR_UNKNOWN_FORMAT; if (false == _full_check) { return nResult; } } std::string name = a_util::strings::empty_string; if (_ddl_desc->getHeader()->getLanguageVersion() <= DDLVersion::ddl_version_11) { if (!oDTElement.hasAttribute("type")) { if (oDTElement.hasAttribute("name")) { //NF: ADTF ist robust!! name = oDTElement.getAttribute("name"); } else { pushMessage(a_util::strings::format("Attribute 'type' is missing in 'datatype' tag."), importer_error); nResult = ERR_UNKNOWN_FORMAT; if (false == _full_check) { return nResult; } } } else { name = oDTElement.getAttribute("type"); } } else { if (!oDTElement.hasAttribute("name")) { pushMessage(a_util::strings::format("Attribute 'name' is missing in 'datatype' tag."), importer_error); nResult = ERR_UNKNOWN_FORMAT; if (false == _full_check) { return nResult; } } else { name = oDTElement.getAttribute("name"); } } std::string strDescription = a_util::strings::empty_string; if (oDTElement.hasAttribute("description")) { strDescription = oDTElement.getAttribute("description"); } unsigned int uiArraysize = 1; if (oDTElement.hasAttribute("arraysize")) { uiArraysize = static_cast (a_util::strings::toUInt32(oDTElement.getAttribute("arraysize"))); } DDLAlignment::AlignmentType eAlignment = DDLAlignment::e1; if (oDTElement.hasAttribute("alignment")) { eAlignment = DDLAlignment::fromString(oDTElement.getAttribute("alignment")); if (eAlignment == DDLAlignment::e_invalid) { pushMessage(a_util::strings::format("Attribute 'alignment' is out of range in 'datatype' tag '%s'.", name.c_str()), importer_error); nResult = ERR_INVALID_ARG; if (false == _full_check) { return nResult; } } } if (oDTElement.hasAttribute("size")) { std::string s = oDTElement.getAttribute("size"); if (!a_util::strings::isInt32(s) || a_util::strings::toInt32(s) <= 0) { pushMessage(a_util::strings::format("Attribute 'size' is out of range in 'datatype' tag '%s'.", name.c_str()), importer_error); nResult = ERR_UNKNOWN_FORMAT; if (false == _full_check) { return nResult; } } } std::string strMinVal; bool bMinValid = false; if (oDTElement.hasAttribute("min")) { strMinVal = oDTElement.getAttribute("min"); bMinValid = true; } std::string strMaxVal; bool bMaxValid = false; if (oDTElement.hasAttribute("max")) { strMaxVal = oDTElement.getAttribute("max"); bMaxValid = true; } IDDLUnit* pUnitRef = NULL; if (oDTElement.hasAttribute("unit")) { DDLBaseunit* pBaseUnit = NULL; DDLUnit* pUnit = NULL; DDLBaseunitVec vecDDLBaseunits = _ddl_desc->getBaseunits(); DDLUnitVec vecDDLUnits = _ddl_desc->getUnits(); DDLUnitVec vecDDLUnitRefs; DDLBaseunitVec vecDDLBaseunitRefs; if (_current_ref_ddl) { vecDDLBaseunitRefs = _current_ref_ddl->getBaseunits(); vecDDLUnitRefs = _current_ref_ddl->getUnits(); } std::string strAttr = oDTElement.getAttribute("unit"); pBaseUnit = tryToFind(strAttr, vecDDLBaseunitRefs, vecDDLBaseunits); if (pBaseUnit == NULL) { pUnit = tryToFind(strAttr, vecDDLUnitRefs, vecDDLUnits); if (pUnit == NULL) { pushMessage(a_util::strings::format("No 'unit' or 'refUnit' found with name='%s' defined in datatype '%s'.", strAttr.c_str(), name.c_str()), importer_error); nResult = ERR_NO_CLASS; if (false == _full_check) { return nResult; } } else { pUnitRef = (IDDLUnit*) pUnit; } } else { pUnitRef = (IDDLUnit*) pBaseUnit; } } *ppoNewDatatype = new DDLDataType(name, static_cast(a_util::strings::toUInt32(oDTElement.getAttribute("size"))), pUnitRef, strDescription, eAlignment, uiArraysize, _creation_level, a_util::strings::empty_string, bMinValid, strMinVal, bMaxValid, strMaxVal); // Add version information for behavior differentiation DDLVersion language_version = DDLVersion::getDefaultVersion(); DDLHeader* pHeader = _ddl_desc->getHeader(); if (NULL != pHeader) { language_version = pHeader->getLanguageVersion(); } (*ppoNewDatatype)->setDDLVersion(language_version); return a_util::result::SUCCESS; } a_util::result::Result DDLImporter::buildDatatypes() { if (!_init_flag) { return ERR_NOT_INITIALIZED; } a_util::xml::DOMElement oDatatypesNode; a_util::result::Result nResult = a_util::result::SUCCESS; if (!_dom.findNode("//datatypes", oDatatypesNode)) { pushMessage(std::string("DDL does not contain the 'datatypes' element"), importer_error); return ERR_NOT_FOUND; } a_util::xml::DOMElementList oDatatypes; oDatatypesNode.findNodes("datatype", oDatatypes); DDLDTVec vecDDLDataTypes(_sorted); for (tDOMElemIt it = oDatatypes.begin(); oDatatypes.end() != it; ++it) { DDLDataType * poDTTmp = NULL; a_util::result::Result nRes = buildSingleDatatype(&poDTTmp, *it); if (isFailed(nRes)) { vecDDLDataTypes.deleteAll(); nResult = nRes; if (false == _full_check) { return nResult; } continue; } if (_basic_check && vecDDLDataTypes.find(poDTTmp->getName())) { pushMessage(a_util::strings::format("The datatype '%s' is specified more than once.", poDTTmp->getName().c_str()), importer_error); nResult = ERR_RESOURCE_IN_USE; if (false == _full_check) { return nResult; } } vecDDLDataTypes.insert(poDTTmp); } _ddl_desc->refDatatypes(vecDDLDataTypes); if (isFailed(nResult)) { return nResult; } return a_util::result::SUCCESS; } static inline bool CheckAttrib(const a_util::xml::DOMAttributes oAttrs, const std::string& strAttrib, unsigned int& nRes) { a_util::xml::DOMAttributes::const_iterator itAttr = oAttrs.find(strAttrib); if (itAttr != oAttrs.end()) { nRes = a_util::strings::toUInt32(itAttr->second); return true; } return false; } static inline bool CheckAttrib(const a_util::xml::DOMAttributes oAttrs, const std::string& strAttrib, std::string& strRes) { a_util::xml::DOMAttributes::const_iterator itAttr = oAttrs.find(strAttrib); if (itAttr != oAttrs.end()) { strRes = itAttr->second.c_str(); return true; } return false; } a_util::result::Result DDLImporter::buildSingleStruct(DDLComplex ** ppoNewStruct, const a_util::xml::DOMElement& oStructElement) { if (!ppoNewStruct) { return ERR_POINTER; } *ppoNewStruct = NULL; // get already defined types DDLDTVec vecDTs = _ddl_desc->getDatatypes(); DDLComplexVec vecStructs = _ddl_desc->getStructs(); DDLEnumVec vecEnums = _ddl_desc->getEnums(); // get already defined types DDLDTVec vecDTRefs; DDLComplexVec vecStructRefs; DDLEnumVec vecEnumRefs; if (_current_ref_ddl) { vecDTRefs = _current_ref_ddl->getDatatypes(); vecStructRefs = _current_ref_ddl->getStructs(); vecEnumRefs = _current_ref_ddl->getEnums(); } a_util::result::Result nResult = a_util::result::SUCCESS; std::string strStructName = oStructElement.getAttribute("name"); if (!oStructElement.hasAttribute("name")) { strStructName = oStructElement.getAttribute("type"); if (!oStructElement.hasAttribute("type")) { pushMessage(a_util::strings::format("Attribute 'name' is missing in 'struct' tag."), importer_error); nResult = ERR_UNKNOWN_FORMAT; if (false == _full_check) { return nResult; } } } // mandatory property, but no error (compatibility to former DDL versions) std::string strVersion = a_util::strings::empty_string; if (!oStructElement.hasAttribute("version")) { // mandatory property, but no error (compatibility to former DDL versions) } else { strVersion = oStructElement.getAttribute("version"); } std::string strComment = a_util::strings::empty_string; if (oStructElement.hasAttribute("comment")) { strComment = oStructElement.getAttribute("comment"); } DDLAlignment::AlignmentType eAlignment = DDLAlignment::e1; if (oStructElement.hasAttribute("alignment")) { std::string strAttr = oStructElement.getAttribute("alignment"); eAlignment = DDLAlignment::fromString(strAttr); if (eAlignment == DDLAlignment::e_invalid) { pushMessage(a_util::strings::format("The struct '%s' has an invalid alignment of '%s'", strStructName.c_str(), strAttr.c_str()), importer_error); nResult = ERR_INVALID_ARG; if (false == _full_check) { return nResult; } } } a_util::xml::DOMElementList oElements; oStructElement.findNodes("element", oElements); DDLElementVec vecDDLElements; for (tDOMElemIt itElem = oElements.begin(); oElements.end() != itElem; ++itElem) { std::string strElementName; if (itElem->hasAttribute("name")) { strElementName = itElem->getAttribute("name"); } if (_basic_check && std::find_if(vecDDLElements.begin(), vecDDLElements.end(), DDLCompareFunctor(strElementName)) != vecDDLElements.end()) { pushMessage(a_util::strings::format("The struct element name '%s.%s' is already used", strStructName.c_str(), strElementName.c_str()), importer_error); nResult = ERR_RESOURCE_IN_USE; if (false == _full_check) { return nResult; } } // check optional attributes unsigned int uiBitpos = 0; CheckAttrib(itElem->getAttributes(), "bitpos", uiBitpos); unsigned int uiNumBits = 0; CheckAttrib(itElem->getAttributes(), "numbits", uiNumBits); a_util::result::Result nRes = a_util::result::SUCCESS; bool bNoBytePosSet = !itElem->hasAttribute("bytepos"); std::string strBytePos = itElem->getAttribute("bytepos"); bool bNoByteOrderSet = !itElem->hasAttribute("byteorder"); std::string strByteOrder = itElem->getAttribute("byteorder"); bool bNoAlignmentSet = !itElem->hasAttribute("alignment"); std::string strAlignment = itElem->getAttribute("alignment"); a_util::xml::DOMElement oDeserialized; if (itElem->findNode("deserialized", oDeserialized)) { bNoAlignmentSet = !oDeserialized.hasAttribute("alignment"); strAlignment = oDeserialized.getAttribute("alignment"); } a_util::xml::DOMElement oSerialized; if (itElem->findNode("serialized", oSerialized)) { bNoBytePosSet = !oSerialized.hasAttribute("bytepos"); strBytePos = oSerialized.getAttribute("bytepos"); bNoByteOrderSet = !oSerialized.hasAttribute("byteorder"); strByteOrder = oSerialized.getAttribute("byteorder"); CheckAttrib(oSerialized.getAttributes(), "bitpos", uiBitpos); CheckAttrib(oSerialized.getAttributes(), "numbits", uiNumBits); } if (!itElem->hasAttribute("type") || !itElem->hasAttribute("name") || bNoBytePosSet || !itElem->hasAttribute("arraysize") || bNoByteOrderSet || bNoAlignmentSet) { std::transform(vecDDLElements.begin(), vecDDLElements.end(), vecDDLElements.begin(), DDLDescription::deleteChild); if (!itElem->hasAttribute("name")) { pushMessage(a_util::strings::format("Attribute 'name' is missing in 'struct' tag."), importer_error); } if (!itElem->hasAttribute("type")) { if (!strElementName.empty()) { pushMessage(a_util::strings::format("Attribute 'type' is missing in 'struct' tag '%s'.", strElementName.c_str()), importer_error); } else { pushMessage(a_util::strings::format("Attribute 'type' is missing in 'struct' tag."), importer_error); } } if (bNoBytePosSet) { if (!strElementName.empty()) { pushMessage(a_util::strings::format("Attribute 'bytepos' is missing in 'struct' tag '%s'.", strElementName.c_str()), importer_error); } else { pushMessage(a_util::strings::format("Attribute 'bytepos' is missing in 'struct' tag."), importer_error); } } if (!itElem->hasAttribute("arraysize")) { if (!strElementName.empty()) { pushMessage(a_util::strings::format("Attribute 'arraysize' is missing in 'struct' tag '%s'.", strElementName.c_str()), importer_error); } else { pushMessage(a_util::strings::format("Attribute 'arraysize' is missing in 'struct' tag."), importer_error); } } if (bNoByteOrderSet) { if (!strElementName.empty()) { pushMessage(a_util::strings::format("Attribute 'byteorder' is missing in 'struct' tag '%s'.", strElementName.c_str()), importer_error); } else { pushMessage(a_util::strings::format("Attribute 'byteorder' is missing in 'struct' tag."), importer_error); } } if (bNoAlignmentSet) { if (!strElementName.empty()) { pushMessage(a_util::strings::format("Attribute 'alignment' is missing in 'struct' tag '%s'.", strElementName.c_str()), importer_error); } else { pushMessage(a_util::strings::format("Attribute 'alignment' is missing in 'struct' tag."), importer_error); } } nRes = ERR_UNKNOWN_FORMAT; if (false == _full_check) { return nRes; } } if (itElem->getAttribute("type") == strStructName) { std::transform(vecDDLElements.begin(), vecDDLElements.end(), vecDDLElements.begin(), DDLDescription::deleteChild); pushMessage(a_util::strings::format("Unresolvable recursion in struct '%s'.", strStructName.c_str()), importer_error); nRes = ERR_UNKNOWN_FORMAT; if (false == _full_check) { return nRes; } } // resolve type // if the Importer is called with createPartial then the DDL will search for Referenced first // after that it will reference to a local DDL Type or put it to the unresolved types DDLDataType * poDataType = NULL; DDLComplex * poComplex = NULL; DDLEnum* poEnum = NULL; std::string strTypeAttr = itElem->getAttribute("type"); poDataType = tryToFind(strTypeAttr, vecDTRefs, vecDTs); if (poDataType == NULL) { poComplex = tryToFind(strTypeAttr, vecStructRefs, vecStructs); if (poComplex == NULL) { poComplex = tryToFind(strTypeAttr, _unknown_structs, vecStructs); if (poComplex == NULL) { poEnum = tryToFind(strTypeAttr, vecEnumRefs, vecEnums); if(poEnum == NULL) { // => create object, mark it, and continue poComplex = new DDLComplex(strTypeAttr, 1); _unknown_structs.insert(poComplex); } } } } if (_basic_check && itElem->hasAttribute("arraysize")) { if (uiNumBits > 0 && a_util::strings::toInt32(itElem->getAttribute("arraysize")) > 1) { pushMessage(a_util::strings::format("Attribute 'numbits' is not allowed in array elements."), importer_error); return ERR_INVALID_ARG; } } std::string strDescription; CheckAttrib(itElem->getAttributes(), "description", strDescription); std::string strComment; CheckAttrib(itElem->getAttributes(), "comment", strComment); // value is used in combination with enums to implement constants std::string strConstantValue; CheckAttrib(itElem->getAttributes(), "value", strConstantValue); std::string strMinValue; bool bMinValid = CheckAttrib(itElem->getAttributes(), "min", strMinValue); std::string strMaxValue; bool bMaxValid = CheckAttrib(itElem->getAttributes(), "max", strMaxValue); std::string strDefaultValue; bool bDefaultValid = CheckAttrib(itElem->getAttributes(), "default", strDefaultValue); std::string strScaleValue; bool bScaleValid = CheckAttrib(itElem->getAttributes(), "scale", strScaleValue); std::string strOffsetValue; bool bOffsetValid = CheckAttrib(itElem->getAttributes(), "offset", strOffsetValue); // resolve unit // if the Importer is called with createPartial then the DDL will search for Referenced first // after that it will reference to a local DDL Type or put it to the unresolved types DDLUnit* poUnit = NULL; DDLBaseunit* poBaseUnit = NULL; IDDLUnit* pUnitRef = NULL; if (itElem->hasAttribute("unit")) { DDLUnitVec vecDDLUnits = _ddl_desc->getUnits(); DDLUnitVec vecDDLUnitRefs; if (_current_ref_ddl != NULL) { vecDDLUnitRefs = _current_ref_ddl->getUnits(); } DDLBaseunitVec vecDDLBaseUnits = _ddl_desc->getBaseunits(); DDLBaseunitVec vecDDLBaseUnitRefs; if (_current_ref_ddl != NULL) { vecDDLBaseUnitRefs = _current_ref_ddl->getBaseunits(); } std::string strUnitAttr = itElem->getAttribute("unit"); poUnit = tryToFind(strUnitAttr, vecDDLUnitRefs, vecDDLUnits); if (poUnit == NULL) { poBaseUnit = tryToFind(strUnitAttr, vecDDLBaseUnitRefs, vecDDLBaseUnits); if (poBaseUnit != NULL) { pUnitRef = (IDDLUnit*) poBaseUnit; } } else { pUnitRef = (IDDLUnit*) poUnit; } if (pUnitRef == NULL) { std::transform(vecDDLElements.begin(), vecDDLElements.end(), vecDDLElements.begin(), DDLDescription::deleteChild); pushMessage(a_util::strings::format("Missing class '%s' for unit in element '%s' in struct '%s'.", strUnitAttr.c_str(), strElementName.c_str(), strStructName.c_str()), importer_error); nRes = ERR_NO_CLASS; if (false == _full_check) { return nRes; } } } // do not continue with struct, if any mandatory property could not found if (isFailed(nRes)) { nResult = nRes; if (false == _full_check) { return nResult; } continue; } if (DDLAlignment::fromString(strAlignment) == DDLAlignment::e_invalid) { pushMessage(a_util::strings::format("The struct element '%s.%s' has an invalid alignment of '%s'", strStructName.c_str(), strElementName.c_str(), strAlignment.c_str()), importer_error); nResult = ERR_INVALID_ARG; if (false == _full_check) { return nResult; } } const std::string& strArraySize = itElem->getAttribute("arraysize"); if (NULL == poDataType) { if (poEnum != NULL) { bool bIsDynamic = !a_util::strings::isUInt32(strArraySize); vecDDLElements.push_back(new DDLElement(poEnum, strElementName, static_cast(a_util::strings::toUInt32(strBytePos)), bIsDynamic ? 0 : static_cast(a_util::strings::toUInt32(strArraySize)), DDLByteorder::fromString(strByteOrder), DDLAlignment::fromString(strAlignment), pUnitRef, uiBitpos, uiNumBits, strDescription, strComment, bIsDynamic ? strArraySize: a_util::strings::empty_string, strConstantValue)); } else { bool bIsDynamic = !a_util::strings::isUInt32(strArraySize); vecDDLElements.push_back(new DDLElement(poComplex, strElementName, static_cast(a_util::strings::toUInt32(strBytePos)), bIsDynamic ? 0 : static_cast(a_util::strings::toUInt32(strArraySize)), DDLByteorder::fromString(strByteOrder), DDLAlignment::fromString(strAlignment), pUnitRef, uiBitpos, uiNumBits, strDescription, strComment, bIsDynamic ? strArraySize : a_util::strings::empty_string)); } } else { bool bIsDynamic = !a_util::strings::isUInt32(strArraySize); vecDDLElements.push_back(new DDLElement(poDataType, strElementName, static_cast(a_util::strings::toUInt32(strBytePos)), bIsDynamic ? 0 : static_cast(a_util::strings::toUInt32(strArraySize)), DDLByteorder::fromString(strByteOrder), DDLAlignment::fromString(strAlignment), pUnitRef, uiBitpos, uiNumBits, strDescription, strComment, bIsDynamic ? strArraySize : a_util::strings::empty_string, a_util::strings::empty_string, bMinValid, strMinValue, bMaxValid, strMaxValue, bDefaultValid, strDefaultValue, bScaleValid, strScaleValue, bOffsetValid, strOffsetValue)); } } // do not create new DDLComplex, if any mandatory property could not found if (isFailed(nResult)) { return nResult; } DDLComplexIt itUnknown = std::find_if(_unknown_structs.begin(), _unknown_structs.end(), DDLCompareFunctor<>(oStructElement.getAttribute("name"))); if (_unknown_structs.end() == itUnknown) { // create new object *ppoNewStruct = new DDLComplex(strStructName, static_cast(a_util::strings::toUInt32(strVersion)), strComment, eAlignment, DDLElementVec(), _creation_level); } else { // use placeholder object and fill it with concrete data (*itUnknown)->create(strStructName, static_cast(a_util::strings::toUInt32(strVersion)), strComment, eAlignment, DDLElementVec(), _creation_level); *ppoNewStruct = *itUnknown; // unmark object _unknown_structs.erase(itUnknown); } if (oStructElement.hasAttribute("ddlversion")) { auto version = DDLVersion::fromString(oStructElement.getAttribute("ddlversion")); (*ppoNewStruct)->setDDLVersion(version); } else { // Add version information for behavior differentiation DDLVersion language_version = DDLVersion::getDefaultVersion(); DDLHeader* pHeader = _ddl_desc->getHeader(); if (NULL != pHeader) { language_version = pHeader->getLanguageVersion(); } (*ppoNewStruct)->setDDLVersion(language_version); } (*ppoNewStruct)->setElements(vecDDLElements); return a_util::result::SUCCESS; } a_util::result::Result DDLImporter::buildStructs() { if (!_init_flag) { return ERR_NOT_INITIALIZED; } a_util::xml::DOMElement oStructs; a_util::result::Result nResult = a_util::result::SUCCESS; if (!_dom.findNode("//structs", oStructs)) { pushMessage(std::string("DDL does not contain the 'structs' element"), importer_error); return ERR_NOT_FOUND; } else { // build up struct objects a_util::xml::DOMElementList oStructList; if (!oStructs.findNodes("struct", oStructList)) { // => no error } else { DDLComplexVec vecStructs(_sorted); _ddl_desc->cloneStructs(vecStructs); for (tDOMElemIt it = oStructList.begin(); oStructList.end() != it; ++it) { DDLComplex * poStructTmp = NULL; a_util::result::Result nRes = buildSingleStruct(&poStructTmp, *it); if (isFailed(nRes)) { nResult = nRes; if (false == _full_check) { return nResult; } continue; } if (_basic_check && vecStructs.find(poStructTmp->getName())) { pushMessage(a_util::strings::format("The struct '%s' is specified more than once.", poStructTmp->getName().c_str()), importer_error); nResult = ERR_RESOURCE_IN_USE; if (false == _full_check) { return nResult; } } _ddl_desc->addStruct(poStructTmp); } for (DDLComplexIt itUnknown = _unknown_structs.begin(); _unknown_structs.end() != itUnknown; ++itUnknown) { pushMessage(a_util::strings::format("The struct '%s' was referenced but not defined.", (*itUnknown)->getName().c_str()), importer_error); } if (!_unknown_structs.empty()) { vecStructs.deleteAll(); // unmark object pushMessage(std::string("There are undefined types/structs in this description."), importer_error); nResult = ERR_UNKNOWN; if (false == _full_check) { return nResult; } } } if (isFailed(nResult)) { return nResult; } } return a_util::result::SUCCESS; } a_util::result::Result DDLImporter::buildSingleStream(DDLStream ** ppoNewStream, a_util::xml::DOMElement oStreamElement) { if (!ppoNewStream) { return ERR_POINTER; } *ppoNewStream = NULL; std::string name = a_util::strings::empty_string; a_util::result::Result nResult = a_util::result::SUCCESS; if (!oStreamElement.hasAttribute("name")) { if (!oStreamElement.hasAttribute("type")) { pushMessage(a_util::strings::format("Attribute 'name' is missing in 'stream' tag."), importer_error); nResult = ERR_UNKNOWN_FORMAT; if (false == _full_check) { return nResult; } } else { // compatibility with old versions oStreamElement.setAttribute("name", oStreamElement.getAttribute("type")); name = oStreamElement.getAttribute("type"); } } else { name = oStreamElement.getAttribute("name"); } // resolve type DDLComplexVec vecStructs = _ddl_desc->getStructs(); DDLComplexVec vecStructRefs; if (_current_ref_ddl) { vecStructRefs = _current_ref_ddl->getStructs(); } DDLComplex* pTypeFound = tryToFind(oStreamElement.getAttribute("type"), vecStructRefs , vecStructs); if (pTypeFound == NULL) { if (!name.empty()) { pushMessage(a_util::strings::format("The type '%s' of the stream '%s' is not defined.", oStreamElement.getAttribute("type").c_str(), name.c_str()), importer_error); } else { pushMessage(a_util::strings::format("The type '%s' of an unnamed stream is not defined.", oStreamElement.getAttribute("type").c_str()), importer_error); } nResult = ERR_NO_CLASS; if (false == _full_check) { return nResult; } } // check optional attribute std::string strDescription = a_util::strings::empty_string; if (oStreamElement.hasAttribute("description")) { strDescription = oStreamElement.getAttribute("description"); } a_util::xml::DOMElementList oStructs; oStreamElement.findNodes("struct", oStructs); DDLStreamStructVec vecDDLStreamStructs; for (tDOMElemIt itStruct = oStructs.begin(); oStructs.end() != itStruct; ++itStruct) { std::string strElementName = itStruct->getAttribute("name"); a_util::result::Result nRes = a_util::result::SUCCESS; if (!itStruct->hasAttribute("type") || !itStruct->hasAttribute("bytepos")) { std::transform(vecDDLStreamStructs.begin(), vecDDLStreamStructs.end(), vecDDLStreamStructs.begin(), DDLDescription::deleteChild); if (!strElementName.empty() && !name.empty()) { pushMessage(a_util::strings::format("The struct '%s' in stream '%s' is missing required attributes (type/bytepos).", strElementName.c_str(), name.c_str()), importer_error); } else if (!name.empty()) { pushMessage(a_util::strings::format("An unnamed struct in stream '%s' is missing required attributes (type/bytepos).", name.c_str()), importer_error); } else { pushMessage(a_util::strings::format("An unnamed struct in an unnamed stream is missing required attributes (type/bytepos)."), importer_error); } nRes = ERR_UNKNOWN_FORMAT; if (false == _full_check) { return nRes; } } // resolve type DDLComplex* pStreamStructType = tryToFind(itStruct->getAttribute("type"), vecStructRefs , vecStructs); if (pStreamStructType == NULL) { std::transform(vecDDLStreamStructs.begin(), vecDDLStreamStructs.end(), vecDDLStreamStructs.begin(), DDLDescription::deleteChild); pushMessage(a_util::strings::format("The type '%s' of a struct of stream '%s' is not defined.", itStruct->getAttribute("type").c_str(), name.c_str()), importer_error); nRes = ERR_NO_CLASS; if (false == _full_check) { return nRes; } } // check optional attribute std::string strStructName = pStreamStructType->getName(); if (itStruct->hasAttribute("name")) { strStructName = itStruct->getAttribute("name"); } // do not continue with stream struct, if any mandatory property could not found if (isFailed(nRes)) { nResult = nRes; if (false == _full_check) { return nResult; } continue; } vecDDLStreamStructs.push_back(new DDLStreamStruct(pStreamStructType, static_cast(a_util::strings::toUInt32(itStruct->getAttribute("bytepos"))), strStructName)); } // do not create new DDLStream, if any mandatory property could not found if (isFailed(nResult)) { return nResult; } *ppoNewStream = new DDLStream(pTypeFound, name, strDescription, DDLStreamStructVec(), _creation_level); // Add version information for behavior differentiation DDLVersion language_version = DDLVersion::ddl_version_invalid; DDLHeader* pHeader = _ddl_desc->getHeader(); if (NULL != pHeader) { language_version = pHeader->getLanguageVersion(); } (*ppoNewStream)->setDDLVersion(language_version); (*ppoNewStream)->refStructs(vecDDLStreamStructs); return a_util::result::SUCCESS; } a_util::result::Result DDLImporter::buildStreams() { if (!_init_flag) { return ERR_NOT_INITIALIZED; } a_util::xml::DOMElement oStreams; a_util::result::Result nResult = a_util::result::SUCCESS; if (!_dom.findNode("//streams", oStreams)) { pushMessage(std::string("DDL does not contain the 'streams' element"), importer_error); return nResult; } else { a_util::xml::DOMElementList oStreamList; DDLStreamVec vecStreams(_sorted); if (!oStreams.findNodes("stream", oStreamList)) { // => no error } else { for (tDOMElemIt it = oStreamList.begin(); oStreamList.end() != it; ++it) { DDLStream * poStreamTmp = NULL; a_util::result::Result nRes = buildSingleStream(&poStreamTmp, *it); if (isFailed(nRes)) { vecStreams.deleteAll(); nResult = nRes; if (isFailed(nResult)) { return nResult; } continue; } if (_basic_check && vecStreams.find(poStreamTmp->getName())) { pushMessage(a_util::strings::format("The stream '%s' is specified more than once.", poStreamTmp->getName().c_str()), importer_error); nResult = ERR_RESOURCE_IN_USE; if (false == _full_check) { return nResult; } } vecStreams.insert(poStreamTmp); } // make all elements of stream vector unique _ddl_desc->refStreams(vecStreams); } if (isFailed(nResult)) { return nResult; } } return a_util::result::SUCCESS; } void DDLImporter::pushMessage(const std::string& strMsg, ImporterMsgSeverity severity) { ImporterMsg sError = {strMsg, severity}; _errors.push_back(sError); } template T* DDLImporter::tryToFind(const std::string& name, DDLContainer& first_data, DDLContainer& second_data) { T* pRes = NULL; if (_prefere_reference) { pRes = first_data.find(name); if (!pRes) { pRes = second_data.find(name); } } else { pRes = second_data.find(name); if (!pRes) { pRes = first_data.find(name); } } return pRes; } a_util::result::Result DDLImporter::buildEnums() { if (!_init_flag) { return ERR_NOT_INITIALIZED; } a_util::xml::DOMElement oEnums; if (!_dom.findNode("//enums", oEnums)) { //kompatibilit�t zu alten files!! if (_ddl_desc->getHeader()->getLanguageVersion() < DDLVersion::ddl_version_20) { return a_util::result::SUCCESS; } else { pushMessage(std::string("DDL does not contain the 'enums' element."), importer_warning); } return a_util::result::SUCCESS; } else { a_util::result::Result nResult = a_util::result::SUCCESS; // build up enum objects a_util::xml::DOMElementList oEnumList; if (!oEnums.findNodes("enum", oEnumList)) { // => no error } else { DDLEnumVec vecDDLEnums(_sorted); for (tDOMElemIt it = oEnumList.begin(); oEnumList.end() != it; ++it) { DDLEnum * poEnumTmp = NULL; a_util::result::Result nRes = buildSingleEnum(&poEnumTmp, *it); if (isFailed(nRes)) { vecDDLEnums.deleteAll(); nResult = nRes; if (false == _full_check) { return nResult; } continue; } vecDDLEnums.insert(poEnumTmp); } _ddl_desc->refEnums(vecDDLEnums); } if (isFailed(nResult)) { return nResult; } } return a_util::result::SUCCESS; } a_util::result::Result DDLImporter::buildSingleEnum( DDLEnum** ppoNewEnum, const a_util::xml::DOMElement& oEnumElement ) { if (!ppoNewEnum) { return ERR_POINTER; } *ppoNewEnum = NULL; std::string name = oEnumElement.getAttribute("name"); a_util::result::Result nResult = a_util::result::SUCCESS; if (!oEnumElement.hasAttribute("name")) { pushMessage(a_util::strings::format("Attribute 'name' is missing in 'enum' tag."), importer_error); nResult = ERR_UNKNOWN_FORMAT; if (false == _full_check) { return nResult; } } std::string strType; if (!oEnumElement.hasAttribute("type")) { if (!name.empty()) { pushMessage(a_util::strings::format("Attribute 'type' is missing in 'constant' tag '%s'.", name.c_str()), importer_error); } else { pushMessage(a_util::strings::format("Attribute 'type' is missing in 'constant' tag."), importer_error); } nResult = ERR_UNKNOWN_FORMAT; if (false == _full_check) { return nResult; } } else { strType = oEnumElement.getAttribute("type"); } // do not continue with enum, if any enum property could not found (all properties are mandatory!) if (isFailed(nResult)) { return nResult; } EnumNameValueVec vecNameValues; a_util::xml::DOMElementList oEnumElements; oEnumElement.findNodes("element", oEnumElements); a_util::result::Result nRes = a_util::result::SUCCESS; for (a_util::xml::DOMElementList::iterator itEnumElement = oEnumElements.begin(); itEnumElement != oEnumElements.end(); ++itEnumElement) { nRes = a_util::result::SUCCESS; std::string strElementName; if(!itEnumElement->hasAttribute("name")) { pushMessage(a_util::strings::format("Attribute 'name' is missing in 'enum/element' tag."), importer_error); nRes = ERR_UNKNOWN_FORMAT; if (false == _full_check) { return nRes; } } else { strElementName = itEnumElement->getAttribute("name"); } std::string strElementValue; if(!itEnumElement->hasAttribute("value")) { if (!name.empty() && !strElementName.empty()) { pushMessage(a_util::strings::format("No 'value' defined in 'enum/element' tag '%s/%s'.", name.c_str(), strElementName.c_str()), importer_error); } else if (!strElementName.empty()) { pushMessage(a_util::strings::format("No 'value' defined in 'enum/element' tag '%s'.", strElementName.c_str()), importer_error); } else { pushMessage(a_util::strings::format("No 'value' defined in 'enum/element' tag."), importer_error); } nRes = ERR_UNKNOWN_FORMAT; if (false == _full_check) { return nRes; } } else { strElementValue = itEnumElement->getAttribute("value"); } if (isFailed(nRes)) { nResult = nRes; if (false == _full_check) { return nResult; } continue; } vecNameValues.push_back(std::make_pair(std::string(strElementName), std::string(strElementValue))); } // do not continue with enum, if any enum element property could not found (all properties are mandatory!) if (isFailed(nResult)) { return nResult; } // get already defined types DDLDTVec vecDTs = _ddl_desc->getDatatypes(); // get already defined types DDLDTVec vecDTRefs; if (_current_ref_ddl) { vecDTRefs = _current_ref_ddl->getDatatypes(); } DDLDataType * poDataType = NULL; poDataType = tryToFind(strType, vecDTRefs, vecDTs); if (poDataType == NULL) { pushMessage(a_util::strings::format("Data type '%s' could not be resolved.", strType.c_str()), importer_error); nResult = ERR_UNKNOWN_FORMAT; if (false == _full_check) { return nResult; } } // do not create new DDLEnum, if any enum property could not found (all properties are mandatory!) if (isFailed(nResult)) { return nResult; } *ppoNewEnum = new DDLEnum(poDataType, name, vecNameValues, NULL, _creation_level); return a_util::result::SUCCESS; } a_util::result::Result DDLImporter::buildStreamMetaTypes() { if (!_init_flag) { return ERR_NOT_INITIALIZED; } a_util::xml::DOMElement oTypes; if (!_dom.findNode("//streammetatypes", oTypes)) { return a_util::result::SUCCESS; } a_util::result::Result nResult = a_util::result::SUCCESS; // build up stream meta type objects a_util::xml::DOMElementList oTypeList; if (oTypes.findNodes("streammetatype", oTypeList)) { DDLStreamMetaTypeVec vecDDLStreamMetaTypes(_sorted); for (a_util::xml::DOMElementList::iterator it = oTypeList.begin(); it != oTypeList.end(); ++it) { a_util::result::Result nRes = buildSingleStreamMetaType(*it, vecDDLStreamMetaTypes); if (isFailed(nRes)) { nResult = nRes; if (false == _full_check) { vecDDLStreamMetaTypes.deleteAll(); return nRes; } continue; } } for (DDLStreamMetaTypeVec::iterator it = _unknown_stream_meta_types.begin(); it != _unknown_stream_meta_types.end(); ++it) { pushMessage(a_util::strings::format("The struct '%s' was referenced but not defined.", (*it)->getName().c_str()), importer_error); } if (!_unknown_stream_meta_types.empty()) { vecDDLStreamMetaTypes.deleteAll(); // unmark object pushMessage(std::string("There are undefined streammetatypes in this description."), importer_error); nResult = ERR_UNKNOWN; if (false == _full_check) { return nResult; } } _ddl_desc->refStreamMetaTypes(vecDDLStreamMetaTypes); } return nResult; } a_util::result::Result DDLImporter::buildSingleStreamMetaType(const a_util::xml::DOMElement& oStreamMetaTypeElement, DDLStreamMetaTypeVec& vecStreamMetaTypes) { const a_util::xml::DOMAttributes oAttributes = oStreamMetaTypeElement.getAttributes(); a_util::xml::DOMAttributes::const_iterator itName = oAttributes.find("name"); a_util::xml::DOMAttributes::const_iterator itVersion = oAttributes.find("version"); a_util::xml::DOMAttributes::const_iterator itParent = oAttributes.find("parent"); if (itName == oAttributes.end()) { pushMessage(a_util::strings::format("Attribute 'name' is missing in 'streammetatype' tag."), importer_error); return ERR_UNKNOWN_FORMAT; } if (itVersion == oAttributes.end()) { pushMessage(a_util::strings::format("Attribute 'version' is missing in 'streammetatype' tag."), importer_error); return ERR_UNKNOWN_FORMAT; } a_util::result::Result nResult = a_util::result::SUCCESS; DDLStreamMetaType* pParent = NULL; if (itParent != oAttributes.end() && !itParent->second.empty()) { if (_current_ref_ddl) { pParent = const_cast(_current_ref_ddl->getStreamMetaTypeByName(itParent->second)); } if (!pParent) { pParent = tryToFind(itParent->second, _unknown_stream_meta_types, vecStreamMetaTypes); if (!pParent) { pParent = new DDLStreamMetaType(itParent->second, "1"); _unknown_stream_meta_types.insert(pParent); } } } DDLPropertyVec oProps; a_util::xml::DOMElementList oPropertyNodes; if (oStreamMetaTypeElement.findNodes("property", oPropertyNodes)) { for (a_util::xml::DOMElementList::const_iterator it = oPropertyNodes.begin(); it != oPropertyNodes.end(); ++it) { a_util::xml::DOMAttributes attrs = it->getAttributes(); a_util::xml::DOMAttributes::const_iterator itName = attrs.find("name"); a_util::xml::DOMAttributes::const_iterator itType = attrs.find("type"); if (itName != attrs.end() && itType != attrs.end()) { oProps.push_back(new DDLProperty(itName->second, itType->second)); } } } a_util::memory::unique_ptr pStreamMetaType(new DDLStreamMetaType(itName->second, itVersion->second, oProps, pParent)); DDLStreamMetaTypeVec::iterator itUnknown = std::find_if(_unknown_stream_meta_types.begin(), _unknown_stream_meta_types.end(), DDLCompareFunctor<>(itName->second)); if (itUnknown != _unknown_stream_meta_types.end()) { *(*itUnknown) = *pStreamMetaType.get(); vecStreamMetaTypes.insert(*itUnknown); _unknown_stream_meta_types.erase(itUnknown); } else { vecStreamMetaTypes.insert(pStreamMetaType.release()); } return nResult; } } // namespace ddl