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