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 26JsonObj *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 44void 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 60void JSON_Free(void *obj) 61{ 62 if (obj != nullptr) { 63 SoftBusFree(obj); 64 } 65} 66 67char *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 93JsonObj *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 119bool 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 134bool 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 154template <typename Integer> 155static 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 170template <typename Integer> 171static 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 191bool JSON_AddInt16ToObject(JsonObj *obj, const char *key, int16_t value) 192{ 193 return JSON_AddIntegerToObject(obj, key, value); 194} 195 196bool 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 205bool JSON_AddInt32ToObject(JsonObj *obj, const char *key, int32_t value) 206{ 207 return JSON_AddIntegerToObject(obj, key, value); 208} 209 210bool 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 219bool JSON_AddInt64ToObject(JsonObj *obj, const char *key, int64_t value) 220{ 221 return JSON_AddIntegerToObject(obj, key, value); 222} 223 224bool 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 233bool 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 248bool 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 273bool 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 292bool 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 331bool 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 347bool 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} 374 375bool JSON_IsArrayExist(const JsonObj *obj, const char *key) 376{ 377 if (obj == nullptr || key == nullptr) { 378 COMM_LOGE(COMM_ADAPTER, "input invalid"); 379 return false; 380 } 381 nlohmann::json *json = reinterpret_cast<nlohmann::json *>(obj->context); 382 if (json == nullptr) { 383 COMM_LOGE(COMM_ADAPTER, "invaild json param"); 384 return false; 385 } 386 if (!json->contains(key)) { 387 COMM_LOGW(COMM_ADAPTER, "key does not exist"); 388 return false; 389 } 390 nlohmann::json item = (*json)[key]; 391 return item.is_array(); 392}