#include "OdaCommon.h" #include "NwXmlToSearch.h" #include "tinyxml/tinyxml.h" #include "NwDataType.h" #include "PropertyTree/NwVariantUtils.h" #include "PropertyTree/NwPropertyTree.h" #include "NwVariant.h" #define STL_USING_MAP #include "OdaSTL.h" #include "NwName.h" NwDataType::Enum strToDataType(const char* dt) { const std::map StrToDataType = { { "float", NwDataType::dt_DOUBLE }, { "int32", NwDataType::dt_INT32 }, { "bool", NwDataType::dt_BOOL }, { "wstring", NwDataType::dt_DISPLAY_STRING }, { "time", NwDataType::dt_DATETIME }, { "linear", NwDataType::dt_DOUBLE_LENGTH }, { "angle", NwDataType::dt_DOUBLE_ANGLE }, { "name", NwDataType::dt_NAME }, { "string", NwDataType::dt_IDENTIFIER_STRING }, { "area", NwDataType::dt_DOUBLE_AREA }, { "volume", NwDataType::dt_DOUBLE_VOLUME } }; if (dt) { auto it = StrToDataType.find(dt); if (it != StrToDataType.end()) { return it->second; } } return NwDataType::dt_INT32; } NwSelectionFindConditionType::Enum strToFindCondType(const char* ct) { const std::map StrToFindCondType = { { "never", NwSelectionFindConditionType::Enum::NEVER }, { "attrib", NwSelectionFindConditionType::Enum::ATTRIB }, { "no_attrib", NwSelectionFindConditionType::Enum::NO_ATTRIB }, { "prop", NwSelectionFindConditionType::Enum::PROP }, { "no_prop", NwSelectionFindConditionType::Enum::NO_PROP }, { "same_type", NwSelectionFindConditionType::Enum::SAME_TYPE }, { "equals", NwSelectionFindConditionType::Enum::EQUALS }, { "not_equals", NwSelectionFindConditionType::Enum::NOT_EQUALS }, { "less_than", NwSelectionFindConditionType::Enum::LESS_THAN }, { "less_equal", NwSelectionFindConditionType::Enum::LESS_EQUAL }, { "greater_equal", NwSelectionFindConditionType::Enum::GREATER_EQUAL }, { "greater_than", NwSelectionFindConditionType::Enum::GREATER_THAN }, { "contains", NwSelectionFindConditionType::Enum::CONTAINS }, { "wildcard", NwSelectionFindConditionType::Enum::WILDCARD }, { "within_day", NwSelectionFindConditionType::Enum::WITHIN_DAY }, { "within_week", NwSelectionFindConditionType::Enum::WITHIN_WEEK } }; if (ct) { auto it = StrToFindCondType.find(ct); if (it != StrToFindCondType.end()) { return it->second; } } return NwSelectionFindConditionType::Enum::EQUALS; } NwSelectionFindConditionMode::Enum strToFindModeType(const char* modeTxt) { std::map StrToFindCondModeType = { { "all", NwSelectionFindConditionMode::ALL }, { "selected", NwSelectionFindConditionMode::SELECTED }, { "below", NwSelectionFindConditionMode::BELOW} }; if (modeTxt) { auto modeIt = StrToFindCondModeType.find(modeTxt); if (modeIt != StrToFindCondModeType.end()) { return modeIt->second; } } return NwSelectionFindConditionMode::ALL; } // see: schemas/nw-exchange-12.0.xsd nameType Node OdResult getNameType(TiXmlElement* xmlNode, OdString& name, OdString& intName) { if (!xmlNode) { // node name not found return eNullPtr; } const char* textNode = xmlNode->GetText(); if (!textNode) { // not found text node return eNullPtr; } name = OdString(textNode, CP_UTF_8); const char* intNameText = intName = xmlNode->Attribute("internal"); if (!intNameText) { // not found internal attribute "internal" return eNullPtr; } intName = OdString(intNameText, CP_UTF_8); return eOk; } OdResult getDataType(TiXmlElement* valueNode, OdNwVariant& data) { if (!valueNode) { return eNullPtr; } TiXmlElement* dataValueNode = valueNode->FirstChildElement("data"); if (!dataValueNode) { return eNullPtr; } const char * typeTxt = dataValueNode->Attribute("type"); if (!typeTxt) { return eNullPtr; } if (OdAnsiString(typeTxt) == "name") { TiXmlElement* nameNode = dataValueNode->FirstChildElement("name"); if (!nameNode) { return eNullPtr; } const char* internalNameTxt = nameNode->Attribute("internal"); const char* nameTxt = nameNode->GetText(); data.setRxObjectPtr(OdRxObject::cast(OdNwName::createObject(internalNameTxt, nameTxt))); } else { const char* valueTxt = dataValueNode->GetText(); if (!typeTxt) { return eNullPtr; } if (!valueTxt) { return eNullPtr; } data = NwVariantUtils::str2Variant(OdString(valueTxt), strToDataType(typeTxt)); } return eOk; } void setFindCondFlag(OdNwSearchPtr pSearch, OdUInt32 cndIdx, OdUInt32 flagsd) { for (auto i : { NwSelectionFindConditionFlags::IGNORE_CATEGORY_USER_NAME, NwSelectionFindConditionFlags::IGNORE_CATEGORY_INTERNAL_NAME, NwSelectionFindConditionFlags::IGNORE_PROPERTY_USER_NAME, NwSelectionFindConditionFlags::IGNORE_PROPERTY_INTERNAL_NAME, NwSelectionFindConditionFlags::IGNORE_STRING_VALUE_CASE, NwSelectionFindConditionFlags::NEGATE_CONDITIONS, NwSelectionFindConditionFlags::START_GROUP, NwSelectionFindConditionFlags::IGNORE_STRING_VALUE_DIACRITICS, NwSelectionFindConditionFlags::IGNORE_STRING_VALUE_CHARACTER_WIDTH }) { if (i & flagsd) { pSearch->setFindConditionFlag(cndIdx, i, true); } else { pSearch->setFindConditionFlag(cndIdx, i, false); } } } OdResult parseXml(const char* src, OdNwPropertyTreePtr propTree, OdNwSearchPtr& pSearch, OdString &errDescr) { TiXmlDocument xmlDoc; xmlDoc.Parse(src, 0, TIXML_ENCODING_UTF8); if (xmlDoc.Error()) { errDescr = xmlDoc.ErrorDesc(); return eSyntaxError; } TiXmlElement* xmlRoot = nullptr, * findSpecNode = nullptr; xmlRoot = xmlDoc.RootElement(); if (OdAnsiString(xmlRoot->Value()) != "exchange") { errDescr = L"not found root element excahnge"; return eSyntaxError; } findSpecNode = xmlRoot->FirstChildElement("findspec"); if (!findSpecNode) { errDescr = L"not found element exchange/findspec"; return eSyntaxError; } [[maybe_unused]] const char* modeTxt = findSpecNode->Attribute("mode"); TiXmlElement* conditionsNode = findSpecNode->FirstChildElement("conditions"); if (!conditionsNode) { errDescr = L"not found element exchange/findspec/conditions"; return eSyntaxError; } [[maybe_unused]] const char* disjTxt = conditionsNode->Attribute("disjoint"); TiXmlElement* conditionNode = conditionsNode->FirstChildElement("condition"); if (!conditionNode) { errDescr = L"not found element condition"; return eSyntaxError; } OdUInt32 cndidx = 0; while (conditionNode) { const char* testTxt = conditionNode->Attribute("test"); const char* flagsTxt = conditionNode->Attribute("flags"); OdUInt32 flagsd = 0; if (flagsTxt) { flagsd = strtol(flagsTxt, 0, 10); } if (!testTxt) { errDescr = L"not found attribute condition@test"; return eSyntaxError; } NwSelectionFindConditionType::Enum testEnum = strToFindCondType(testTxt); OdString categoryOdName, categoryOdIntName; TiXmlElement* categoryNode = conditionNode->FirstChildElement("category"); if (categoryNode) { if (getNameType(categoryNode->FirstChildElement("name"), categoryOdName, categoryOdIntName) != eOk) { errDescr = L"error handling conditions/condition[i]/category/name - node"; return eSyntaxError; } } else { categoryOdName = L"Item"; categoryOdIntName = L"LcOaNode"; } TiXmlElement* propertyNode = conditionNode->FirstChildElement("property"); if (!propertyNode) { errDescr = L"not found propery node"; return eSyntaxError; } OdString propOdName, propOdIntName; if (getNameType(propertyNode->FirstChildElement("name"), propOdName, propOdIntName) != eOk) { errDescr = L"error handling conditions/condition[i]/property/name - node"; return eSyntaxError; } OdNwVariant varData; if (getDataType(conditionNode->FirstChildElement("value"), varData) != eOk) { errDescr = L"error handling value node"; return eSyntaxError; } pSearch->addFindCondition(propTree, categoryOdName, propOdName, testEnum, varData); setFindCondFlag(pSearch, cndidx, flagsd); conditionNode = conditionNode->NextSiblingElement("condition"); cndidx++; } [[maybe_unused]] NwSelectionFindConditionMode::Enum searchMode = NwSelectionFindConditionMode::NONE; pSearch->setMode(strToFindModeType(modeTxt)); pSearch->setPruneBelow(false); return eOk; }