• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "trigger_checker.h"
17 
18 #include <ctype.h>
19 #include "init_param.h"
20 #include "trigger_manager.h"
21 
22 #define MAX_CALC_PARAM 100
23 // 申请整块能存作为计算的节点
CalculatorInit(LogicCalculator * calculator,int dataNumber,int dataUnit,int needCondition)24 int CalculatorInit(LogicCalculator *calculator, int dataNumber, int dataUnit, int needCondition)
25 {
26     PARAM_CHECK(calculator != NULL, return -1, "Invalid param");
27     PARAM_CHECK(dataUnit <= (int)sizeof(LogicData), return -1, "Invalid param");
28     PARAM_CHECK(dataNumber <= MAX_CALC_PARAM, return -1, "Invalid param");
29     int dataSize = dataUnit * dataNumber;
30     if (needCondition) {
31         dataSize += MAX_DATA_BUFFER_MAX;
32     }
33     calculator->data = (char *)malloc(dataSize);
34     PARAM_CHECK(calculator->data != NULL, return -1, "Failed to malloc for calculator");
35     calculator->dataNumber = dataNumber;
36     calculator->endIndex = 0;
37     calculator->dataUnit = dataUnit;
38 
39     dataSize = dataUnit * dataNumber;
40     calculator->conditionName = calculator->data + dataSize;
41     dataSize += SUPPORT_DATA_BUFFER_MAX;
42     calculator->conditionContent = calculator->data + dataSize;
43     dataSize += SUPPORT_DATA_BUFFER_MAX;
44     calculator->inputName = calculator->data + dataSize;
45     dataSize += SUPPORT_DATA_BUFFER_MAX;
46     calculator->inputContent = calculator->data + dataSize;
47     dataSize += SUPPORT_DATA_BUFFER_MAX;
48     calculator->readContent = calculator->data + dataSize;
49     return memset_s(calculator->triggerContent,
50         sizeof(calculator->triggerContent), 0, sizeof(calculator->triggerContent));
51 }
52 
CalculatorFree(LogicCalculator * calculator)53 void CalculatorFree(LogicCalculator *calculator)
54 {
55     PARAM_CHECK(calculator != NULL, return, "Invalid param");
56     if (calculator->data != NULL) {
57         free(calculator->data);
58     }
59     calculator->data = NULL;
60 }
61 
CalculatorClear(LogicCalculator * calculator)62 static void CalculatorClear(LogicCalculator *calculator)
63 {
64     PARAM_CHECK(calculator != NULL, return, "Invalid param");
65     calculator->endIndex = 0;
66 }
67 
CalculatorPushChar(LogicCalculator * calculator,char data)68 static int CalculatorPushChar(LogicCalculator *calculator, char data)
69 {
70     PARAM_CHECK(calculator != NULL, return -1, "Invalid param");
71     PARAM_CHECK(calculator->endIndex < calculator->dataNumber, return -1, "More data for calculator support");
72     PARAM_CHECK(sizeof(char) == calculator->dataUnit, return -1, "More data for calculator support");
73     calculator->data[calculator->endIndex++] = data;
74     return 0;
75 }
76 
CalculatorPopChar(LogicCalculator * calculator,char * data)77 static int CalculatorPopChar(LogicCalculator *calculator, char *data)
78 {
79     PARAM_CHECK(calculator != NULL, return -1, "Invalid param");
80     PARAM_CHECK(calculator->endIndex < calculator->dataNumber, return -1, "More data for calculator support");
81     if (calculator->endIndex == 0) {
82         return -1;
83     }
84     *data = calculator->data[--calculator->endIndex];
85     return 0;
86 }
87 
CalculatorPush(LogicCalculator * calculator,const void * data)88 static int CalculatorPush(LogicCalculator *calculator, const void *data)
89 {
90     PARAM_CHECK(calculator != NULL, return -1, "Invalid param");
91     PARAM_CHECK(calculator->endIndex < calculator->dataNumber, return -1, "More data for calculator support");
92     char *tmpData = (char *)calculator->data + calculator->dataUnit * calculator->endIndex;
93     int ret = memcpy_s(tmpData, calculator->dataUnit, data, calculator->dataUnit);
94     PARAM_CHECK(ret == EOK, return -1, "Failed to copy logic data");
95     calculator->endIndex++;
96     return 0;
97 }
98 
CalculatorPop(LogicCalculator * calculator,void * data)99 static int CalculatorPop(LogicCalculator *calculator, void *data)
100 {
101     PARAM_CHECK(calculator != NULL && data != NULL, return -1, "Invalid param");
102     PARAM_CHECK(calculator->endIndex < calculator->dataNumber, return -1, "More data for calculator support");
103     if (calculator->endIndex == 0) {
104         return -1;
105     }
106     char *tmpData = (char *)calculator->data + calculator->dataUnit * (calculator->endIndex - 1);
107     int ret = memcpy_s(data, calculator->dataUnit, tmpData, calculator->dataUnit);
108     PARAM_CHECK(ret == EOK, return -1, "Failed to copy logic data");
109     calculator->endIndex--;
110     return 0;
111 }
112 
CalculatorLength(const LogicCalculator * calculator)113 static int CalculatorLength(const LogicCalculator *calculator)
114 {
115     PARAM_CHECK(calculator != NULL, return 0, "Invalid param");
116     return calculator->endIndex;
117 }
118 
PrefixAdd(char * prefix,uint32_t * prefixIndex,uint32_t prefixLen,char op)119 static int PrefixAdd(char *prefix, uint32_t *prefixIndex, uint32_t prefixLen, char op)
120 {
121     if ((*prefixIndex + 1 + 1 + 1) >= prefixLen) {
122         return -1;
123     }
124     prefix[(*prefixIndex)++] = ' ';
125     prefix[(*prefixIndex)++] = op;
126     prefix[(*prefixIndex)++] = ' ';
127     return 0;
128 }
129 
HandleOperationOr(LogicCalculator * calculator,char * prefix,uint32_t * prefixIndex,uint32_t prefixLen)130 static int HandleOperationOr(LogicCalculator *calculator, char *prefix, uint32_t *prefixIndex, uint32_t prefixLen)
131 {
132     char e;
133     prefix[(*prefixIndex)++] = ' ';
134     if (CalculatorLength(calculator) == 0) {
135         CalculatorPushChar(calculator, '|');
136     } else {
137         do {
138             CalculatorPopChar(calculator, &e);
139             if (e == '(') {
140                 CalculatorPushChar(calculator, e);
141             } else {
142                 int ret = PrefixAdd(prefix, prefixIndex, prefixLen, e);
143                 PARAM_CHECK(ret == 0, return -1, "Invalid prefix");
144             }
145         } while (CalculatorLength(calculator) > 0 && e != '(');
146         CalculatorPushChar(calculator, '|');
147     }
148     return 0;
149 }
150 
CompareValue(const char * condition,const char * value)151 static int CompareValue(const char *condition, const char *value)
152 {
153     if (strcmp(condition, "*") == 0) {
154         return 1;
155     }
156     if (strcmp(condition, value) == 0) {
157         return 1;
158     }
159     char *tmp = strstr(condition, "*");
160     if (tmp != NULL && (strncmp(value, condition, tmp - condition) == 0)) {
161         return 1;
162     }
163     return 0;
164 }
165 
ComputeSubCondition(const LogicCalculator * calculator,LogicData * data,const char * condition)166 static int ComputeSubCondition(const LogicCalculator *calculator, LogicData *data, const char *condition)
167 {
168     if (!LOGIC_DATA_TEST_FLAG(data, LOGIC_DATA_FLAGS_ORIGINAL)) {
169         return LOGIC_DATA_TEST_FLAG(data, LOGIC_DATA_FLAGS_TRUE);
170     }
171     uint32_t triggerContentSize = strlen(calculator->triggerContent);
172     // 解析条件, aaaa && bbb=1 && ccc=1的场景
173     char *subStr = strstr(condition + data->startIndex, "=");
174     if (subStr != NULL && ((uint32_t)(subStr - condition) > data->endIndex)) {
175         if (strncmp(condition + data->startIndex, calculator->triggerContent, triggerContentSize) == 0) {
176             return 1;
177         }
178         return 0;
179     }
180     int ret = GetValueFromContent(condition + data->startIndex,
181         data->endIndex - data->startIndex, 0, calculator->conditionName, SUPPORT_DATA_BUFFER_MAX);
182     PARAM_CHECK(ret == 0, return -1, "Failed parse content name");
183     ret = GetValueFromContent(condition + data->startIndex, data->endIndex - data->startIndex,
184         strlen(calculator->conditionName) + 1, calculator->conditionContent, SUPPORT_DATA_BUFFER_MAX);
185     PARAM_CHECK(ret == 0, return -1, "Failed parse content value");
186     // check name
187     if ((calculator->inputName != NULL) && (strcmp(calculator->conditionName, calculator->inputName) == 0)) {
188         return CompareValue(calculator->conditionContent, calculator->inputContent);
189     } else if (calculator->conditionName != NULL && strlen(calculator->conditionName) > 0) {
190         uint32_t len = SUPPORT_DATA_BUFFER_MAX;
191         ret = SystemReadParam(calculator->conditionName, calculator->readContent, &len);
192         if (ret != 0) {
193             return 0;
194         }
195         return CompareValue(calculator->conditionContent, calculator->readContent);
196     }
197     return 0;
198 }
199 
GetValueFromContent(const char * content,uint32_t contentSize,uint32_t start,char * value,uint32_t valueSize)200 int GetValueFromContent(const char *content, uint32_t contentSize, uint32_t start, char *value, uint32_t valueSize)
201 {
202     uint32_t contentIndex = start;
203     uint32_t currIndex = 0;
204     while (contentIndex < contentSize && currIndex < valueSize) {
205         if (content[contentIndex] == '=') {
206             value[currIndex++] = '\0';
207             return 0;
208         }
209         value[currIndex++] = content[contentIndex++];
210     }
211     if (currIndex < valueSize) {
212         value[currIndex] = '\0';
213         return 0;
214     }
215     return -1;
216 }
217 
ComputeCondition(LogicCalculator * calculator,const char * condition)218 int ComputeCondition(LogicCalculator *calculator, const char *condition)
219 {
220     PARAM_CHECK(calculator != NULL && condition != NULL, return -1, "Invalid calculator");
221     uint32_t currIndex = 0;
222     uint32_t start = 0;
223     int noneOper = 1;
224     CalculatorClear(calculator);
225     LogicData data1 = {};
226     LogicData data2 = {};
227     while (currIndex < strlen(condition)) {
228         if (condition[currIndex] == '|' || condition[currIndex] == '&') {
229             noneOper = 0;
230             int ret = CalculatorPop(calculator, (void*)&data2);
231             int ret1 = CalculatorPop(calculator, (void*)&data1);
232             PARAM_CHECK((ret == 0 && ret1 == 0), return -1, "Failed to pop data");
233 
234             ret = ComputeSubCondition(calculator, &data1, condition);
235             data1.flags = 0;
236             if (condition[currIndex] == '|' && ret == 1) {
237                 LOGIC_DATA_SET_FLAG(&data1, LOGIC_DATA_FLAGS_TRUE);
238             } else if ((condition[currIndex] == '|' || ret == 1) &&
239                 (ComputeSubCondition(calculator, &data2, condition) == 1)) {
240                 LOGIC_DATA_SET_FLAG(&data1, LOGIC_DATA_FLAGS_TRUE);
241             }
242             ret = CalculatorPush(calculator, (void *)&data1);
243             PARAM_CHECK(ret == 0, return -1, "Failed to push data");
244             start = currIndex + 1; // 跳过符号
245         } else if (isspace(condition[currIndex])) {
246             if (start == currIndex) {
247                 start = ++currIndex;
248                 continue;
249             }
250             data1.flags = LOGIC_DATA_FLAGS_ORIGINAL;
251             data1.startIndex = start;
252             data1.endIndex = currIndex;
253             int ret = CalculatorPush(calculator, (void *)&data1);
254             PARAM_CHECK(ret == 0, return -1, "Failed to push data");
255             start = currIndex + 1;
256         }
257         currIndex++;
258     }
259     if (noneOper) {
260         data1.flags = LOGIC_DATA_FLAGS_ORIGINAL;
261         data1.startIndex = start;
262         data1.endIndex = strlen(condition);
263     } else {
264         int ret = CalculatorPop(calculator, &data1);
265         PARAM_CHECK(ret == 0, return -1, "Invalid calculator");
266     }
267     return ComputeSubCondition(calculator, &data1, condition);
268 }
269 
ConvertInfixToPrefix(const char * condition,char * prefix,uint32_t prefixLen)270 int ConvertInfixToPrefix(const char *condition, char *prefix, uint32_t prefixLen)
271 {
272     PARAM_CHECK(condition != NULL && prefix != NULL, return -1, "Invalid condition");
273     char e = 0;
274     int ret;
275     uint32_t curr = 0;
276     uint32_t prefixIndex = 0;
277     LogicCalculator calculator;
278     CalculatorInit(&calculator, MAX_CALC_PARAM, 1, 0);
279 
280     while (curr < strlen(condition)) {
281         if (condition[curr] == ')') {
282             CalculatorPopChar(&calculator, &e);
283             while (e != '(') {
284                 ret = PrefixAdd(prefix, &prefixIndex, prefixLen, e);
285                 PARAM_CHECK(ret == 0,
286                     CalculatorFree(&calculator); return -1, "Invalid prefix");
287                 CalculatorPopChar(&calculator, &e);
288             }
289         } else if (condition[curr] == '|') {
290             PARAM_CHECK(condition[curr + 1] == '|',
291                 CalculatorFree(&calculator); return -1, "Invalid condition");
292             ret = HandleOperationOr(&calculator, prefix, &prefixIndex, prefixLen);
293             PARAM_CHECK(ret == 0,
294                 CalculatorFree(&calculator); return -1, "Invalid prefix");
295             curr++;
296         } else if (condition[curr] == '&') {
297             PARAM_CHECK(condition[curr + 1] == '&',
298                 CalculatorFree(&calculator); return -1, "Invalid condition");
299             prefix[prefixIndex++] = ' ';
300             CalculatorPushChar(&calculator, condition[curr]);
301             curr++;
302         } else if (condition[curr] == '(') {
303             CalculatorPushChar(&calculator, condition[curr]);
304         } else {
305             prefix[prefixIndex++] = condition[curr];
306         }
307         curr++;
308         PARAM_CHECK(prefixIndex < prefixLen,
309             CalculatorFree(&calculator); return -1, "Invalid prefixIndex");
310     }
311 
312     while (CalculatorLength(&calculator) > 0) {
313         CalculatorPopChar(&calculator, &e);
314         ret = PrefixAdd(prefix, &prefixIndex, prefixLen, e);
315         PARAM_CHECK(ret == 0,
316             CalculatorFree(&calculator);
317             return -1, "Invalid prefix %u %u", prefixIndex, prefixLen);
318     }
319     prefix[prefixIndex] = '\0';
320     CalculatorFree(&calculator);
321     return 0;
322 }
323 
CheckMatchSubCondition(const char * condition,const char * input,int length)324 int CheckMatchSubCondition(const char *condition, const char *input, int length)
325 {
326     PARAM_CHECK(condition != NULL, return 0, "Invalid condition");
327     PARAM_CHECK(input != NULL, return 0, "Invalid input");
328     char *tmp = strstr(condition, input);
329     if ((tmp != NULL) && ((int)strlen(tmp) > length) && (tmp[length] == '=')) {
330         return 1;
331     }
332     return 0;
333 }
334