ConditionEvent.cpp 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289
  1. #include "stdafx.h"
  2. #include "ConditionEvent.h"
  3. #include <iostream>
  4. ConditionEvent::ConditionEvent(ResDataObject* event)
  5. {
  6. m_nContionNum = 0;
  7. m_strName = event->GetKey(0);
  8. m_strType = "";
  9. int typeIdx = event->GetFirstOf("Type");
  10. if (typeIdx < 0)
  11. {
  12. //不能没有Type字段
  13. return;
  14. }
  15. ResDataObject resType = (*event)[typeIdx];
  16. ResDataObject resConds;
  17. if (string("Conditions") == (string)(resType))
  18. {
  19. m_strType = (string)(resType);
  20. //只取第一个
  21. //m_resCoditions = (*event)[1];
  22. if ((*event).GetFirstOf("OR") >= 0)
  23. {
  24. m_resCoditions = (*event)["OR"];
  25. }
  26. else if ((*event).GetFirstOf("AND") >= 0)
  27. {
  28. m_resCoditions = (*event)["AND"];
  29. }
  30. m_nContionNum = m_resCoditions.size();
  31. //m_resCoditions = new ResDataObject[m_nContionNum];
  32. //for (int x = 0; x < m_nContionNum; x++)
  33. //{
  34. // m_resCoditions[x] = m_resCoditions[x];
  35. // cout << "条件 " << x << m_resCoditions[x].encode() << endl;
  36. //}
  37. }
  38. else if (string("External") == (string)(resType))
  39. {
  40. m_strType = (string)(resType);
  41. m_strValue = (string)(*event)[1];
  42. }
  43. else if(string("Timeout") == (string)(resType))
  44. {
  45. m_strType = (string)(resType);
  46. m_strValue = (string)(*event)[1];
  47. }
  48. else
  49. {
  50. //未知类型,笔误,应该报错
  51. }
  52. }
  53. ConditionEvent::~ConditionEvent()
  54. {
  55. delete m_resCoditions;
  56. }
  57. bool ExpressionValue(ResDataObject& resCalc, const char* value)
  58. {
  59. if (resCalc.GetFirstOf("Operator") < 0)
  60. {
  61. return (string)(resCalc) == (string)(value);
  62. }
  63. string oper = (string)resCalc["Operator"];
  64. transform(oper.begin(), oper.end(), oper.begin(), ::tolower);
  65. string opValue = (string)(resCalc["Value"]);
  66. string ckValue = (string)value;
  67. if (oper == "!=" || oper == "<>")
  68. {
  69. return !(opValue == ckValue);
  70. }
  71. else if (oper == "in")
  72. {
  73. return opValue.find(ckValue) >= 0;
  74. }
  75. else if (oper == "not in")
  76. {
  77. return opValue.find(ckValue) < 0;
  78. }
  79. else if (oper == "between" )
  80. {
  81. string orgOper = (string)resCalc["Operator"];
  82. if (ckValue.find('.') > 0 || opValue.find('.') > 0)
  83. {
  84. //浮点数
  85. int nSepPos = opValue.find(',');
  86. if (nSepPos < 0)
  87. return false;
  88. double doValueMin = std::stod(opValue.substr(0, nSepPos));
  89. double doValueMax = std::stod(opValue.substr(nSepPos + 1, opValue.length() - nSepPos - 1));
  90. double dcValue = std::stod(ckValue);
  91. return orgOper[0] == 'B' ? dcValue >= doValueMin: dcValue > doValueMin
  92. && orgOper[3] == 'W' ? dcValue <= doValueMax : dcValue < doValueMax;
  93. }
  94. else
  95. {
  96. int nSepPos = opValue.find(',');
  97. if (nSepPos < 0)
  98. return false;
  99. long doValueMin = std::stod(opValue.substr(0, nSepPos));
  100. long doValueMax = std::stod(opValue.substr(nSepPos + 1, opValue.length() - nSepPos - 1));
  101. long dcValue = std::stod(ckValue);
  102. return orgOper[0] == 'B' ? dcValue >= doValueMin : dcValue > doValueMin
  103. && orgOper[3] == 'W' ? dcValue <= doValueMax : dcValue < doValueMax;
  104. }
  105. }
  106. else
  107. {
  108. //比较大小
  109. if (ckValue.find('.') > 0 || opValue.find('.') > 0)
  110. {
  111. //浮点数
  112. double doValue = std::stod(opValue);
  113. double dcValue = std::stod(ckValue);
  114. if (oper == "<")
  115. return dcValue < doValue;
  116. else if (oper == "<=")
  117. return dcValue <= doValue;
  118. else if (oper == ">")
  119. return dcValue > doValue;
  120. else if (oper == ">=")
  121. return dcValue >= doValue;
  122. else
  123. return false;
  124. }
  125. else
  126. {
  127. //整型或者其他
  128. long doValue = std::stol(opValue);
  129. long dcValue = std::stol(ckValue);
  130. if (oper == "<")
  131. return dcValue < doValue;
  132. else if (oper == "<=")
  133. return dcValue <= doValue;
  134. else if (oper == ">")
  135. return dcValue > doValue;
  136. else if (oper == ">=")
  137. return dcValue >= doValue;
  138. else
  139. return false;
  140. }
  141. }
  142. }
  143. std::vector<std::string> stringSplit(const std::string& str, char delim) {
  144. std::size_t previous = 0;
  145. std::size_t current = str.find_first_of(delim);
  146. std::vector<std::string> elems;
  147. while (current != std::string::npos) {
  148. if (current > previous) {
  149. elems.push_back(str.substr(previous, current - previous));
  150. }
  151. previous = current + 1;
  152. current = str.find_first_of(delim, previous);
  153. }
  154. if (previous != str.size()) {
  155. elems.push_back(str.substr(previous));
  156. }
  157. return elems;
  158. }
  159. string GetContextValue(ResDataObject* resContext, const char* pszURI)
  160. {
  161. string uri = pszURI;
  162. auto step = stringSplit(uri, '.');
  163. ResDataObject ret = *resContext;
  164. try {
  165. for (int x = 0; x < step.size(); x++)
  166. {
  167. ret = ret[step[x].c_str()];
  168. }
  169. return (string)ret;
  170. }
  171. catch (...)
  172. {
  173. return "";
  174. }
  175. }
  176. bool ConditionEvent::Check(const char* pszTypeName, ResDataObject *resContext, const char* pszDevice)
  177. {
  178. string evtType = pszTypeName;
  179. if (evtType == "External")
  180. {
  181. if (m_strValue == (string)(*resContext))
  182. {
  183. //时间名称相同,则触发
  184. m_bTriggered = true;
  185. return true;
  186. }
  187. else
  188. {
  189. return false;
  190. }
  191. }
  192. else if (evtType == "Timeout")
  193. {
  194. //整体超时,但是可能有Action执行结果,暂不处理
  195. m_bTriggered = true;
  196. return true;
  197. }
  198. else if (evtType == "Action" || evtType == "Notify")
  199. {
  200. //处理所有的条件
  201. for (int x = 0; x < m_resCoditions.size(); x++)
  202. {
  203. //是Action
  204. ResDataObject condi = m_resCoditions[x];
  205. string condiType = condi["Type"];
  206. string device = condi["Device"];
  207. if (evtType == condiType && string(pszDevice) == device)
  208. {
  209. //Action的Key和Notify的Key
  210. string checkValueKey = condi[condiType.c_str()];
  211. if(checkValueKey == string((*resContext)["KEY"]))
  212. {
  213. ResDataObject caculate = condi["Check"];
  214. bool bRet = ExpressionValue(caculate, GetContextValue(resContext, caculate.GetKey(0)).c_str());
  215. m_resConditionsValue.update(m_resCoditions.GetKey(x), bRet);
  216. return CaculateCondition();
  217. }
  218. }
  219. }
  220. }
  221. else
  222. {
  223. return false;
  224. }
  225. return true;
  226. }
  227. bool ConditionEvent::CaculateCondition()
  228. {
  229. string type = m_resCoditions.GetKey(0);
  230. bool bRet;
  231. if (type == "AND")
  232. {
  233. bRet = true;
  234. //所有条件
  235. for (int x = 0; x < m_resConditionsValue.size(); x++)
  236. {
  237. if (!(bool)m_resConditionsValue[x])
  238. {
  239. bRet = false;
  240. return bRet;
  241. }
  242. }
  243. return true;
  244. }
  245. else if (type == "OR")
  246. {
  247. bRet = false;
  248. for (int x = 0; x < m_resConditionsValue.size(); x++)
  249. {
  250. if ((bool)m_resConditionsValue[x])
  251. {
  252. bRet = true;
  253. return bRet;
  254. }
  255. }
  256. return false;
  257. }
  258. }
  259. int ConditionEvent::GetTimeout()
  260. {
  261. if (m_strType == "Timeout")
  262. return std::stoi(m_strValue);
  263. return 0;
  264. }