1/* 2 * Copyright (c) 2021 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 "base/json/json_util.h" 17 18#include "cJSON.h" 19 20namespace OHOS::Ace { 21 22JsonValue::JsonValue(JsonObject* object) : object_(object) {} 23 24JsonValue::JsonValue(JsonObject* object, bool isRoot) : object_(object), isRoot_(isRoot) {} 25 26JsonValue::~JsonValue() 27{ 28 if (object_ != nullptr && isRoot_) { 29 cJSON_Delete(object_); 30 } 31 object_ = nullptr; 32} 33 34bool JsonValue::IsBool() const 35{ 36 return cJSON_IsBool(object_); 37} 38 39bool JsonValue::IsNumber() const 40{ 41 return cJSON_IsNumber(object_); 42} 43 44bool JsonValue::IsString() const 45{ 46 return cJSON_IsString(object_); 47} 48 49bool JsonValue::IsArray() const 50{ 51 return cJSON_IsArray(object_); 52} 53 54bool JsonValue::IsObject() const 55{ 56 return cJSON_IsObject(object_); 57} 58 59bool JsonValue::IsValid() const 60{ 61 return (object_ != nullptr) && !cJSON_IsInvalid(object_); 62} 63 64bool JsonValue::IsNull() const 65{ 66 return (object_ == nullptr) || cJSON_IsNull(object_); 67} 68 69bool JsonValue::Contains(const std::string& key) const 70{ 71 return cJSON_HasObjectItem(object_, key.c_str()); 72} 73 74bool JsonValue::GetBool() const 75{ 76 return cJSON_IsTrue(object_) != 0; 77} 78 79bool JsonValue::GetBool(const std::string& key, bool defaultValue) const 80{ 81 if (Contains(key) && GetValue(key)->IsBool()) { 82 return GetValue(key)->GetBool(); 83 } 84 return defaultValue; 85} 86 87int32_t JsonValue::GetInt() const 88{ 89 return static_cast<int32_t>((object_ == nullptr) ? 0 : object_->valuedouble); 90} 91 92uint32_t JsonValue::GetUInt() const 93{ 94 return static_cast<uint32_t>((object_ == nullptr) ? 0 : object_->valuedouble); 95} 96 97int64_t JsonValue::GetInt64() const 98{ 99 return static_cast<int64_t>((object_ == nullptr) ? 0 : object_->valuedouble); 100} 101 102double JsonValue::GetDouble() const 103{ 104 return (object_ == nullptr) ? 0.0 : object_->valuedouble; 105} 106 107double JsonValue::GetDouble(const std::string& key, double defaultVal) const 108{ 109 auto value = GetValue(key); 110 if (value && value->IsNumber()) { 111 return value->GetDouble(); 112 } 113 return defaultVal; 114} 115 116std::string JsonValue::GetString() const 117{ 118 return ((object_ == nullptr) || (object_->valuestring == nullptr)) ? "" : std::string(object_->valuestring); 119} 120 121std::unique_ptr<JsonValue> JsonValue::GetNext() const 122{ 123 if (object_ == nullptr) { 124 return std::make_unique<JsonValue>(nullptr); 125 } 126 return std::make_unique<JsonValue>(object_->next); 127} 128 129std::unique_ptr<JsonValue> JsonValue::GetChild() const 130{ 131 if (object_ == nullptr) { 132 return std::make_unique<JsonValue>(nullptr); 133 } 134 return std::make_unique<JsonValue>(object_->child); 135} 136 137std::string JsonValue::GetKey() const 138{ 139 return ((object_ == nullptr) || (object_->string == nullptr)) ? "" : std::string(object_->string); 140} 141std::unique_ptr<JsonValue> JsonValue::GetValue(const std::string& key) const 142{ 143 return std::make_unique<JsonValue>(cJSON_GetObjectItem(object_, key.c_str())); 144} 145 146std::unique_ptr<JsonValue> JsonValue::GetObject(const std::string& key) const 147{ 148 if (Contains(key) && GetValue(key)->IsObject()) { 149 return GetValue(key); 150 } 151 return std::make_unique<JsonValue>(); 152} 153 154int32_t JsonValue::GetArraySize() const 155{ 156 return cJSON_GetArraySize(object_); 157} 158 159std::unique_ptr<JsonValue> JsonValue::GetArrayItem(int32_t index) const 160{ 161 return std::make_unique<JsonValue>(cJSON_GetArrayItem(object_, index)); 162} 163 164bool JsonValue::Put(const char* key, const char* value) 165{ 166 if (!value || !key) { 167 return false; 168 } 169 170 cJSON* child = cJSON_CreateString(value); 171 if (child == nullptr) { 172 return false; 173 } 174 cJSON_AddItemToObject(object_, key, child); 175 return true; 176} 177 178bool JsonValue::PutFixedAttr(const char* key, const char* value, 179 const NG::InspectorFilter& filter, NG::FixedAttrBit attr) 180{ 181 if (filter.CheckFixedAttr(attr)) { 182 return Put(key, value); 183 } 184 return false; 185} 186 187bool JsonValue::PutExtAttr(const char* key, const char* value, const NG::InspectorFilter& filter) 188{ 189 if (filter.CheckExtAttr(key)) { 190 return Put(key, value); 191 } 192 return false; 193} 194 195const JsonObject* JsonValue::GetJsonObject() const 196{ 197 return object_; 198} 199 200bool JsonValue::Put(const char* key, const std::unique_ptr<JsonValue>& value) 201{ 202 if (!value || !key) { 203 return false; 204 } 205 cJSON* jsonObject = cJSON_Duplicate(value->GetJsonObject(), true); 206 if (jsonObject == nullptr) { 207 return false; 208 } 209 210 cJSON_AddItemToObject(object_, key, jsonObject); 211 return true; 212} 213 214bool JsonValue::PutFixedAttr(const char* key, const std::unique_ptr<JsonValue>& value, 215 const NG::InspectorFilter& filter, NG::FixedAttrBit attr) 216{ 217 if (filter.CheckFixedAttr(attr)) { 218 return Put(key, value); 219 } 220 return false; 221} 222 223bool JsonValue::PutExtAttr(const char* key, const std::unique_ptr<JsonValue>& value, 224 const NG::InspectorFilter& filter) 225{ 226 if (filter.CheckExtAttr(key)) { 227 return Put(key, value); 228 } 229 return false; 230} 231 232// add item to array 233bool JsonValue::Put(const std::unique_ptr<JsonValue>& value) 234{ 235 if (!value) { 236 return false; 237 } 238 cJSON* jsonObject = cJSON_Duplicate(value->GetJsonObject(), true); 239 if (jsonObject == nullptr) { 240 return false; 241 } 242 243 cJSON_AddItemToArray(object_, jsonObject); 244 return true; 245} 246 247bool JsonValue::Put(const char* key, size_t value) 248{ 249 if (key == nullptr) { 250 return false; 251 } 252 253 cJSON* child = cJSON_CreateNumber(static_cast<double>(value)); 254 if (child == nullptr) { 255 return false; 256 } 257 cJSON_AddItemToObject(object_, key, child); 258 return true; 259} 260 261bool JsonValue::PutFixedAttr(const char* key, size_t value, 262 const NG::InspectorFilter& filter, NG::FixedAttrBit attr) 263{ 264 if (filter.CheckFixedAttr(attr)) { 265 return Put(key, value); 266 } 267 return false; 268} 269 270bool JsonValue::PutExtAttr(const char* key, size_t value, const NG::InspectorFilter& filter) 271{ 272 if (filter.CheckExtAttr(key)) { 273 return Put(key, value); 274 } 275 return false; 276} 277 278bool JsonValue::Put(const char* key, int32_t value) 279{ 280 if (key == nullptr) { 281 return false; 282 } 283 284 cJSON* child = cJSON_CreateNumber(static_cast<double>(value)); 285 if (child == nullptr) { 286 return false; 287 } 288 cJSON_AddItemToObject(object_, key, child); 289 return true; 290} 291 292bool JsonValue::PutFixedAttr(const char* key, int32_t value, 293 const NG::InspectorFilter& filter, NG::FixedAttrBit attr) 294{ 295 if (filter.CheckFixedAttr(attr)) { 296 return Put(key, value); 297 } 298 return false; 299} 300 301bool JsonValue::PutExtAttr(const char* key, int32_t value, const NG::InspectorFilter& filter) 302{ 303 if (filter.CheckExtAttr(key)) { 304 return Put(key, value); 305 } 306 return false; 307} 308 309bool JsonValue::Put(const char* key, int64_t value) 310{ 311 return Put(key, static_cast<double>(value)); 312} 313 314bool JsonValue::PutFixedAttr(const char* key, int64_t value, 315 const NG::InspectorFilter& filter, NG::FixedAttrBit attr) 316{ 317 if (filter.CheckFixedAttr(attr)) { 318 return Put(key, value); 319 } 320 return false; 321} 322 323bool JsonValue::PutExtAttr(const char* key, int64_t value, const NG::InspectorFilter& filter) 324{ 325 if (filter.CheckExtAttr(key)) { 326 return Put(key, value); 327 } 328 return false; 329} 330 331bool JsonValue::Put(const char* key, double value) 332{ 333 if (key == nullptr) { 334 return false; 335 } 336 337 cJSON* child = cJSON_CreateNumber(value); 338 if (child == nullptr) { 339 return false; 340 } 341 cJSON_AddItemToObject(object_, key, child); 342 return true; 343} 344 345bool JsonValue::PutFixedAttr(const char* key, double value, 346 const NG::InspectorFilter& filter, NG::FixedAttrBit attr) 347{ 348 if (filter.CheckFixedAttr(attr)) { 349 return Put(key, value); 350 } 351 return false; 352} 353 354bool JsonValue::PutExtAttr(const char* key, double value, const NG::InspectorFilter& filter) 355{ 356 if (filter.CheckExtAttr(key)) { 357 return Put(key, value); 358 } 359 return false; 360} 361 362JsonObject* JsonValue::ReleaseJsonObject() 363{ 364 if (!isRoot_) { 365 return nullptr; 366 } 367 JsonObject* object = object_; 368 object_ = nullptr; 369 return object; 370} 371 372bool JsonValue::PutRef(const char* key, std::unique_ptr<JsonValue>&& value) 373{ 374 if (key == nullptr || value == nullptr) { 375 return false; 376 } 377 /* 378 * If value is root, it controls the lifecycle of JsonObject, we can just move it into current object 379 * Else we need to copy the JsonObject and put the new object in current object 380 */ 381 if (value->isRoot_) { 382 cJSON_AddItemToObject(object_, key, value->ReleaseJsonObject()); 383 return true; 384 } else { 385 std::unique_ptr<JsonValue> lValue = std::move(value); 386 return Put(key, lValue); 387 } 388} 389 390bool JsonValue::PutRef(std::unique_ptr<JsonValue>&& value) 391{ 392 if (value == nullptr) { 393 return false; 394 } 395 /* 396 * If value is root, it controls the lifecycle of JsonObject, we can just move it into current object 397 * Else we need to copy the JsonObject and put the new object in current object 398 */ 399 if (value->isRoot_) { 400 cJSON_AddItemToArray(object_, value->ReleaseJsonObject()); 401 return true; 402 } else { 403 std::unique_ptr<JsonValue> lValue = std::move(value); 404 return Put(lValue); 405 } 406} 407 408bool JsonValue::Replace(const char* key, double value) 409{ 410 if (key == nullptr) { 411 return false; 412 } 413 414 cJSON* child = cJSON_CreateNumber(value); 415 if (child == nullptr) { 416 return false; 417 } 418 if (!cJSON_ReplaceItemInObject(object_, key, child)) { 419 cJSON_Delete(child); 420 return false; 421 } 422 return true; 423} 424 425bool JsonValue::Put(const char* key, bool value) 426{ 427 if (key == nullptr) { 428 return false; 429 } 430 431 cJSON* child = cJSON_CreateBool(value); 432 if (child == nullptr) { 433 return false; 434 } 435 cJSON_AddItemToObject(object_, key, child); 436 return true; 437} 438 439bool JsonValue::PutFixedAttr(const char* key, bool value, 440 const NG::InspectorFilter& filter, NG::FixedAttrBit attr) 441{ 442 if (filter.CheckFixedAttr(attr)) { 443 return Put(key, value); 444 } 445 return false; 446} 447 448bool JsonValue::PutExtAttr(const char* key, bool value, const NG::InspectorFilter& filter) 449{ 450 if (filter.CheckExtAttr(key)) { 451 return Put(key, value); 452 } 453 return false; 454} 455 456bool JsonValue::Replace(const char* key, bool value) 457{ 458 if (key == nullptr) { 459 return false; 460 } 461 462 cJSON* child = cJSON_CreateBool(value); 463 if (child == nullptr) { 464 return false; 465 } 466 if (!cJSON_ReplaceItemInObject(object_, key, child)) { 467 cJSON_Delete(child); 468 return false; 469 } 470 return true; 471} 472 473bool JsonValue::Replace(const char* key, const char* value) 474{ 475 if ((value == nullptr) || (key == nullptr)) { 476 return false; 477 } 478 479 cJSON* child = cJSON_CreateString(value); 480 if (child == nullptr) { 481 return false; 482 } 483 if (!cJSON_ReplaceItemInObject(object_, key, child)) { 484 cJSON_Delete(child); 485 return false; 486 } 487 return true; 488} 489 490bool JsonValue::Replace(const char* key, int32_t value) 491{ 492 if (key == nullptr) { 493 return false; 494 } 495 496 cJSON* child = cJSON_CreateNumber(static_cast<double>(value)); 497 if (child == nullptr) { 498 return false; 499 } 500 if (!cJSON_ReplaceItemInObject(object_, key, child)) { 501 cJSON_Delete(child); 502 return false; 503 } 504 return true; 505} 506 507bool JsonValue::Replace(const char* key, const std::unique_ptr<JsonValue>& value) 508{ 509 if ((value == nullptr) || (key == nullptr)) { 510 return false; 511 } 512 cJSON* jsonObject = cJSON_Duplicate(value->GetJsonObject(), true); 513 if (jsonObject == nullptr) { 514 return false; 515 } 516 517 if (!cJSON_ReplaceItemInObject(object_, key, jsonObject)) { 518 cJSON_Delete(jsonObject); 519 return false; 520 } 521 return true; 522} 523 524bool JsonValue::Delete(const char* key) 525{ 526 if (key == nullptr) { 527 return false; 528 } 529 cJSON_DeleteItemFromObject(object_, key); 530 return true; 531} 532 533std::string JsonValue::ToString() 534{ 535 std::string result; 536 if (!object_) { 537 return result; 538 } 539 540 // It is null-terminated. 541 char* unformatted = cJSON_PrintUnformatted(object_); 542 if (unformatted != nullptr) { 543 result = unformatted; 544 cJSON_free(unformatted); 545 } 546 return result; 547} 548 549std::string JsonValue::GetString(const std::string& key, const std::string& defaultVal) const 550{ 551 auto value = GetValue(key); 552 if (value && value->IsString()) { 553 return value->GetString(); 554 } 555 return defaultVal; 556} 557 558int32_t JsonValue::GetInt(const std::string& key, int32_t defaultVal) const 559{ 560 auto value = GetValue(key); 561 if (value && value->IsNumber()) { 562 return value->GetInt(); 563 } 564 return defaultVal; 565} 566 567uint32_t JsonValue::GetUInt(const std::string& key, uint32_t defaultVal) const 568{ 569 auto value = GetValue(key); 570 if (value && value->IsNumber()) { 571 return value->GetUInt(); 572 } 573 return defaultVal; 574} 575 576int64_t JsonValue::GetInt64(const std::string& key, int64_t defaultVal) const 577{ 578 auto value = GetValue(key); 579 if (value && value->IsNumber()) { 580 return value->GetInt64(); 581 } 582 return defaultVal; 583} 584 585std::unique_ptr<JsonValue> JsonUtil::ParseJsonData(const char* data, const char** parseEnd) 586{ 587 return std::make_unique<JsonValue>(cJSON_ParseWithOpts(data, parseEnd, true), true); 588} 589 590std::unique_ptr<JsonValue> JsonUtil::ParseJsonString(const std::string& content, const char** parseEnd) 591{ 592 return ParseJsonData(content.c_str(), parseEnd); 593} 594 595std::unique_ptr<JsonValue> JsonUtil::Create(bool isRoot) 596{ 597 return std::make_unique<JsonValue>(cJSON_CreateObject(), isRoot); 598} 599 600std::unique_ptr<JsonValue> JsonUtil::CreateArray(bool isRoot) 601{ 602 return std::make_unique<JsonValue>(cJSON_CreateArray(), isRoot); 603} 604 605} // namespace OHOS::Ace 606