123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289 |
- #include "stdafx.h"
- #include "ConditionEvent.h"
- #include <iostream>
- 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<std::string> stringSplit(const std::string& str, char delim) {
- std::size_t previous = 0;
- std::size_t current = str.find_first_of(delim);
- std::vector<std::string> 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;
- }
|