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
20 namespace OHOS::Ace {
21
JsonValue(JsonObject * object)22 JsonValue::JsonValue(JsonObject* object) : object_(object) {}
23
JsonValue(JsonObject * object,bool isRoot)24 JsonValue::JsonValue(JsonObject* object, bool isRoot) : object_(object), isRoot_(isRoot) {}
25
~JsonValue()26 JsonValue::~JsonValue()
27 {
28 if (object_ != nullptr && isRoot_) {
29 cJSON_Delete(object_);
30 }
31 object_ = nullptr;
32 }
33
IsBool() const34 bool JsonValue::IsBool() const
35 {
36 return cJSON_IsBool(object_);
37 }
38
IsNumber() const39 bool JsonValue::IsNumber() const
40 {
41 return cJSON_IsNumber(object_);
42 }
43
IsString() const44 bool JsonValue::IsString() const
45 {
46 return cJSON_IsString(object_);
47 }
48
IsArray() const49 bool JsonValue::IsArray() const
50 {
51 return cJSON_IsArray(object_);
52 }
53
IsObject() const54 bool JsonValue::IsObject() const
55 {
56 return cJSON_IsObject(object_);
57 }
58
IsValid() const59 bool JsonValue::IsValid() const
60 {
61 return (object_ != nullptr) && !cJSON_IsInvalid(object_);
62 }
63
IsNull() const64 bool JsonValue::IsNull() const
65 {
66 return (object_ == nullptr) || cJSON_IsNull(object_);
67 }
68
Contains(const std::string & key) const69 bool JsonValue::Contains(const std::string& key) const
70 {
71 return cJSON_HasObjectItem(object_, key.c_str());
72 }
73
GetBool() const74 bool JsonValue::GetBool() const
75 {
76 return cJSON_IsTrue(object_) != 0;
77 }
78
GetBool(const std::string & key,bool defaultValue) const79 bool 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
GetInt() const87 int32_t JsonValue::GetInt() const
88 {
89 return static_cast<int32_t>((object_ == nullptr) ? 0 : object_->valuedouble);
90 }
91
GetUInt() const92 uint32_t JsonValue::GetUInt() const
93 {
94 return static_cast<uint32_t>((object_ == nullptr) ? 0 : object_->valuedouble);
95 }
96
GetInt64() const97 int64_t JsonValue::GetInt64() const
98 {
99 return static_cast<int64_t>((object_ == nullptr) ? 0 : object_->valuedouble);
100 }
101
GetDouble() const102 double JsonValue::GetDouble() const
103 {
104 return (object_ == nullptr) ? 0.0 : object_->valuedouble;
105 }
106
GetDouble(const std::string & key,double defaultVal) const107 double 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
GetString() const116 std::string JsonValue::GetString() const
117 {
118 return ((object_ == nullptr) || (object_->valuestring == nullptr)) ? "" : std::string(object_->valuestring);
119 }
120
GetNext() const121 std::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
GetChild() const129 std::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
GetKey() const137 std::string JsonValue::GetKey() const
138 {
139 return ((object_ == nullptr) || (object_->string == nullptr)) ? "" : std::string(object_->string);
140 }
GetValue(const std::string & key) const141 std::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
GetObject(const std::string & key) const146 std::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
GetArraySize() const154 int32_t JsonValue::GetArraySize() const
155 {
156 return cJSON_GetArraySize(object_);
157 }
158
GetArrayItem(int32_t index) const159 std::unique_ptr<JsonValue> JsonValue::GetArrayItem(int32_t index) const
160 {
161 return std::make_unique<JsonValue>(cJSON_GetArrayItem(object_, index));
162 }
163
Put(const char * key,const char * value)164 bool 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
PutFixedAttr(const char * key,const char * value,const NG::InspectorFilter & filter,NG::FixedAttrBit attr)178 bool 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
PutExtAttr(const char * key,const char * value,const NG::InspectorFilter & filter)187 bool 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
GetJsonObject() const195 const JsonObject* JsonValue::GetJsonObject() const
196 {
197 return object_;
198 }
199
Put(const char * key,const std::unique_ptr<JsonValue> & value)200 bool 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
Put(const char * key,const std::shared_ptr<JsonValue> & value)214 bool JsonValue::Put(const char* key, const std::shared_ptr<JsonValue>& value)
215 {
216 if (!value || !key) {
217 return false;
218 }
219 cJSON* jsonObject = cJSON_Duplicate(value->GetJsonObject(), true);
220 if (jsonObject == nullptr) {
221 return false;
222 }
223
224 cJSON_AddItemToObject(object_, key, jsonObject);
225 return true;
226 }
227
PutFixedAttr(const char * key,const std::unique_ptr<JsonValue> & value,const NG::InspectorFilter & filter,NG::FixedAttrBit attr)228 bool JsonValue::PutFixedAttr(const char* key, const std::unique_ptr<JsonValue>& value,
229 const NG::InspectorFilter& filter, NG::FixedAttrBit attr)
230 {
231 if (filter.CheckFixedAttr(attr)) {
232 return Put(key, value);
233 }
234 return false;
235 }
236
PutExtAttr(const char * key,const std::unique_ptr<JsonValue> & value,const NG::InspectorFilter & filter)237 bool JsonValue::PutExtAttr(const char* key, const std::unique_ptr<JsonValue>& value,
238 const NG::InspectorFilter& filter)
239 {
240 if (filter.CheckExtAttr(key)) {
241 return Put(key, value);
242 }
243 return false;
244 }
245
246 // add item to array
Put(const std::unique_ptr<JsonValue> & value)247 bool JsonValue::Put(const std::unique_ptr<JsonValue>& value)
248 {
249 if (!value) {
250 return false;
251 }
252 cJSON* jsonObject = cJSON_Duplicate(value->GetJsonObject(), true);
253 if (jsonObject == nullptr) {
254 return false;
255 }
256
257 cJSON_AddItemToArray(object_, jsonObject);
258 return true;
259 }
260
Put(const std::shared_ptr<JsonValue> & value)261 bool JsonValue::Put(const std::shared_ptr<JsonValue>& value)
262 {
263 if (!value) {
264 return false;
265 }
266 cJSON* jsonObject = cJSON_Duplicate(value->GetJsonObject(), true);
267 if (jsonObject == nullptr) {
268 return false;
269 }
270
271 cJSON_AddItemToArray(object_, jsonObject);
272 return true;
273 }
274
Put(const char * key,size_t value)275 bool JsonValue::Put(const char* key, size_t value)
276 {
277 if (key == nullptr) {
278 return false;
279 }
280
281 cJSON* child = cJSON_CreateNumber(static_cast<double>(value));
282 if (child == nullptr) {
283 return false;
284 }
285 cJSON_AddItemToObject(object_, key, child);
286 return true;
287 }
288
PutFixedAttr(const char * key,size_t value,const NG::InspectorFilter & filter,NG::FixedAttrBit attr)289 bool JsonValue::PutFixedAttr(const char* key, size_t value,
290 const NG::InspectorFilter& filter, NG::FixedAttrBit attr)
291 {
292 if (filter.CheckFixedAttr(attr)) {
293 return Put(key, value);
294 }
295 return false;
296 }
297
PutExtAttr(const char * key,size_t value,const NG::InspectorFilter & filter)298 bool JsonValue::PutExtAttr(const char* key, size_t value, const NG::InspectorFilter& filter)
299 {
300 if (filter.CheckExtAttr(key)) {
301 return Put(key, value);
302 }
303 return false;
304 }
305
Put(const char * key,int32_t value)306 bool JsonValue::Put(const char* key, int32_t value)
307 {
308 if (key == nullptr) {
309 return false;
310 }
311
312 cJSON* child = cJSON_CreateNumber(static_cast<double>(value));
313 if (child == nullptr) {
314 return false;
315 }
316 cJSON_AddItemToObject(object_, key, child);
317 return true;
318 }
319
PutFixedAttr(const char * key,int32_t value,const NG::InspectorFilter & filter,NG::FixedAttrBit attr)320 bool JsonValue::PutFixedAttr(const char* key, int32_t value,
321 const NG::InspectorFilter& filter, NG::FixedAttrBit attr)
322 {
323 if (filter.CheckFixedAttr(attr)) {
324 return Put(key, value);
325 }
326 return false;
327 }
328
PutExtAttr(const char * key,int32_t value,const NG::InspectorFilter & filter)329 bool JsonValue::PutExtAttr(const char* key, int32_t value, const NG::InspectorFilter& filter)
330 {
331 if (filter.CheckExtAttr(key)) {
332 return Put(key, value);
333 }
334 return false;
335 }
336
Put(const char * key,int64_t value)337 bool JsonValue::Put(const char* key, int64_t value)
338 {
339 return Put(key, static_cast<double>(value));
340 }
341
PutFixedAttr(const char * key,int64_t value,const NG::InspectorFilter & filter,NG::FixedAttrBit attr)342 bool JsonValue::PutFixedAttr(const char* key, int64_t value,
343 const NG::InspectorFilter& filter, NG::FixedAttrBit attr)
344 {
345 if (filter.CheckFixedAttr(attr)) {
346 return Put(key, value);
347 }
348 return false;
349 }
350
PutExtAttr(const char * key,int64_t value,const NG::InspectorFilter & filter)351 bool JsonValue::PutExtAttr(const char* key, int64_t value, const NG::InspectorFilter& filter)
352 {
353 if (filter.CheckExtAttr(key)) {
354 return Put(key, value);
355 }
356 return false;
357 }
358
Put(const char * key,double value)359 bool JsonValue::Put(const char* key, double value)
360 {
361 if (key == nullptr) {
362 return false;
363 }
364
365 cJSON* child = cJSON_CreateNumber(value);
366 if (child == nullptr) {
367 return false;
368 }
369 cJSON_AddItemToObject(object_, key, child);
370 return true;
371 }
372
PutFixedAttr(const char * key,double value,const NG::InspectorFilter & filter,NG::FixedAttrBit attr)373 bool JsonValue::PutFixedAttr(const char* key, double value,
374 const NG::InspectorFilter& filter, NG::FixedAttrBit attr)
375 {
376 if (filter.CheckFixedAttr(attr)) {
377 return Put(key, value);
378 }
379 return false;
380 }
381
PutExtAttr(const char * key,double value,const NG::InspectorFilter & filter)382 bool JsonValue::PutExtAttr(const char* key, double value, const NG::InspectorFilter& filter)
383 {
384 if (filter.CheckExtAttr(key)) {
385 return Put(key, value);
386 }
387 return false;
388 }
389
ReleaseJsonObject()390 JsonObject* JsonValue::ReleaseJsonObject()
391 {
392 if (!isRoot_) {
393 return nullptr;
394 }
395 JsonObject* object = object_;
396 object_ = nullptr;
397 return object;
398 }
399
PutRef(const char * key,std::unique_ptr<JsonValue> && value)400 bool JsonValue::PutRef(const char* key, std::unique_ptr<JsonValue>&& value)
401 {
402 if (key == nullptr || value == nullptr) {
403 return false;
404 }
405 /*
406 * If value is root, it controls the lifecycle of JsonObject, we can just move it into current object
407 * Else we need to copy the JsonObject and put the new object in current object
408 */
409 if (value->isRoot_) {
410 cJSON_AddItemToObject(object_, key, value->ReleaseJsonObject());
411 return true;
412 } else {
413 std::unique_ptr<JsonValue> lValue = std::move(value);
414 return Put(key, lValue);
415 }
416 }
417
PutRef(std::unique_ptr<JsonValue> && value)418 bool JsonValue::PutRef(std::unique_ptr<JsonValue>&& value)
419 {
420 if (value == nullptr) {
421 return false;
422 }
423 /*
424 * If value is root, it controls the lifecycle of JsonObject, we can just move it into current object
425 * Else we need to copy the JsonObject and put the new object in current object
426 */
427 if (value->isRoot_) {
428 cJSON_AddItemToArray(object_, value->ReleaseJsonObject());
429 return true;
430 } else {
431 std::unique_ptr<JsonValue> lValue = std::move(value);
432 return Put(lValue);
433 }
434 }
435
PutRef(std::shared_ptr<JsonValue> && value)436 bool JsonValue::PutRef(std::shared_ptr<JsonValue>&& value)
437 {
438 if (value == nullptr) {
439 return false;
440 }
441 /*
442 * If value is root, it controls the lifecycle of JsonObject, we can just move it into current object
443 * Else we need to copy the JsonObject and put the new object in current object
444 */
445 if (value->isRoot_) {
446 cJSON_AddItemToArray(object_, value->ReleaseJsonObject());
447 return true;
448 } else {
449 std::shared_ptr<JsonValue> lValue = std::move(value);
450 return Put(lValue);
451 }
452 }
453
Replace(const char * key,double value)454 bool JsonValue::Replace(const char* key, double value)
455 {
456 if (key == nullptr) {
457 return false;
458 }
459
460 cJSON* child = cJSON_CreateNumber(value);
461 if (child == nullptr) {
462 return false;
463 }
464 if (!cJSON_ReplaceItemInObject(object_, key, child)) {
465 cJSON_Delete(child);
466 return false;
467 }
468 return true;
469 }
470
Put(const char * key,bool value)471 bool JsonValue::Put(const char* key, bool value)
472 {
473 if (key == nullptr) {
474 return false;
475 }
476
477 cJSON* child = cJSON_CreateBool(value);
478 if (child == nullptr) {
479 return false;
480 }
481 cJSON_AddItemToObject(object_, key, child);
482 return true;
483 }
484
PutFixedAttr(const char * key,bool value,const NG::InspectorFilter & filter,NG::FixedAttrBit attr)485 bool JsonValue::PutFixedAttr(const char* key, bool value,
486 const NG::InspectorFilter& filter, NG::FixedAttrBit attr)
487 {
488 if (filter.CheckFixedAttr(attr)) {
489 return Put(key, value);
490 }
491 return false;
492 }
493
PutExtAttr(const char * key,bool value,const NG::InspectorFilter & filter)494 bool JsonValue::PutExtAttr(const char* key, bool value, const NG::InspectorFilter& filter)
495 {
496 if (filter.CheckExtAttr(key)) {
497 return Put(key, value);
498 }
499 return false;
500 }
501
Replace(const char * key,bool value)502 bool JsonValue::Replace(const char* key, bool value)
503 {
504 if (key == nullptr) {
505 return false;
506 }
507
508 cJSON* child = cJSON_CreateBool(value);
509 if (child == nullptr) {
510 return false;
511 }
512 if (!cJSON_ReplaceItemInObject(object_, key, child)) {
513 cJSON_Delete(child);
514 return false;
515 }
516 return true;
517 }
518
Replace(const char * key,const char * value)519 bool JsonValue::Replace(const char* key, const char* value)
520 {
521 if ((value == nullptr) || (key == nullptr)) {
522 return false;
523 }
524
525 cJSON* child = cJSON_CreateString(value);
526 if (child == nullptr) {
527 return false;
528 }
529 if (!cJSON_ReplaceItemInObject(object_, key, child)) {
530 cJSON_Delete(child);
531 return false;
532 }
533 return true;
534 }
535
Replace(const char * key,int32_t value)536 bool JsonValue::Replace(const char* key, int32_t value)
537 {
538 if (key == nullptr) {
539 return false;
540 }
541
542 cJSON* child = cJSON_CreateNumber(static_cast<double>(value));
543 if (child == nullptr) {
544 return false;
545 }
546 if (!cJSON_ReplaceItemInObject(object_, key, child)) {
547 cJSON_Delete(child);
548 return false;
549 }
550 return true;
551 }
552
Replace(const char * key,const std::unique_ptr<JsonValue> & value)553 bool JsonValue::Replace(const char* key, const std::unique_ptr<JsonValue>& value)
554 {
555 if ((value == nullptr) || (key == nullptr)) {
556 return false;
557 }
558 cJSON* jsonObject = cJSON_Duplicate(value->GetJsonObject(), true);
559 if (jsonObject == nullptr) {
560 return false;
561 }
562
563 if (!cJSON_ReplaceItemInObject(object_, key, jsonObject)) {
564 cJSON_Delete(jsonObject);
565 return false;
566 }
567 return true;
568 }
569
Delete(const char * key)570 bool JsonValue::Delete(const char* key)
571 {
572 if (key == nullptr) {
573 return false;
574 }
575 cJSON_DeleteItemFromObject(object_, key);
576 return true;
577 }
578
ToString()579 std::string JsonValue::ToString()
580 {
581 std::string result;
582 if (!object_) {
583 return result;
584 }
585
586 // It is null-terminated.
587 char* unformatted = cJSON_PrintUnformatted(object_);
588 if (unformatted != nullptr) {
589 result = unformatted;
590 cJSON_free(unformatted);
591 }
592 return result;
593 }
594
GetString(const std::string & key,const std::string & defaultVal) const595 std::string JsonValue::GetString(const std::string& key, const std::string& defaultVal) const
596 {
597 auto value = GetValue(key);
598 if (value && value->IsString()) {
599 return value->GetString();
600 }
601 return defaultVal;
602 }
603
GetInt(const std::string & key,int32_t defaultVal) const604 int32_t JsonValue::GetInt(const std::string& key, int32_t defaultVal) const
605 {
606 auto value = GetValue(key);
607 if (value && value->IsNumber()) {
608 return value->GetInt();
609 }
610 return defaultVal;
611 }
612
GetUInt(const std::string & key,uint32_t defaultVal) const613 uint32_t JsonValue::GetUInt(const std::string& key, uint32_t defaultVal) const
614 {
615 auto value = GetValue(key);
616 if (value && value->IsNumber()) {
617 return value->GetUInt();
618 }
619 return defaultVal;
620 }
621
GetInt64(const std::string & key,int64_t defaultVal) const622 int64_t JsonValue::GetInt64(const std::string& key, int64_t defaultVal) const
623 {
624 auto value = GetValue(key);
625 if (value && value->IsNumber()) {
626 return value->GetInt64();
627 }
628 return defaultVal;
629 }
630
ParseJsonData(const char * data,const char ** parseEnd)631 std::unique_ptr<JsonValue> JsonUtil::ParseJsonData(const char* data, const char** parseEnd)
632 {
633 return std::make_unique<JsonValue>(cJSON_ParseWithOpts(data, parseEnd, true), true);
634 }
635
636 #if defined(ACE_STATIC)
ParseJsonDataWithLength(const char * data,size_t len)637 std::unique_ptr<JsonValue> JsonUtil::ParseJsonDataWithLength(const char* data, size_t len)
638 {
639 return std::make_unique<JsonValue>(cJSON_ParseWithLength(data, len), true);
640 }
641 #endif
642
ParseJsonString(const std::string & content,const char ** parseEnd)643 std::unique_ptr<JsonValue> JsonUtil::ParseJsonString(const std::string& content, const char** parseEnd)
644 {
645 return ParseJsonData(content.c_str(), parseEnd);
646 }
647
Create(bool isRoot)648 std::unique_ptr<JsonValue> JsonUtil::Create(bool isRoot)
649 {
650 return std::make_unique<JsonValue>(cJSON_CreateObject(), isRoot);
651 }
652
CreateSharedPtrJson(bool isRoot)653 std::shared_ptr<JsonValue> JsonUtil::CreateSharedPtrJson(bool isRoot)
654 {
655 return std::make_shared<JsonValue>(cJSON_CreateObject(), isRoot);
656 }
657
CreateArray(bool isRoot)658 std::unique_ptr<JsonValue> JsonUtil::CreateArray(bool isRoot)
659 {
660 return std::make_unique<JsonValue>(cJSON_CreateArray(), isRoot);
661 }
662
663 } // namespace OHOS::Ace
664