• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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