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 #include "softbus_adapter_json.h"
17
18 #include "nlohmann/json.hpp"
19 #include "securec.h"
20 #include "softbus_adapter_log.h"
21 #include "softbus_adapter_mem.h"
22
23 #define JSON_LOGE(fmt, ...) HILOG_ERROR(SOFTBUS_HILOG_ID, "[%{public}s()] " fmt, __FUNCTION__, ##__VA_ARGS__)
24
JSON_CreateObject(void)25 JsonObj *JSON_CreateObject(void)
26 {
27 JsonObj *obj = new (std::nothrow) JsonObj();
28 if (obj == nullptr) {
29 JSON_LOGE("new JsonObj fail");
30 return nullptr;
31 }
32 nlohmann::json *json = new (std::nothrow) nlohmann::json();
33 if (json == nullptr) {
34 JSON_LOGE("new nlohmann fail");
35 delete obj;
36 obj = nullptr;
37 return nullptr;
38 }
39 obj->context = reinterpret_cast<void *>(json);
40 return obj;
41 }
42
JSON_Delete(JsonObj * obj)43 void JSON_Delete(JsonObj *obj)
44 {
45 if (obj == nullptr) {
46 return;
47 }
48 if (obj->context != nullptr) {
49 nlohmann::json *json = reinterpret_cast<nlohmann::json *>(obj->context);
50 if (json != nullptr) {
51 delete json;
52 }
53 obj->context = nullptr;
54 }
55 delete obj;
56 obj = nullptr;
57 }
58
JSON_Free(void * obj)59 void JSON_Free(void *obj)
60 {
61 if (obj != nullptr) {
62 SoftBusFree(obj);
63 }
64 }
65
JSON_PrintUnformatted(const JsonObj * obj)66 char *JSON_PrintUnformatted(const JsonObj *obj)
67 {
68 if (obj == nullptr) {
69 JSON_LOGE("invalid param");
70 return nullptr;
71 }
72 nlohmann::json *json = reinterpret_cast<nlohmann::json *>(obj->context);
73 if (json == nullptr) {
74 return nullptr;
75 }
76 std::string jsonString = json->dump();
77
78 char *result = (char *)SoftBusCalloc(jsonString.length() + 1); /* 1 for '\0' */
79 if (result == nullptr) {
80 JSON_LOGE("malloc array fail");
81 return nullptr;
82 }
83 if (strcpy_s(result, jsonString.length() + 1, jsonString.c_str()) != EOK) {
84 SoftBusFree(result);
85 return nullptr;
86 }
87 return result;
88 }
89
JSON_Parse(const char * str,uint32_t len)90 JsonObj *JSON_Parse(const char *str, uint32_t len)
91 {
92 JsonObj *obj = JSON_CreateObject();
93 if (obj == nullptr) {
94 JSON_LOGE("create json object fail");
95 return nullptr;
96 }
97 nlohmann::json *json = reinterpret_cast<nlohmann::json *>(obj->context);
98 if (json == nullptr) {
99 JSON_Delete(obj);
100 JSON_LOGE("cast json fail");
101 return nullptr;
102 }
103 std::string jsonString(str, len);
104 nlohmann::json entity = nlohmann::json::parse(jsonString, nullptr, false);
105 if (entity.is_discarded()) {
106 JSON_Delete(obj);
107 JSON_LOGE("parse json fail");
108 return nullptr;
109 }
110 for (auto &item : entity.items()) {
111 (*json)[item.key()] = item.value();
112 }
113 return obj;
114 }
115
JSON_AddBoolToObject(JsonObj * obj,const char * key,bool value)116 bool JSON_AddBoolToObject(JsonObj *obj, const char *key, bool value)
117 {
118 if (obj == nullptr || key == nullptr) {
119 JSON_LOGE("invalid param");
120 return false;
121 }
122 nlohmann::json *json = reinterpret_cast<nlohmann::json *>(obj->context);
123 if (json == nullptr) {
124 return false;
125 }
126 (*json)[key] = value;
127 return true;
128 }
129
JSON_GetBoolFromOject(const JsonObj * obj,const char * key,bool * value)130 bool JSON_GetBoolFromOject(const JsonObj *obj, const char *key, bool *value)
131 {
132 if (obj == nullptr || key == nullptr || value == nullptr) {
133 JSON_LOGE("invalid param");
134 return false;
135 }
136 nlohmann::json *json = reinterpret_cast<nlohmann::json *>(obj->context);
137 if (json == nullptr) {
138 return false;
139 }
140 nlohmann::json item = (*json)[key];
141 if (!item.is_boolean()) {
142 JSON_LOGE("Cannot find or invalid [%{public}s]", key);
143 return false;
144 }
145 *value = item.get<bool>();
146 return true;
147 }
148
149 template<typename Integer>
JSON_AddIntegerToObject(JsonObj * obj,const char * key,Integer num)150 static bool JSON_AddIntegerToObject(JsonObj *obj, const char *key, Integer num)
151 {
152 if (obj == nullptr || key == nullptr) {
153 JSON_LOGE("invalid param");
154 return false;
155 }
156 nlohmann::json *json = reinterpret_cast<nlohmann::json *>(obj->context);
157 if (json == nullptr) {
158 return false;
159 }
160 (*json)[key] = num;
161 return true;
162 }
163
164 template<typename Integer>
JSON_GetIntegerFromObject(const JsonObj * obj,const char * key,Integer & value)165 static bool JSON_GetIntegerFromObject(const JsonObj *obj, const char *key, Integer &value)
166 {
167 if (obj == nullptr || key == nullptr) {
168 JSON_LOGE("invalid param");
169 return false;
170 }
171 nlohmann::json *json = reinterpret_cast<nlohmann::json *>(obj->context);
172 if (json == nullptr) {
173 return false;
174 }
175 nlohmann::json item = (*json)[key];
176 if (!item.is_number()) {
177 JSON_LOGE("Cannot find or invalid [%{public}s]", key);
178 return false;
179 }
180 value = item.get<Integer>();
181 return true;
182 }
183
JSON_AddInt16ToObject(JsonObj * obj,const char * key,int16_t value)184 bool JSON_AddInt16ToObject(JsonObj *obj, const char *key, int16_t value)
185 {
186 return JSON_AddIntegerToObject(obj, key, value);
187 }
188
JSON_GetInt16FromOject(const JsonObj * obj,const char * key,int16_t * value)189 bool JSON_GetInt16FromOject(const JsonObj *obj, const char *key, int16_t *value)
190 {
191 if (value == nullptr) {
192 JSON_LOGE("invalid param");
193 return false;
194 }
195 return JSON_GetIntegerFromObject(obj, key, *value);
196 }
197
JSON_AddInt32ToObject(JsonObj * obj,const char * key,int32_t value)198 bool JSON_AddInt32ToObject(JsonObj *obj, const char *key, int32_t value)
199 {
200 return JSON_AddIntegerToObject(obj, key, value);
201 }
202
JSON_GetInt32FromOject(const JsonObj * obj,const char * key,int32_t * value)203 bool JSON_GetInt32FromOject(const JsonObj *obj, const char *key, int32_t *value)
204 {
205 if (value == nullptr) {
206 JSON_LOGE("invalid param");
207 return false;
208 }
209 return JSON_GetIntegerFromObject(obj, key, *value);
210 }
211
JSON_AddInt64ToObject(JsonObj * obj,const char * key,int64_t value)212 bool JSON_AddInt64ToObject(JsonObj *obj, const char *key, int64_t value)
213 {
214 return JSON_AddIntegerToObject(obj, key, value);
215 }
216
JSON_GetInt64FromOject(const JsonObj * obj,const char * key,int64_t * value)217 bool JSON_GetInt64FromOject(const JsonObj *obj, const char *key, int64_t *value)
218 {
219 if (value == nullptr) {
220 JSON_LOGE("invalid param");
221 return false;
222 }
223 return JSON_GetIntegerFromObject(obj, key, *value);
224 }
225
JSON_AddStringToObject(JsonObj * obj,const char * key,const char * value)226 bool JSON_AddStringToObject(JsonObj *obj, const char *key, const char *value)
227 {
228 if (obj == nullptr || key == nullptr || value == nullptr) {
229 JSON_LOGE("invalid param");
230 return false;
231 }
232 nlohmann::json *json = reinterpret_cast<nlohmann::json *>(obj->context);
233 if (json == nullptr) {
234 return false;
235 }
236 (*json)[key] = std::string(value);
237 return true;
238 }
239
JSON_GetStringFromOject(const JsonObj * obj,const char * key,char * value,uint32_t size)240 bool JSON_GetStringFromOject(const JsonObj *obj, const char *key, char *value, uint32_t size)
241 {
242 if (obj == nullptr || key == nullptr || value == nullptr) {
243 JSON_LOGE("invalid param");
244 return false;
245 }
246 nlohmann::json *json = reinterpret_cast<nlohmann::json *>(obj->context);
247 if (json == nullptr) {
248 return false;
249 }
250 nlohmann::json item = (*json)[key];
251 if (!item.is_string()) {
252 JSON_LOGE("cannot find or invalid [%{public}s]", key);
253 return false;
254 }
255 std::string valueString = item.get<std::string>();
256 if (strcpy_s(value, size, valueString.c_str()) != EOK) {
257 JSON_LOGE("strcpy [%{public}s] value err, size=%{public}u, value=%{public}s",
258 key, size, valueString.c_str());
259 return false;
260 }
261 return true;
262 }
263
JSON_AddStringArrayToObject(JsonObj * obj,const char * const key,const char ** value,int32_t len)264 bool JSON_AddStringArrayToObject(JsonObj *obj, const char * const key, const char **value, int32_t len)
265 {
266 if (value == NULL || obj == NULL || key == NULL || len == 0) {
267 JSON_LOGE("input invalid");
268 return false;
269 }
270 nlohmann::json *json = reinterpret_cast<nlohmann::json *>(obj->context);
271 if (json == nullptr) {
272 return false;
273 }
274 nlohmann::json valueStringArray = nlohmann::json::array();
275 for (int32_t i = 0; i < len; i++) {
276 valueStringArray.push_back(value[i]);
277 }
278 (*json)[key] = valueStringArray;
279 return true;
280 }
281
JSON_GetStringArrayFromOject(const JsonObj * obj,const char * const key,char ** value,int32_t * len)282 bool JSON_GetStringArrayFromOject(const JsonObj *obj, const char * const key, char **value, int32_t *len)
283 {
284 if (value == NULL || obj == NULL || key == NULL || len == NULL || *len <= 0) {
285 JSON_LOGE("input invalid");
286 return false;
287 }
288 nlohmann::json *json = reinterpret_cast<nlohmann::json *>(obj->context);
289 if (json == nullptr) {
290 return false;
291 }
292 nlohmann::json item = (*json)[key];
293 if (!item.is_array()) {
294 JSON_LOGE("cannot find or invalid [%{public}s]", key);
295 return false;
296 }
297 if (*len < item.size()) {
298 JSON_LOGE("item size invalid, size=%lu.", (unsigned long)item.size());
299 return false;
300 }
301 int32_t i = 0;
302 for (nlohmann::json::iterator it = item.begin(); it != item.end(); ++it) {
303 std::string str = it.value().get<std::string>();
304 const char *valueString = str.c_str();
305 uint32_t len = strlen(valueString) + 1;
306 value[i] = (char*)SoftBusCalloc(len);
307 if (value[i] == NULL) {
308 return false;
309 }
310 if (strcpy_s(value[i], len, valueString) != EOK) {
311 JSON_LOGE("strcpy [%{public}s] value err, value=%{public}s", key, valueString);
312 return false;
313 }
314 i++;
315 }
316 *len = item.size();
317 return true;
318 }