#include "stdafx.h" #include "ConditionEvent.h" #include ConditionEvent::ConditionEvent(ResDataObject* event) { m_nContionNum = 0; m_strName = event->GetKey(0); m_strType = ""; int typeIdx = event->GetFirstOf("Type"); if (typeIdx < 0) { //不能没有Type字段 return; } ResDataObject resType = (*event)[typeIdx]; ResDataObject resConds; if (string("Conditions") == (string)(resType)) { m_strType = (string)(resType); //只取第一个 //m_resCoditions = (*event)[1]; if ((*event).GetFirstOf("OR") >= 0) { m_resCoditions = (*event)["OR"]; } else if ((*event).GetFirstOf("AND") >= 0) { m_resCoditions = (*event)["AND"]; } m_nContionNum = m_resCoditions.size(); //m_resCoditions = new ResDataObject[m_nContionNum]; //for (int x = 0; x < m_nContionNum; x++) //{ // m_resCoditions[x] = m_resCoditions[x]; // cout << "条件 " << x << m_resCoditions[x].encode() << endl; //} } else if (string("External") == (string)(resType)) { m_strType = (string)(resType); m_strValue = (string)(*event)[1]; } else if(string("Timeout") == (string)(resType)) { m_strType = (string)(resType); m_strValue = (string)(*event)[1]; } else { //未知类型,笔误,应该报错 } } ConditionEvent::~ConditionEvent() { delete m_resCoditions; } bool ExpressionValue(ResDataObject& resCalc, const char* value) { if (resCalc.GetFirstOf("Operator") < 0) { return (string)(resCalc) == (string)(value); } string oper = (string)resCalc["Operator"]; transform(oper.begin(), oper.end(), oper.begin(), ::tolower); string opValue = (string)(resCalc["Value"]); string ckValue = (string)value; if (oper == "!=" || oper == "<>") { return !(opValue == ckValue); } else if (oper == "in") { return opValue.find(ckValue) >= 0; } else if (oper == "not in") { return opValue.find(ckValue) < 0; } else if (oper == "between" ) { string orgOper = (string)resCalc["Operator"]; if (ckValue.find('.') > 0 || opValue.find('.') > 0) { //浮点数 int nSepPos = opValue.find(','); if (nSepPos < 0) return false; double doValueMin = std::stod(opValue.substr(0, nSepPos)); double doValueMax = std::stod(opValue.substr(nSepPos + 1, opValue.length() - nSepPos - 1)); double dcValue = std::stod(ckValue); return orgOper[0] == 'B' ? dcValue >= doValueMin: dcValue > doValueMin && orgOper[3] == 'W' ? dcValue <= doValueMax : dcValue < doValueMax; } else { int nSepPos = opValue.find(','); if (nSepPos < 0) return false; long doValueMin = std::stod(opValue.substr(0, nSepPos)); long doValueMax = std::stod(opValue.substr(nSepPos + 1, opValue.length() - nSepPos - 1)); long dcValue = std::stod(ckValue); return orgOper[0] == 'B' ? dcValue >= doValueMin : dcValue > doValueMin && orgOper[3] == 'W' ? dcValue <= doValueMax : dcValue < doValueMax; } } else { //比较大小 if (ckValue.find('.') > 0 || opValue.find('.') > 0) { //浮点数 double doValue = std::stod(opValue); double dcValue = std::stod(ckValue); if (oper == "<") return dcValue < doValue; else if (oper == "<=") return dcValue <= doValue; else if (oper == ">") return dcValue > doValue; else if (oper == ">=") return dcValue >= doValue; else return false; } else { //整型或者其他 long doValue = std::stol(opValue); long dcValue = std::stol(ckValue); if (oper == "<") return dcValue < doValue; else if (oper == "<=") return dcValue <= doValue; else if (oper == ">") return dcValue > doValue; else if (oper == ">=") return dcValue >= doValue; else return false; } } } std::vector stringSplit(const std::string& str, char delim) { std::size_t previous = 0; std::size_t current = str.find_first_of(delim); std::vector elems; while (current != std::string::npos) { if (current > previous) { elems.push_back(str.substr(previous, current - previous)); } previous = current + 1; current = str.find_first_of(delim, previous); } if (previous != str.size()) { elems.push_back(str.substr(previous)); } return elems; } string GetContextValue(ResDataObject* resContext, const char* pszURI) { string uri = pszURI; auto step = stringSplit(uri, '.'); ResDataObject ret = *resContext; try { for (int x = 0; x < step.size(); x++) { ret = ret[step[x].c_str()]; } return (string)ret; } catch (...) { return ""; } } bool ConditionEvent::Check(const char* pszTypeName, ResDataObject *resContext, const char* pszDevice) { string evtType = pszTypeName; if (evtType == "External") { if (m_strValue == (string)(*resContext)) { //时间名称相同,则触发 m_bTriggered = true; return true; } else { return false; } } else if (evtType == "Timeout") { //整体超时,但是可能有Action执行结果,暂不处理 m_bTriggered = true; return true; } else if (evtType == "Action" || evtType == "Notify") { //处理所有的条件 for (int x = 0; x < m_resCoditions.size(); x++) { //是Action ResDataObject condi = m_resCoditions[x]; string condiType = condi["Type"]; string device = condi["Device"]; if (evtType == condiType && string(pszDevice) == device) { //Action的Key和Notify的Key string checkValueKey = condi[condiType.c_str()]; if(checkValueKey == string((*resContext)["KEY"])) { ResDataObject caculate = condi["Check"]; bool bRet = ExpressionValue(caculate, GetContextValue(resContext, caculate.GetKey(0)).c_str()); m_resConditionsValue.update(m_resCoditions.GetKey(x), bRet); return CaculateCondition(); } } } } else { return false; } return true; } bool ConditionEvent::CaculateCondition() { string type = m_resCoditions.GetKey(0); bool bRet; if (type == "AND") { bRet = true; //所有条件 for (int x = 0; x < m_resConditionsValue.size(); x++) { if (!(bool)m_resConditionsValue[x]) { bRet = false; return bRet; } } return true; } else if (type == "OR") { bRet = false; for (int x = 0; x < m_resConditionsValue.size(); x++) { if ((bool)m_resConditionsValue[x]) { bRet = true; return bRet; } } return false; } } int ConditionEvent::GetTimeout() { if (m_strType == "Timeout") return std::stoi(m_strValue); return 0; }