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