1/* 2 * Copyright (c) 2022 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 "tooling/base/pt_json.h" 17 18#include "libpandabase/macros.h" 19 20namespace panda::ecmascript::tooling { 21std::unique_ptr<PtJson> PtJson::CreateObject() 22{ 23 return std::make_unique<PtJson>(cJSON_CreateObject()); 24} 25 26std::unique_ptr<PtJson> PtJson::CreateArray() 27{ 28 return std::make_unique<PtJson>(cJSON_CreateArray()); 29} 30 31void PtJson::ReleaseRoot() 32{ 33 if (object_ != nullptr) { 34 cJSON_Delete(object_); 35 object_ = nullptr; 36 } 37} 38 39std::unique_ptr<PtJson> PtJson::Parse(const std::string &data) 40{ 41 cJSON *value = cJSON_ParseWithOpts(data.c_str(), nullptr, true); 42 return std::make_unique<PtJson>(value); 43} 44 45std::string PtJson::Stringify() const 46{ 47 if (object_ == nullptr) { 48 return ""; 49 } 50 51 char *str = cJSON_PrintUnformatted(object_); 52 if (str == nullptr) { 53 return ""; 54 } 55 56 std::string result(str); 57 cJSON_free(str); 58 return result; 59} 60 61bool PtJson::Add(const char *key, bool value) const 62{ 63 ASSERT(key != nullptr && !Contains(key)); 64 65 cJSON *node = cJSON_CreateBool(value); 66 if (node == nullptr) { 67 return false; 68 } 69 70 cJSON_bool ret = cJSON_AddItemToObject(object_, key, node); 71 if (ret == 0) { 72 cJSON_Delete(node); 73 return false; 74 } 75 76 return true; 77} 78 79bool PtJson::Add(const char *key, int32_t value) const 80{ 81 return Add(key, static_cast<double>(value)); 82} 83 84bool PtJson::Add(const char *key, int64_t value) const 85{ 86 return Add(key, static_cast<double>(value)); 87} 88 89bool PtJson::Add(const char *key, uint32_t value) const 90{ 91 return Add(key, static_cast<double>(value)); 92} 93 94bool PtJson::Add(const char *key, double value) const 95{ 96 ASSERT(key != nullptr && !Contains(key)); 97 98 cJSON *node = cJSON_CreateNumber(value); 99 if (node == nullptr) { 100 return false; 101 } 102 103 cJSON_bool ret = cJSON_AddItemToObject(object_, key, node); 104 if (ret == 0) { 105 cJSON_Delete(node); 106 return false; 107 } 108 109 return true; 110} 111 112bool PtJson::Add(const char *key, const char *value) const 113{ 114 ASSERT(key != nullptr && !Contains(key)); 115 116 cJSON *node = cJSON_CreateString(value); 117 if (node == nullptr) { 118 return false; 119 } 120 121 cJSON_bool ret = cJSON_AddItemToObject(object_, key, node); 122 if (ret == 0) { 123 cJSON_Delete(node); 124 return false; 125 } 126 127 return true; 128} 129 130bool PtJson::Add(const char *key, const std::unique_ptr<PtJson> &value) const 131{ 132 ASSERT(key != nullptr && !Contains(key)); 133 134 cJSON *node = value->GetJson(); 135 if (node == nullptr) { 136 return false; 137 } 138 139 cJSON_bool ret = cJSON_AddItemToObject(object_, key, node); 140 if (ret == 0) { 141 return false; 142 } 143 144 return true; 145} 146 147bool PtJson::Push(bool value) const 148{ 149 cJSON *node = cJSON_CreateBool(value); 150 if (node == nullptr) { 151 return false; 152 } 153 154 cJSON_bool ret = cJSON_AddItemToArray(object_, node); 155 if (ret == 0) { 156 cJSON_Delete(node); 157 return false; 158 } 159 160 return true; 161} 162 163bool PtJson::Push(int32_t value) const 164{ 165 return Push(static_cast<double>(value)); 166} 167 168bool PtJson::Push(int64_t value) const 169{ 170 return Push(static_cast<double>(value)); 171} 172 173bool PtJson::Push(uint32_t value) const 174{ 175 return Push(static_cast<double>(value)); 176} 177 178bool PtJson::Push(double value) const 179{ 180 cJSON *node = cJSON_CreateNumber(value); 181 if (node == nullptr) { 182 return false; 183 } 184 185 cJSON_bool ret = cJSON_AddItemToArray(object_, node); 186 if (ret == 0) { 187 cJSON_Delete(node); 188 return false; 189 } 190 191 return true; 192} 193 194bool PtJson::Push(const char *value) const 195{ 196 cJSON *node = cJSON_CreateString(value); 197 if (node == nullptr) { 198 return false; 199 } 200 201 cJSON_bool ret = cJSON_AddItemToArray(object_, node); 202 if (ret == 0) { 203 cJSON_Delete(node); 204 return false; 205 } 206 207 return true; 208} 209 210bool PtJson::Push(const std::unique_ptr<PtJson> &value) const 211{ 212 if (value == nullptr) { 213 return false; 214 } 215 216 cJSON *node = value->GetJson(); 217 if (node == nullptr) { 218 return false; 219 } 220 221 cJSON_bool ret = cJSON_AddItemToArray(object_, node); 222 if (ret == 0) { 223 return false; 224 } 225 226 return true; 227} 228 229bool PtJson::Remove(const char *key) const 230{ 231 ASSERT(key != nullptr && Contains(key)); 232 233 cJSON_DeleteItemFromObject(object_, key); 234 return true; 235} 236 237bool PtJson::Contains(const char *key) const 238{ 239 cJSON *node = cJSON_GetObjectItemCaseSensitive(object_, key); 240 return node != nullptr; 241} 242 243std::string PtJson::GetKey() const 244{ 245 if (object_ == nullptr || object_->string == nullptr) { 246 return ""; 247 } 248 249 return std::string(object_->string); 250} 251 252cJSON *PtJson::GetJson() const 253{ 254 return object_; 255} 256 257bool PtJson::IsBool() const 258{ 259 return cJSON_IsBool(object_) != 0; 260} 261 262bool PtJson::IsNumber() const 263{ 264 return cJSON_IsNumber(object_) != 0; 265} 266 267bool PtJson::IsString() const 268{ 269 return cJSON_IsString(object_) != 0; 270} 271 272bool PtJson::IsObject() const 273{ 274 return cJSON_IsObject(object_) != 0; 275} 276 277bool PtJson::IsArray() const 278{ 279 return cJSON_IsArray(object_) != 0; 280} 281 282bool PtJson::IsNull() const 283{ 284 return cJSON_IsNull(object_) != 0; 285} 286 287bool PtJson::GetBool(bool defaultValue) const 288{ 289 if (!IsBool()) { 290 return defaultValue; 291 } 292 293 return cJSON_IsTrue(object_) != 0; 294} 295 296int32_t PtJson::GetInt(int32_t defaultValue) const 297{ 298 if (!IsNumber()) { 299 return defaultValue; 300 } 301 302 return static_cast<int32_t>(object_->valuedouble); 303} 304 305int64_t PtJson::GetInt64(int64_t defaultValue) const 306{ 307 if (!IsNumber()) { 308 return defaultValue; 309 } 310 311 return static_cast<int64_t>(object_->valuedouble); 312} 313 314uint32_t PtJson::GetUInt(uint32_t defaultValue) const 315{ 316 if (!IsNumber()) { 317 return defaultValue; 318 } 319 320 return static_cast<uint32_t>(object_->valuedouble); 321} 322 323uint64_t PtJson::GetUInt64(uint64_t defaultValue) const 324{ 325 if (!IsNumber()) { 326 return defaultValue; 327 } 328 329 return static_cast<uint64_t>(object_->valuedouble); 330} 331 332double PtJson::GetDouble(double defaultValue) const 333{ 334 if (!IsNumber()) { 335 return defaultValue; 336 } 337 338 return object_->valuedouble; 339} 340 341std::string PtJson::GetString() const 342{ 343 if (!IsString()) { 344 return ""; 345 } 346 347 return std::string(object_->valuestring); 348} 349 350int32_t PtJson::GetSize() const 351{ 352 return cJSON_GetArraySize(object_); 353} 354 355std::unique_ptr<PtJson> PtJson::Get(int32_t index) const 356{ 357 return std::make_unique<PtJson>(cJSON_GetArrayItem(object_, index)); 358} 359 360Result PtJson::GetBool(const char *key, bool *value) const 361{ 362 cJSON *item = cJSON_GetObjectItem(object_, key); 363 if (item == nullptr) { 364 return Result::NOT_EXIST; 365 } 366 if (cJSON_IsBool(item) == 0) { 367 return Result::TYPE_ERROR; 368 } 369 370 *value = cJSON_IsTrue(item) != 0; 371 return Result::SUCCESS; 372} 373 374Result PtJson::GetInt(const char *key, int32_t *value) const 375{ 376 double result; 377 Result ret = GetDouble(key, &result); 378 if (ret == Result::SUCCESS) { 379 *value = static_cast<int32_t>(result); 380 } 381 return ret; 382} 383 384Result PtJson::GetInt64(const char *key, int64_t *value) const 385{ 386 double result; 387 Result ret = GetDouble(key, &result); 388 if (ret == Result::SUCCESS) { 389 *value = static_cast<int64_t>(result); 390 } 391 return ret; 392} 393 394Result PtJson::GetUInt(const char *key, uint32_t *value) const 395{ 396 double result; 397 Result ret = GetDouble(key, &result); 398 if (ret == Result::SUCCESS) { 399 *value = static_cast<uint32_t>(result); 400 } 401 return ret; 402} 403 404Result PtJson::GetUInt64(const char *key, uint64_t *value) const 405{ 406 double result; 407 Result ret = GetDouble(key, &result); 408 if (ret == Result::SUCCESS) { 409 *value = static_cast<uint64_t>(result); 410 } 411 return ret; 412} 413 414Result PtJson::GetDouble(const char *key, double *value) const 415{ 416 cJSON *item = cJSON_GetObjectItem(object_, key); 417 if (item == nullptr) { 418 return Result::NOT_EXIST; 419 } 420 if (cJSON_IsNumber(item) == 0) { 421 return Result::TYPE_ERROR; 422 } 423 424 *value = item->valuedouble; 425 return Result::SUCCESS; 426} 427 428Result PtJson::GetString(const char *key, std::string *value) const 429{ 430 cJSON *item = cJSON_GetObjectItem(object_, key); 431 if (item == nullptr) { 432 return Result::NOT_EXIST; 433 } 434 if (cJSON_IsString(item) == 0) { 435 return Result::TYPE_ERROR; 436 } 437 438 *value = item->valuestring; 439 return Result::SUCCESS; 440} 441 442Result PtJson::GetObject(const char *key, std::unique_ptr<PtJson> *value) const 443{ 444 cJSON *item = cJSON_GetObjectItem(object_, key); 445 if (item == nullptr) { 446 return Result::NOT_EXIST; 447 } 448 if (cJSON_IsObject(item) == 0) { 449 return Result::TYPE_ERROR; 450 } 451 452 *value = std::make_unique<PtJson>(item); 453 return Result::SUCCESS; 454} 455 456Result PtJson::GetArray(const char *key, std::unique_ptr<PtJson> *value) const 457{ 458 cJSON *item = cJSON_GetObjectItem(object_, key); 459 if (item == nullptr) { 460 return Result::NOT_EXIST; 461 } 462 if (cJSON_IsArray(item) == 0) { 463 return Result::TYPE_ERROR; 464 } 465 466 *value = std::make_unique<PtJson>(item); 467 return Result::SUCCESS; 468} 469 470Result PtJson::GetAny(const char *key, std::unique_ptr<PtJson> *value) const 471{ 472 cJSON *item = cJSON_GetObjectItem(object_, key); 473 if (item == nullptr) { 474 return Result::NOT_EXIST; 475 } 476 477 *value = std::make_unique<PtJson>(item); 478 return Result::SUCCESS; 479} 480} // namespace panda::ecmascript 481