1 /*
2  * Copyright (c) 2022 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 "input_parse.h"
17 
18 #include <sstream>
19 
20 #include "cJSON.h"
21 #include "define_multimodal.h"
22 
23 #undef MMI_LOG_TAG
24 #define MMI_LOG_TAG "GetDeviceNode"
25 
26 namespace OHOS {
27 namespace MMI {
28 namespace {
29 struct JsonParser {
30     JsonParser() = default;
~JsonParserOHOS::MMI::__anon84af44dc0110::JsonParser31     ~JsonParser()
32     {
33         if (json_ != nullptr) {
34             cJSON_Delete(json_);
35         }
36     }
37     operator cJSON *()
38     {
39         return json_;
40     }
41     cJSON *json_ { nullptr };
42 };
43 
GetJsonData(cJSON * json,const std::string & key,std::string & val)44 void GetJsonData(cJSON *json, const std::string& key, std::string& val)
45 {
46     if (!cJSON_IsObject(json)) {
47         MMI_HILOGE("The json is not object");
48         return;
49     }
50     if (cJSON_HasObjectItem(json, key.c_str())) {
51         cJSON* rawValue = cJSON_GetObjectItem(json, key.c_str());
52         if (cJSON_IsString(rawValue)) {
53             val = rawValue->valuestring;
54         }
55     }
56     return;
57 }
58 
59 template <class T>
GetJsonData(cJSON * json,const std::string & key,T & val)60 void GetJsonData(cJSON *json, const std::string& key, T& val)
61 {
62     if (!cJSON_IsObject(json)) {
63         MMI_HILOGE("The json is not object");
64         return;
65     }
66     if (cJSON_HasObjectItem(json, key.c_str())) {
67         cJSON* rawNum = cJSON_GetObjectItem(json, key.c_str());
68         if (cJSON_IsNumber(rawNum)) {
69             val = rawNum->valueint;
70         }
71     }
72     return;
73 }
74 
GetJsonData(cJSON * json,const std::string & key,std::vector<int32_t> & vals)75 void GetJsonData(cJSON *json, const std::string& key, std::vector<int32_t>& vals)
76 {
77     if (!cJSON_IsObject(json)) {
78         MMI_HILOGE("The json is not object");
79         return;
80     }
81     if (!cJSON_HasObjectItem(json, key.c_str())) {
82         MMI_HILOGE("The json is not data:%{public}s", key.c_str());
83         return;
84     }
85     cJSON* rawVal = cJSON_GetObjectItem(json, key.c_str());
86     if (!cJSON_IsArray(rawVal)) {
87         MMI_HILOGE("The rawVal is not Array");
88         return;
89     }
90     int32_t rawValSize = cJSON_GetArraySize(rawVal);
91     for (int32_t i = 0; i < rawValSize; ++i) {
92         cJSON* val = cJSON_GetArrayItem(rawVal, i);
93         if (cJSON_IsNumber(val)) {
94             vals.push_back(val->valueint);
95         }
96     }
97     return;
98 }
99 
ParseEvents(cJSON * eventInfo,DeviceEvent & event)100 bool ParseEvents(cJSON* eventInfo, DeviceEvent& event)
101 {
102     if (!cJSON_IsArray(eventInfo)) {
103         MMI_HILOGE("The eventInfo is not array");
104         return false;
105     }
106     int32_t eventSize = cJSON_GetArraySize(eventInfo);
107     for (int32_t i = 0; i < eventSize; ++i) {
108         cJSON* eventArray = cJSON_GetArrayItem(eventInfo, i);
109         if (cJSON_IsArray(eventArray)) {
110             cJSON* xPos = cJSON_GetArrayItem(eventArray, 0);
111             if (!cJSON_IsNumber(xPos)) {
112                 MMI_HILOGE("The xPos is not number");
113                 return false;
114             }
115             Pos pos;
116             pos.xPos = xPos->valueint;
117             cJSON* yPos = cJSON_GetArrayItem(eventArray, 1);
118             if (!cJSON_IsNumber(yPos)) {
119                 MMI_HILOGE("The yPos is not number");
120                 return false;
121             }
122             pos.yPos = yPos->valueint;
123             event.posXY.push_back(pos);
124         }
125     }
126     return true;
127 }
128 
ParseEventsObj(cJSON * eventInfo,DeviceEvent & event)129 void ParseEventsObj(cJSON* eventInfo, DeviceEvent& event)
130 {
131     if (!cJSON_IsObject(eventInfo)) {
132         MMI_HILOGE("The eventInfo is not object");
133         return;
134     }
135     GetJsonData(eventInfo, "eventType", event.eventType);
136     GetJsonData(eventInfo, "event", event.event);
137     GetJsonData(eventInfo, "keyValue", event.keyValue);
138     GetJsonData(eventInfo, "blockTime", event.blockTime);
139     GetJsonData(eventInfo, "ringEvents", event.ringEvents);
140     GetJsonData(eventInfo, "direction", event.direction);
141     GetJsonData(eventInfo, "distance", event.distance);
142     GetJsonData(eventInfo, "xPos", event.xPos);
143     GetJsonData(eventInfo, "yPos", event.yPos);
144     GetJsonData(eventInfo, "tiltX", event.tiltX);
145     GetJsonData(eventInfo, "tiltY", event.tiltY);
146     GetJsonData(eventInfo, "pressure", event.pressure);
147     GetJsonData(eventInfo, "trackingId", event.trackingId);
148     GetJsonData(eventInfo, "reportType", event.reportType);
149     GetJsonData(eventInfo, "keyStatus", event.keyStatus);
150     return;
151 }
152 
ParseData(cJSON * events,std::vector<DeviceEvent> & eventData)153 bool ParseData(cJSON* events, std::vector<DeviceEvent>& eventData)
154 {
155     if (!cJSON_IsArray(events)) {
156         MMI_HILOGE("The events is not array");
157         return false;
158     }
159     int32_t eventsSize = cJSON_GetArraySize(events);
160     for (int32_t i = 0; i < eventsSize; ++i) {
161         cJSON* eventInfo = cJSON_GetArrayItem(events, i);
162         DeviceEvent event;
163         if (cJSON_IsArray(eventInfo)) {
164             if (!ParseEvents(eventInfo, event)) {
165                 MMI_HILOGE("Failed to parse events");
166                 return false;
167             }
168         } else if (cJSON_IsObject(eventInfo)) {
169             ParseEventsObj(eventInfo, event);
170         } else {
171             MMI_HILOGE("Events is error");
172             return false;
173         }
174         eventData.push_back(event);
175     }
176     return true;
177 }
178 } // namespace
179 
ToString() const180 std::string Pos::ToString() const
181 {
182     std::ostringstream ss;
183     ss << "pos(" << xPos << "," << yPos << ")";
184     return ss.str();
185 }
186 
ToString() const187 std::string DeviceEvent::ToString() const
188 {
189     std::ostringstream ss;
190     ss << "{eventType:" << eventType
191         << ",event:[";
192     for (const auto &item : event) {
193         ss << item << ",";
194     }
195     ss << "],keyValue:" << keyValue
196         << ",blockTime:" << blockTime
197         << ",ringEvents:[";
198     for (const auto &item : ringEvents) {
199         ss << item << ",";
200     }
201     ss << "],direction:" << direction
202         << ",distance:" << distance
203         << ",xPos:" << xPos
204         << ",yPos:" << yPos
205         << ",tiltX:" << tiltX
206         << ",tiltY:" << tiltY
207         << ",pressure:" << pressure
208         << ",trackingId:" << trackingId
209         << ",reportType:" << reportType
210         << ",keyStatus:" << keyStatus
211         << ",posXY:";
212     for (const auto &item : posXY) {
213         ss << item.ToString() << ",";
214     }
215     ss << "}" << std::endl;
216     return ss.str();
217 }
218 
ToString() const219 std::string DeviceItem::ToString() const
220 {
221     std::ostringstream ss;
222     ss << "{deviceName:" << deviceName
223         << ",deviceIndex:" << deviceIndex
224         << ",events:[";
225     for (const auto &item : events) {
226         ss << item.ToString() << ",";
227     }
228     ss << "]" << std::endl;
229     return ss.str();
230 }
231 
DataInit(const std::string & fileData,bool logStatus)232 DeviceItems DataInit(const std::string& fileData, bool logStatus)
233 {
234     CALL_DEBUG_ENTER;
235     JsonParser parser;
236     parser.json_ = cJSON_Parse(fileData.c_str());
237     if (!cJSON_IsArray(parser.json_)) {
238         MMI_HILOGE("The parser is not array");
239         return {};
240     }
241     int32_t arraysSize = cJSON_GetArraySize(parser.json_);
242     DeviceItems deviceItems;
243     for (int32_t i = 0; i < arraysSize; ++i) {
244         cJSON* deviceInfo = cJSON_GetArrayItem(parser.json_, i);
245         if (!cJSON_IsObject(deviceInfo)) {
246             MMI_HILOGE("The deviceInfo is not Object");
247             return {};
248         }
249         cJSON* deviceName = cJSON_GetObjectItem(deviceInfo, "deviceName");
250         if (!cJSON_IsString(deviceName)) {
251             MMI_HILOGE("The deviceName is not string");
252             return {};
253         }
254         DeviceItem deviceItem;
255         deviceItem.deviceName = deviceName->valuestring;
256         GetJsonData(deviceInfo, "deviceIndex", deviceItem.deviceIndex);
257         cJSON *events = nullptr;
258         if (cJSON_HasObjectItem(deviceInfo, "events")) {
259             events = cJSON_GetObjectItem(deviceInfo, "events");
260         } else if (cJSON_HasObjectItem(deviceInfo, "singleEvent")) {
261             events = cJSON_GetObjectItem(deviceInfo, "singleEvent");
262         }
263         if (!cJSON_IsArray(events)) {
264             MMI_HILOGE("The events is not array");
265             return {};
266         }
267         if (!ParseData(events, deviceItem.events)) {
268             MMI_HILOGE("Failed to parse data");
269             return {};
270         }
271         deviceItems.push_back(deviceItem);
272         if (logStatus) {
273             MMI_HILOGW("deviceItem[%{public}d]:%{public}s", i, deviceItem.ToString().c_str());
274         }
275     }
276     return deviceItems;
277 }
278 } // namespace MMI
279 } // namespace OHOS