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