1 /*
2 * Copyright (c) 2023 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 #ifndef OHOS_DMSFWK_JSON_UTIL_H
17 #define OHOS_DMSFWK_JSON_UTIL_H
18
19 #include <string>
20
21 #include "dtbschedmgr_log.h"
22
23 namespace OHOS {
24 namespace DistributedSchedule {
25 namespace {
26 const std::string TAG = "jsonUtil";
27 }
28
29 enum class JsonType {
30 NULLABLE,
31 BOOLEAN,
32 NUMBER,
33 OBJECT,
34 ARRAY,
35 STRING,
36 };
37
38 enum class ArrayType {
39 NUMBER,
40 OBJECT,
41 STRING,
42 NOT_ARRAY,
43 };
44
45 template<typename T, typename dataType>
CheckArrayType(const nlohmann::json & jsonObject,const std::string & key,dataType & data,ArrayType arrayType,int32_t & parseResult)46 void CheckArrayType(const nlohmann::json &jsonObject, const std::string &key,
47 dataType &data, ArrayType arrayType, int32_t &parseResult)
48 {
49 auto arrays = jsonObject.at(key);
50 if (arrays.empty()) {
51 HILOGD("array is empty");
52 return;
53 }
54 switch (arrayType) {
55 case ArrayType::STRING:
56 for (const auto &array : arrays) {
57 if (!array.is_string()) {
58 HILOGE("array %{public}s is not string type", key.c_str());
59 parseResult = ERR_APPEXECFWK_PARSE_PROFILE_PROP_TYPE_ERROR;
60 }
61 }
62 if (parseResult == ERR_OK) {
63 data = jsonObject.at(key).get<T>();
64 }
65 break;
66 case ArrayType::OBJECT:
67 for (const auto &array : arrays) {
68 if (!array.is_object()) {
69 HILOGE("array %{public}s is not object type", key.c_str());
70 parseResult = ERR_APPEXECFWK_PARSE_PROFILE_PROP_TYPE_ERROR;
71 break;
72 }
73 }
74 if (parseResult == ERR_OK) {
75 data = jsonObject.at(key).get<T>();
76 }
77 break;
78 case ArrayType::NUMBER:
79 for (const auto &array : arrays) {
80 if (!array.is_number()) {
81 HILOGE("array %{public}s is not number type", key.c_str());
82 parseResult = ERR_APPEXECFWK_PARSE_PROFILE_PROP_TYPE_ERROR;
83 }
84 }
85 if (parseResult == ERR_OK) {
86 data = jsonObject.at(key).get<T>();
87 }
88 break;
89 case ArrayType::NOT_ARRAY:
90 HILOGE("array %{public}s is not array type", key.c_str());
91 break;
92 default:
93 HILOGE("array %{public}s type error", key.c_str());
94 break;
95 }
96 }
97
98 template<typename T, typename dataType>
GetValueIfFindKey(const nlohmann::json & jsonObject,const nlohmann::detail::iter_impl<const nlohmann::json> & end,const std::string & key,dataType & data,JsonType jsonType,bool isNecessary,int32_t & parseResult,ArrayType arrayType)99 void GetValueIfFindKey(const nlohmann::json &jsonObject, const nlohmann::detail::iter_impl<const nlohmann::json> &end,
100 const std::string &key, dataType &data, JsonType jsonType, bool isNecessary, int32_t &parseResult,
101 ArrayType arrayType)
102 {
103 if (parseResult) {
104 return;
105 }
106 if (jsonObject.find(key) != end) {
107 switch (jsonType) {
108 case JsonType::BOOLEAN:
109 if (!jsonObject.at(key).is_boolean()) {
110 HILOGE("type is error %{public}s is not boolean", key.c_str());
111 parseResult = ERR_APPEXECFWK_PARSE_PROFILE_PROP_TYPE_ERROR;
112 break;
113 }
114 data = jsonObject.at(key).get<T>();
115 break;
116 case JsonType::NUMBER:
117 if (!jsonObject.at(key).is_number()) {
118 HILOGE("type is error %{public}s is not number", key.c_str());
119 parseResult = ERR_APPEXECFWK_PARSE_PROFILE_PROP_TYPE_ERROR;
120 break;
121 }
122 data = jsonObject.at(key).get<T>();
123 break;
124 case JsonType::OBJECT:
125 if (!jsonObject.at(key).is_object()) {
126 HILOGE("type is error %{public}s is not object", key.c_str());
127 parseResult = ERR_APPEXECFWK_PARSE_PROFILE_PROP_TYPE_ERROR;
128 break;
129 }
130 data = jsonObject.at(key).get<T>();
131 break;
132 case JsonType::ARRAY:
133 if (!jsonObject.at(key).is_array()) {
134 HILOGE("type is error %{public}s is not array", key.c_str());
135 parseResult = ERR_APPEXECFWK_PARSE_PROFILE_PROP_TYPE_ERROR;
136 break;
137 }
138 CheckArrayType<T>(jsonObject, key, data, arrayType, parseResult);
139 break;
140 case JsonType::STRING:
141 if (!jsonObject.at(key).is_string()) {
142 HILOGE("type is error %{public}s is not string", key.c_str());
143 parseResult = ERR_APPEXECFWK_PARSE_PROFILE_PROP_TYPE_ERROR;
144 break;
145 }
146 data = jsonObject.at(key).get<T>();
147 break;
148 case JsonType::NULLABLE:
149 HILOGE("type is error %{public}s is nullable", key.c_str());
150 break;
151 default:
152 HILOGE("type is error %{public}s is not jsonType", key.c_str());
153 parseResult = ERR_APPEXECFWK_PARSE_PROFILE_PROP_TYPE_ERROR;
154 }
155 return;
156 }
157 if (isNecessary) {
158 HILOGE("profile prop %{public}s is mission", key.c_str());
159 parseResult = ERR_APPEXECFWK_PARSE_PROFILE_MISSING_PROP;
160 }
161 }
162
163 template<typename T>
GetJsonStrFromInfo(T & t)164 const std::string GetJsonStrFromInfo(T &t)
165 {
166 nlohmann::json json = t;
167 return json.dump();
168 }
169
170 template<typename T>
ParseInfoFromJsonStr(const char * data,T & t)171 bool ParseInfoFromJsonStr(const char *data, T &t)
172 {
173 if (data == nullptr) {
174 HILOGE("%{public}s failed due to data is nullptr", __func__);
175 return false;
176 }
177
178 nlohmann::json jsonObject = nlohmann::json::parse(data, nullptr, false);
179 if (jsonObject.is_discarded()) {
180 HILOGE("%{public}s failed due to data is discarded", __func__);
181 return false;
182 }
183
184 t = jsonObject.get<T>();
185 return true;
186 }
187 } // namespace DistributedSchedule
188 } // namespace OHOS
189 #endif // OHOS_DMSFWK_JSON_UTIL_H
190