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 "comm_log.h"
19 #include "nlohmann/json.hpp"
20 #include "securec.h"
21 #include "softbus_adapter_mem.h"
22
23
JSON_CreateObject(void)24 JsonObj *JSON_CreateObject(void)
25 {
26 JsonObj *obj = new (std::nothrow) JsonObj();
27 if (obj == nullptr) {
28 COMM_LOGE(COMM_ADAPTER, "new JsonObj fail");
29 return nullptr;
30 }
31 nlohmann::json *json = new (std::nothrow) nlohmann::json();
32 if (json == nullptr) {
33 COMM_LOGE(COMM_ADAPTER, "new nlohmann fail");
34 delete obj;
35 obj = nullptr;
36 return nullptr;
37 }
38 obj->context = reinterpret_cast<void *>(json);
39 return obj;
40 }
41
JSON_Delete(JsonObj * obj)42 void JSON_Delete(JsonObj *obj)
43 {
44 if (obj == nullptr) {
45 return;
46 }
47 if (obj->context != nullptr) {
48 nlohmann::json *json = reinterpret_cast<nlohmann::json *>(obj->context);
49 if (json != nullptr) {
50 delete json;
51 }
52 obj->context = nullptr;
53 }
54 delete obj;
55 obj = nullptr;
56 }
57
JSON_Free(void * obj)58 void JSON_Free(void *obj)
59 {
60 if (obj != nullptr) {
61 SoftBusFree(obj);
62 }
63 }
64
JSON_PrintUnformatted(const JsonObj * obj)65 char *JSON_PrintUnformatted(const JsonObj *obj)
66 {
67 if (obj == nullptr) {
68 COMM_LOGE(COMM_ADAPTER, "invalid param");
69 return nullptr;
70 }
71 nlohmann::json *json = reinterpret_cast<nlohmann::json *>(obj->context);
72 if (json == nullptr) {
73 COMM_LOGE(COMM_ADAPTER, "invaild json param");
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 COMM_LOGE(COMM_ADAPTER, "malloc array fail");
81 return nullptr;
82 }
83 if (strcpy_s(result, jsonString.length() + 1, jsonString.c_str()) != EOK) {
84 COMM_LOGE(COMM_ADAPTER, "strcpy json string fail");
85 SoftBusFree(result);
86 return nullptr;
87 }
88 return result;
89 }
90
JSON_Parse(const char * str,uint32_t len)91 JsonObj *JSON_Parse(const char *str, uint32_t len)
92 {
93 JsonObj *obj = JSON_CreateObject();
94 if (obj == nullptr) {
95 COMM_LOGE(COMM_ADAPTER, "create json object fail");
96 return nullptr;
97 }
98 nlohmann::json *json = reinterpret_cast<nlohmann::json *>(obj->context);
99 if (json == nullptr) {
100 JSON_Delete(obj);
101 COMM_LOGE(COMM_ADAPTER, "cast json fail");
102 return nullptr;
103 }
104 std::string jsonString(str, len);
105 nlohmann::json entity = nlohmann::json::parse(jsonString, nullptr, false);
106 if (entity.is_discarded()) {
107 JSON_Delete(obj);
108 COMM_LOGE(COMM_ADAPTER, "parse json fail");
109 return nullptr;
110 }
111 for (auto &item : entity.items()) {
112 (*json)[item.key()] = item.value();
113 }
114 return obj;
115 }
116
JSON_AddBoolToObject(JsonObj * obj,const char * key,bool value)117 bool JSON_AddBoolToObject(JsonObj *obj, const char *key, bool value)
118 {
119 if (obj == nullptr || key == nullptr) {
120 COMM_LOGE(COMM_ADAPTER, "invalid param");
121 return false;
122 }
123 nlohmann::json *json = reinterpret_cast<nlohmann::json *>(obj->context);
124 if (json == nullptr) {
125 COMM_LOGE(COMM_ADAPTER, "invaild json param");
126 return false;
127 }
128 (*json)[key] = value;
129 return true;
130 }
131
JSON_GetBoolFromOject(const JsonObj * obj,const char * key,bool * value)132 bool JSON_GetBoolFromOject(const JsonObj *obj, const char *key, bool *value)
133 {
134 if (obj == nullptr || key == nullptr || value == nullptr) {
135 COMM_LOGE(COMM_ADAPTER, "invalid param");
136 return false;
137 }
138 nlohmann::json *json = reinterpret_cast<nlohmann::json *>(obj->context);
139 if (json == nullptr) {
140 COMM_LOGE(COMM_ADAPTER, "invaild json param");
141 return false;
142 }
143 nlohmann::json item = (*json)[key];
144 if (!item.is_boolean()) {
145 COMM_LOGE(COMM_ADAPTER, "Cannot find or invalid key. key=%{public}s", key);
146 return false;
147 }
148 *value = item.get<bool>();
149 return true;
150 }
151
152 template <typename Integer>
JSON_AddIntegerToObject(JsonObj * obj,const char * key,Integer num)153 static bool JSON_AddIntegerToObject(JsonObj *obj, const char *key, Integer num)
154 {
155 if (obj == nullptr || key == nullptr) {
156 COMM_LOGE(COMM_ADAPTER, "invalid param");
157 return false;
158 }
159 nlohmann::json *json = reinterpret_cast<nlohmann::json *>(obj->context);
160 if (json == nullptr) {
161 COMM_LOGE(COMM_ADAPTER, "invaild json param");
162 return false;
163 }
164 (*json)[key] = num;
165 return true;
166 }
167
168 template <typename Integer>
JSON_GetIntegerFromObject(const JsonObj * obj,const char * key,Integer & value)169 static bool JSON_GetIntegerFromObject(const JsonObj *obj, const char *key, Integer &value)
170 {
171 if (obj == nullptr || key == nullptr) {
172 COMM_LOGE(COMM_ADAPTER, "invalid param");
173 return false;
174 }
175 nlohmann::json *json = reinterpret_cast<nlohmann::json *>(obj->context);
176 if (json == nullptr) {
177 COMM_LOGE(COMM_ADAPTER, "invaild json param");
178 return false;
179 }
180 nlohmann::json item = (*json)[key];
181 if (!item.is_number()) {
182 COMM_LOGE(COMM_ADAPTER, "Cannot find or invalid key. key=%{public}s", key);
183 return false;
184 }
185 value = item.get<Integer>();
186 return true;
187 }
188
JSON_AddInt16ToObject(JsonObj * obj,const char * key,int16_t value)189 bool JSON_AddInt16ToObject(JsonObj *obj, const char *key, int16_t value)
190 {
191 return JSON_AddIntegerToObject(obj, key, value);
192 }
193
JSON_GetInt16FromOject(const JsonObj * obj,const char * key,int16_t * value)194 bool JSON_GetInt16FromOject(const JsonObj *obj, const char *key, int16_t *value)
195 {
196 if (value == nullptr) {
197 COMM_LOGE(COMM_ADAPTER, "invalid param");
198 return false;
199 }
200 return JSON_GetIntegerFromObject(obj, key, *value);
201 }
202
JSON_AddInt32ToObject(JsonObj * obj,const char * key,int32_t value)203 bool JSON_AddInt32ToObject(JsonObj *obj, const char *key, int32_t value)
204 {
205 return JSON_AddIntegerToObject(obj, key, value);
206 }
207
JSON_GetInt32FromOject(const JsonObj * obj,const char * key,int32_t * value)208 bool JSON_GetInt32FromOject(const JsonObj *obj, const char *key, int32_t *value)
209 {
210 if (value == nullptr) {
211 COMM_LOGE(COMM_ADAPTER, "invalid param");
212 return false;
213 }
214 return JSON_GetIntegerFromObject(obj, key, *value);
215 }
216
JSON_AddInt64ToObject(JsonObj * obj,const char * key,int64_t value)217 bool JSON_AddInt64ToObject(JsonObj *obj, const char *key, int64_t value)
218 {
219 return JSON_AddIntegerToObject(obj, key, value);
220 }
221
JSON_GetInt64FromOject(const JsonObj * obj,const char * key,int64_t * value)222 bool JSON_GetInt64FromOject(const JsonObj *obj, const char *key, int64_t *value)
223 {
224 if (value == nullptr) {
225 COMM_LOGE(COMM_ADAPTER, "invalid param");
226 return false;
227 }
228 return JSON_GetIntegerFromObject(obj, key, *value);
229 }
230
JSON_AddStringToObject(JsonObj * obj,const char * key,const char * value)231 bool JSON_AddStringToObject(JsonObj *obj, const char *key, const char *value)
232 {
233 if (obj == nullptr || key == nullptr || value == nullptr) {
234 COMM_LOGE(COMM_ADAPTER, "invalid param");
235 return false;
236 }
237 nlohmann::json *json = reinterpret_cast<nlohmann::json *>(obj->context);
238 if (json == nullptr) {
239 COMM_LOGE(COMM_ADAPTER, "invaild json param");
240 return false;
241 }
242 (*json)[key] = std::string(value);
243 return true;
244 }
245
JSON_GetStringFromOject(const JsonObj * obj,const char * key,char * value,uint32_t size)246 bool JSON_GetStringFromOject(const JsonObj *obj, const char *key, char *value, uint32_t size)
247 {
248 if (obj == nullptr || key == nullptr || value == nullptr) {
249 COMM_LOGE(COMM_ADAPTER, "invalid param");
250 return false;
251 }
252 nlohmann::json *json = reinterpret_cast<nlohmann::json *>(obj->context);
253 if (json == nullptr) {
254 COMM_LOGE(COMM_ADAPTER, "invaild json param");
255 return false;
256 }
257 nlohmann::json item = (*json)[key];
258 if (!item.is_string()) {
259 COMM_LOGD(COMM_ADAPTER, "cannot find or invalid key. key=%{public}s", key);
260 return false;
261 }
262 std::string valueString = item.get<std::string>();
263 if (strcpy_s(value, size, valueString.c_str()) != EOK) {
264 COMM_LOGE(COMM_ADAPTER, "strcpy value err, key=%{public}s, size=%{public}u, value=%{public}s",
265 key, size, valueString.c_str());
266 return false;
267 }
268 return true;
269 }
270
JSON_AddStringArrayToObject(JsonObj * obj,const char * key,const char ** value,int32_t len)271 bool JSON_AddStringArrayToObject(JsonObj *obj, const char *key, const char **value, int32_t len)
272 {
273 if (value == nullptr || obj == nullptr || key == nullptr || len <= 0) {
274 COMM_LOGE(COMM_ADAPTER, "input invalid");
275 return false;
276 }
277 nlohmann::json *json = reinterpret_cast<nlohmann::json *>(obj->context);
278 if (json == nullptr) {
279 COMM_LOGE(COMM_ADAPTER, "invaild json param");
280 return false;
281 }
282 nlohmann::json valueStringArray = nlohmann::json::array();
283 for (int32_t i = 0; i < len; i++) {
284 valueStringArray.push_back(value[i]);
285 }
286 (*json)[key] = valueStringArray;
287 return true;
288 }
289
JSON_GetStringArrayFromOject(const JsonObj * obj,const char * key,char ** value,int32_t * len)290 bool JSON_GetStringArrayFromOject(const JsonObj *obj, const char *key, char **value, int32_t *len)
291 {
292 if (value == nullptr || obj == nullptr || key == nullptr || len == nullptr || *len <= 0) {
293 COMM_LOGE(COMM_ADAPTER, "input invalid");
294 return false;
295 }
296 nlohmann::json *json = reinterpret_cast<nlohmann::json *>(obj->context);
297 if (json == nullptr) {
298 COMM_LOGE(COMM_ADAPTER, "invaild json param");
299 return false;
300 }
301 nlohmann::json item = (*json)[key];
302 if (!item.is_array()) {
303 COMM_LOGE(COMM_ADAPTER, "cannot find or invalid key. key=%{public}s", key);
304 return false;
305 }
306 if ((unsigned long)(*len) < (unsigned long)item.size()) {
307 COMM_LOGE(COMM_ADAPTER, "item size invalid, size=%{public}lu.", (unsigned long)item.size());
308 return false;
309 }
310 int32_t i = 0;
311 for (nlohmann::json::iterator it = item.begin(); it != item.end(); ++it) {
312 std::string str = it.value().get<std::string>();
313 const char *valueString = str.c_str();
314 uint32_t valueLen = strlen(valueString) + 1;
315 value[i] = reinterpret_cast<char *>(SoftBusCalloc(valueLen));
316 if (value[i] == nullptr) {
317 return false;
318 }
319 if (strcpy_s(value[i], valueLen, valueString) != EOK) {
320 COMM_LOGE(COMM_ADAPTER, "strcpy value err. key=%{public}s, value=%{public}s", key, valueString);
321 return false;
322 }
323 i++;
324 }
325 *len = item.size();
326 return true;
327 }
328
JSON_AddBytesToObject(JsonObj * obj,const char * key,uint8_t * value,uint32_t size)329 bool JSON_AddBytesToObject(JsonObj *obj, const char *key, uint8_t *value, uint32_t size)
330 {
331 if (obj == nullptr || key == nullptr || value == nullptr || size == 0) {
332 COMM_LOGE(COMM_ADAPTER, "input invalid");
333 return false;
334 }
335 std::vector<uint8_t> bytes(value, value + size);
336 nlohmann::json *json = reinterpret_cast<nlohmann::json *>(obj->context);
337 if (json == nullptr) {
338 COMM_LOGE(COMM_ADAPTER, "invalid json param");
339 return false;
340 }
341 (*json)[key] = bytes;
342 return true;
343 }
344
JSON_GetBytesFromObject(const JsonObj * obj,const char * key,uint8_t * value,uint32_t bufLen,uint32_t * size)345 bool JSON_GetBytesFromObject(const JsonObj *obj, const char *key, uint8_t *value, uint32_t bufLen, uint32_t *size)
346 {
347 if (obj == nullptr || key == nullptr || value == nullptr || bufLen == 0 || size == nullptr) {
348 COMM_LOGE(COMM_ADAPTER, "input invalid");
349 return false;
350 }
351 nlohmann::json *json = reinterpret_cast<nlohmann::json *>(obj->context);
352 if (json == nullptr) {
353 COMM_LOGE(COMM_ADAPTER, "invaild json param");
354 return false;
355 }
356 if (json->count(key) <= 0) {
357 COMM_LOGE(COMM_ADAPTER, "key does not exist");
358 return false;
359 }
360 std::vector<uint8_t> bytes = (*json)[key];
361 if (bufLen < bytes.size()) {
362 COMM_LOGE(COMM_ADAPTER, "item size invalid, size=%{public}zu", bytes.size());
363 return false;
364 }
365 if (memcpy_s(value, bufLen, bytes.data(), bytes.size()) != EOK) {
366 COMM_LOGE(COMM_ADAPTER, "memcpy fail");
367 return false;
368 }
369 *size = bytes.size();
370 return true;
371 }
372
JSON_IsArrayExist(const JsonObj * obj,const char * key)373 bool JSON_IsArrayExist(const JsonObj *obj, const char *key)
374 {
375 if (obj == nullptr || key == nullptr) {
376 COMM_LOGE(COMM_ADAPTER, "input invalid");
377 return false;
378 }
379 nlohmann::json *json = reinterpret_cast<nlohmann::json *>(obj->context);
380 if (json == nullptr) {
381 COMM_LOGE(COMM_ADAPTER, "invaild json param");
382 return false;
383 }
384 if (!json->contains(key)) {
385 COMM_LOGW(COMM_ADAPTER, "key does not exist");
386 return false;
387 }
388 nlohmann::json item = (*json)[key];
389 return item.is_array();
390 }