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