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 : int8_t {
28 NULLABLE,
29 BOOLEAN,
30 NUMBER,
31 OBJECT,
32 ARRAY,
33 STRING,
34 };
35
36 enum class ArrayType : int8_t {
37 NUMBER,
38 OBJECT,
39 STRING,
40 NOT_ARRAY,
41 };
42
43 class BMSJsonUtil {
44 public:
45 static void GetStrValueIfFindKey(const nlohmann::json &jsonObject,
46 const nlohmann::detail::iter_impl<const nlohmann::json> &end,
47 const std::string &key, std::string &data, bool isNecessary, int32_t &parseResult);
48 static void GetBoolValueIfFindKey(const nlohmann::json &jsonObject,
49 const nlohmann::detail::iter_impl<const nlohmann::json> &end,
50 const std::string &key, bool &data, bool isNecessary, int32_t &parseResult);
51 };
52
53 template<typename T, typename dataType>
CheckArrayType(const nlohmann::json & jsonObject,const std::string & key,dataType & data,ArrayType arrayType,int32_t & parseResult)54 void CheckArrayType(
55 const nlohmann::json &jsonObject, const std::string &key, dataType &data, ArrayType arrayType, int32_t &parseResult)
56 {
57 auto arrays = jsonObject.at(key);
58 if (arrays.empty()) {
59 return;
60 }
61 if (arrays.size() > Constants::MAX_JSON_ARRAY_LENGTH) {
62 parseResult = ERR_APPEXECFWK_PARSE_PROFILE_PROP_SIZE_CHECK_ERROR;
63 return;
64 }
65 switch (arrayType) {
66 case ArrayType::STRING:
67 for (const auto &array : arrays) {
68 if (!array.is_string()) {
69 APP_LOGE("%{public}s not string", key.c_str());
70 parseResult = ERR_APPEXECFWK_PARSE_PROFILE_PROP_TYPE_ERROR;
71 }
72 }
73 if (parseResult == ERR_OK) {
74 data = jsonObject.at(key).get<T>();
75 }
76 break;
77 case ArrayType::OBJECT:
78 for (const auto &array : arrays) {
79 if (!array.is_object()) {
80 APP_LOGE("%{public}s not object", key.c_str());
81 parseResult = ERR_APPEXECFWK_PARSE_PROFILE_PROP_TYPE_ERROR;
82 break;
83 }
84 }
85 if (parseResult == ERR_OK) {
86 data = jsonObject.at(key).get<T>();
87 }
88 break;
89 case ArrayType::NUMBER:
90 for (const auto &array : arrays) {
91 if (!array.is_number()) {
92 APP_LOGE("%{public}s not number", key.c_str());
93 parseResult = ERR_APPEXECFWK_PARSE_PROFILE_PROP_TYPE_ERROR;
94 }
95 }
96 if (parseResult == ERR_OK) {
97 data = jsonObject.at(key).get<T>();
98 }
99 break;
100 case ArrayType::NOT_ARRAY:
101 APP_LOGE("%{public}s not string", key.c_str());
102 break;
103 default:
104 APP_LOGE("%{public}s error", key.c_str());
105 break;
106 }
107 }
108
109 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)110 void GetValueIfFindKey(const nlohmann::json &jsonObject, const nlohmann::detail::iter_impl<const nlohmann::json> &end,
111 const std::string &key, dataType &data, JsonType jsonType, bool isNecessary, int32_t &parseResult,
112 ArrayType arrayType)
113 {
114 if (parseResult) {
115 return;
116 }
117 if (jsonObject.find(key) != end) {
118 switch (jsonType) {
119 case JsonType::NUMBER:
120 if (!jsonObject.at(key).is_number()) {
121 APP_LOGE("type error %{public}s not number", key.c_str());
122 parseResult = ERR_APPEXECFWK_PARSE_PROFILE_PROP_TYPE_ERROR;
123 break;
124 }
125 data = jsonObject.at(key).get<T>();
126 break;
127 case JsonType::OBJECT:
128 if (!jsonObject.at(key).is_object()) {
129 APP_LOGE("type error %{public}s not object", key.c_str());
130 parseResult = ERR_APPEXECFWK_PARSE_PROFILE_PROP_TYPE_ERROR;
131 break;
132 }
133 data = jsonObject.at(key).get<T>();
134 break;
135 case JsonType::ARRAY:
136 if (!jsonObject.at(key).is_array()) {
137 APP_LOGE("type error %{public}s not array", key.c_str());
138 parseResult = ERR_APPEXECFWK_PARSE_PROFILE_PROP_TYPE_ERROR;
139 break;
140 }
141 CheckArrayType<T>(jsonObject, key, data, arrayType, parseResult);
142 break;
143 case JsonType::NULLABLE:
144 APP_LOGE("type error %{public}s nullable", key.c_str());
145 break;
146 default:
147 APP_LOGE("type error %{public}s not jsonType", key.c_str());
148 parseResult = ERR_APPEXECFWK_PARSE_PROFILE_PROP_TYPE_ERROR;
149 }
150 return;
151 }
152 if (isNecessary) {
153 APP_LOGE("profile prop %{public}s mission", key.c_str());
154 parseResult = ERR_APPEXECFWK_PARSE_PROFILE_MISSING_PROP;
155 }
156 }
157
158 template<typename T>
GetJsonStrFromInfo(T & t)159 const std::string GetJsonStrFromInfo(T &t)
160 {
161 nlohmann::json json = t;
162 return json.dump();
163 }
164
165 template<typename T>
ParseInfoFromJsonStr(const char * data,T & t)166 bool ParseInfoFromJsonStr(const char *data, T &t)
167 {
168 if (data == nullptr) {
169 APP_LOGE("data is nullptr");
170 return false;
171 }
172
173 nlohmann::json jsonObject = nlohmann::json::parse(data, nullptr, false);
174 if (jsonObject.is_discarded()) {
175 APP_LOGE("jsonObject discarded");
176 return false;
177 }
178
179 t = jsonObject.get<T>();
180 return true;
181 }
182
183 template<typename T, typename dataType>
GetBigStringIfFindKey(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)184 void GetBigStringIfFindKey(const nlohmann::json &jsonObject,
185 const nlohmann::detail::iter_impl<const nlohmann::json> &end, const std::string &key, dataType &data,
186 JsonType jsonType, bool isNecessary, int32_t &parseResult, ArrayType arrayType)
187 {
188 if (parseResult) {
189 return;
190 }
191 if (jsonObject.find(key) != end) {
192 switch (jsonType) {
193 case JsonType::STRING:
194 if (!jsonObject.at(key).is_string()) {
195 APP_LOGE("type error %{public}s not string", key.c_str());
196 parseResult = ERR_APPEXECFWK_PARSE_PROFILE_PROP_TYPE_ERROR;
197 break;
198 }
199 data = jsonObject.at(key).get<T>();
200 break;
201 default:
202 APP_LOGE("type error %{public}s not jsonType", key.c_str());
203 parseResult = ERR_APPEXECFWK_PARSE_PROFILE_PROP_TYPE_ERROR;
204 }
205 return;
206 }
207 if (isNecessary) {
208 APP_LOGE("profile prop %{public}s mission", key.c_str());
209 parseResult = ERR_APPEXECFWK_PARSE_PROFILE_MISSING_PROP;
210 }
211 }
212 } // namespace AppExecFwk
213 } // namespace OHOS
214 #endif // FOUNDATION_APPEXECFWK_INTERFACES_INNERKITS_APPEXECFWK_BASE_INCLUDE_JSON_UTIL_H