• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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