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 
PutFixedAttr(const char * key,const std::unique_ptr<JsonValue> & value,const NG::InspectorFilter & filter,NG::FixedAttrBit attr)214 bool 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 
PutExtAttr(const char * key,const std::unique_ptr<JsonValue> & value,const NG::InspectorFilter & filter)223 bool 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
Put(const std::unique_ptr<JsonValue> & value)233 bool 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 
Put(const char * key,size_t value)247 bool 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 
PutFixedAttr(const char * key,size_t value,const NG::InspectorFilter & filter,NG::FixedAttrBit attr)261 bool 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 
PutExtAttr(const char * key,size_t value,const NG::InspectorFilter & filter)270 bool 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 
Put(const char * key,int32_t value)278 bool 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 
PutFixedAttr(const char * key,int32_t value,const NG::InspectorFilter & filter,NG::FixedAttrBit attr)292 bool 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 
PutExtAttr(const char * key,int32_t value,const NG::InspectorFilter & filter)301 bool 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 
Put(const char * key,int64_t value)309 bool JsonValue::Put(const char* key, int64_t value)
310 {
311     return Put(key, static_cast<double>(value));
312 }
313 
PutFixedAttr(const char * key,int64_t value,const NG::InspectorFilter & filter,NG::FixedAttrBit attr)314 bool 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 
PutExtAttr(const char * key,int64_t value,const NG::InspectorFilter & filter)323 bool 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 
Put(const char * key,double value)331 bool 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 
PutFixedAttr(const char * key,double value,const NG::InspectorFilter & filter,NG::FixedAttrBit attr)345 bool 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 
PutExtAttr(const char * key,double value,const NG::InspectorFilter & filter)354 bool 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 
ReleaseJsonObject()362 JsonObject* JsonValue::ReleaseJsonObject()
363 {
364     if (!isRoot_) {
365         return nullptr;
366     }
367     JsonObject* object = object_;
368     object_ = nullptr;
369     return object;
370 }
371 
PutRef(const char * key,std::unique_ptr<JsonValue> && value)372 bool 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 
PutRef(std::unique_ptr<JsonValue> && value)390 bool 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 
Replace(const char * key,double value)408 bool 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 
Put(const char * key,bool value)425 bool 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 
PutFixedAttr(const char * key,bool value,const NG::InspectorFilter & filter,NG::FixedAttrBit attr)439 bool 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 
PutExtAttr(const char * key,bool value,const NG::InspectorFilter & filter)448 bool 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 
Replace(const char * key,bool value)456 bool 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 
Replace(const char * key,const char * value)473 bool 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 
Replace(const char * key,int32_t value)490 bool 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 
Replace(const char * key,const std::unique_ptr<JsonValue> & value)507 bool 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 
Delete(const char * key)524 bool JsonValue::Delete(const char* key)
525 {
526     if (key == nullptr) {
527         return false;
528     }
529     cJSON_DeleteItemFromObject(object_, key);
530     return true;
531 }
532 
ToString()533 std::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 
GetString(const std::string & key,const std::string & defaultVal) const549 std::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 
GetInt(const std::string & key,int32_t defaultVal) const558 int32_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 
GetUInt(const std::string & key,uint32_t defaultVal) const567 uint32_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 
GetInt64(const std::string & key,int64_t defaultVal) const576 int64_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 
ParseJsonData(const char * data,const char ** parseEnd)585 std::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 
ParseJsonString(const std::string & content,const char ** parseEnd)590 std::unique_ptr<JsonValue> JsonUtil::ParseJsonString(const std::string& content, const char** parseEnd)
591 {
592     return ParseJsonData(content.c_str(), parseEnd);
593 }
594 
Create(bool isRoot)595 std::unique_ptr<JsonValue> JsonUtil::Create(bool isRoot)
596 {
597     return std::make_unique<JsonValue>(cJSON_CreateObject(), isRoot);
598 }
599 
CreateArray(bool isRoot)600 std::unique_ptr<JsonValue> JsonUtil::CreateArray(bool isRoot)
601 {
602     return std::make_unique<JsonValue>(cJSON_CreateArray(), isRoot);
603 }
604 
605 } // namespace OHOS::Ace
606