1 /*
2 * Copyright (c) 2025 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 "json_object.h"
17
18 namespace OHOS {
19 namespace DistributedHardware {
20
ToJson(JsonItemObject & itemObject,const std::string & value)21 void ToJson(JsonItemObject &itemObject, const std::string &value)
22 {
23 if (itemObject.item_ != nullptr) {
24 cJSON_Delete(itemObject.item_);
25 }
26 itemObject.item_ = cJSON_CreateString(value.c_str());
27 }
28
ToJson(JsonItemObject & itemObject,const char * value)29 void ToJson(JsonItemObject &itemObject, const char *value)
30 {
31 if (itemObject.item_ != nullptr) {
32 cJSON_Delete(itemObject.item_);
33 }
34 itemObject.item_ = cJSON_CreateString(value);
35 }
36
ToJson(JsonItemObject & itemObject,const double & value)37 void ToJson(JsonItemObject &itemObject, const double &value)
38 {
39 if (itemObject.item_ != nullptr) {
40 cJSON_Delete(itemObject.item_);
41 }
42 itemObject.item_ = cJSON_CreateNumber(value);
43 }
44
ToJson(JsonItemObject & itemObject,const bool & value)45 void ToJson(JsonItemObject &itemObject, const bool &value)
46 {
47 if (itemObject.item_ != nullptr) {
48 cJSON_Delete(itemObject.item_);
49 }
50 itemObject.item_ = value ? cJSON_CreateTrue() : cJSON_CreateFalse();
51 }
52
ToJson(JsonItemObject & itemObject,const uint8_t & value)53 void ToJson(JsonItemObject &itemObject, const uint8_t &value)
54 {
55 if (itemObject.item_ != nullptr) {
56 cJSON_Delete(itemObject.item_);
57 }
58 itemObject.item_ = cJSON_CreateNumber(value);
59 }
60
ToJson(JsonItemObject & itemObject,const int16_t & value)61 void ToJson(JsonItemObject &itemObject, const int16_t &value)
62 {
63 if (itemObject.item_ != nullptr) {
64 cJSON_Delete(itemObject.item_);
65 }
66 itemObject.item_ = cJSON_CreateNumber(value);
67 }
68
ToJson(JsonItemObject & itemObject,const uint16_t & value)69 void ToJson(JsonItemObject &itemObject, const uint16_t &value)
70 {
71 if (itemObject.item_ != nullptr) {
72 cJSON_Delete(itemObject.item_);
73 }
74 itemObject.item_ = cJSON_CreateNumber(value);
75 }
76
ToJson(JsonItemObject & itemObject,const int32_t & value)77 void ToJson(JsonItemObject &itemObject, const int32_t &value)
78 {
79 if (itemObject.item_ != nullptr) {
80 cJSON_Delete(itemObject.item_);
81 }
82 itemObject.item_ = cJSON_CreateNumber(value);
83 }
84
ToJson(JsonItemObject & itemObject,const uint32_t & value)85 void ToJson(JsonItemObject &itemObject, const uint32_t &value)
86 {
87 if (itemObject.item_ != nullptr) {
88 cJSON_Delete(itemObject.item_);
89 }
90 itemObject.item_ = cJSON_CreateNumber(value);
91 }
92
ToJson(JsonItemObject & itemObject,const int64_t & value)93 void ToJson(JsonItemObject &itemObject, const int64_t &value)
94 {
95 if (itemObject.item_ != nullptr) {
96 cJSON_Delete(itemObject.item_);
97 }
98 itemObject.item_ = cJSON_CreateNumber(value);
99 }
100
ToJson(JsonItemObject & itemObject,const uint64_t & value)101 void ToJson(JsonItemObject &itemObject, const uint64_t &value)
102 {
103 if (itemObject.item_ != nullptr) {
104 cJSON_Delete(itemObject.item_);
105 }
106 itemObject.item_ = cJSON_CreateNumber(value);
107 }
108
FromJson(const JsonItemObject & itemObject,std::string & value)109 void FromJson(const JsonItemObject &itemObject, std::string &value)
110 {
111 itemObject.GetTo(value);
112 }
113
FromJson(const JsonItemObject & itemObject,double & value)114 void FromJson(const JsonItemObject &itemObject, double &value)
115 {
116 itemObject.GetTo(value);
117 }
118
FromJson(const JsonItemObject & itemObject,bool & value)119 void FromJson(const JsonItemObject &itemObject, bool &value)
120 {
121 itemObject.GetTo(value);
122 }
123
FromJson(const JsonItemObject & itemObject,uint8_t & value)124 void FromJson(const JsonItemObject &itemObject, uint8_t &value)
125 {
126 int32_t tmpValue = 0;
127 itemObject.GetTo(tmpValue);
128 value = static_cast<uint8_t>(tmpValue);
129 }
130
FromJson(const JsonItemObject & itemObject,int16_t & value)131 void FromJson(const JsonItemObject &itemObject, int16_t &value)
132 {
133 int32_t tmpValue = 0;
134 itemObject.GetTo(tmpValue);
135 value = static_cast<int16_t>(tmpValue);
136 }
137
FromJson(const JsonItemObject & itemObject,uint16_t & value)138 void FromJson(const JsonItemObject &itemObject, uint16_t &value)
139 {
140 int32_t tmpValue = 0;
141 itemObject.GetTo(tmpValue);
142 value = static_cast<uint16_t>(tmpValue);
143 }
144
FromJson(const JsonItemObject & itemObject,int32_t & value)145 void FromJson(const JsonItemObject &itemObject, int32_t &value)
146 {
147 itemObject.GetTo(value);
148 }
149
FromJson(const JsonItemObject & itemObject,uint32_t & value)150 void FromJson(const JsonItemObject &itemObject, uint32_t &value)
151 {
152 int32_t tmpValue = 0;
153 itemObject.GetTo(tmpValue);
154 value = static_cast<uint32_t>(tmpValue);
155 }
156
FromJson(const JsonItemObject & itemObject,int64_t & value)157 void FromJson(const JsonItemObject &itemObject, int64_t &value)
158 {
159 itemObject.GetTo(value);
160 }
161
FromJson(const JsonItemObject & itemObject,uint64_t & value)162 void FromJson(const JsonItemObject &itemObject, uint64_t &value)
163 {
164 int64_t tmpValue = 0;
165 itemObject.GetTo(tmpValue);
166 value = static_cast<uint64_t>(tmpValue);
167 }
168
ToString(const JsonItemObject & jsonItem)169 std::string ToString(const JsonItemObject &jsonItem)
170 {
171 return jsonItem.Dump();
172 }
173
JsonItemObject()174 JsonItemObject::JsonItemObject()
175 {}
176
JsonItemObject(const JsonItemObject & object)177 JsonItemObject::JsonItemObject(const JsonItemObject &object)
178 {
179 item_ = object.item_;
180 parent_ = object.parent_;
181 itemName_ = object.itemName_;
182 needDeleteItem_ = object.needDeleteItem_;
183 if (object.needDeleteItem_) {
184 item_ = cJSON_Duplicate(object.item_, cJSON_True);
185 }
186 }
187
~JsonItemObject()188 JsonItemObject::~JsonItemObject()
189 {
190 Delete();
191 }
192
Delete()193 void JsonItemObject::Delete()
194 {
195 if (needDeleteItem_ && item_ != nullptr) {
196 cJSON_Delete(item_);
197 }
198 item_ = nullptr;
199 }
200
IsString() const201 bool JsonItemObject::IsString() const
202 {
203 if (item_ == nullptr) {
204 return false;
205 }
206 return cJSON_IsString(item_);
207 }
208
IsNumber() const209 bool JsonItemObject::IsNumber() const
210 {
211 if (item_ == nullptr) {
212 return false;
213 }
214 return cJSON_IsNumber(item_);
215 }
216
IsNumberInteger() const217 bool JsonItemObject::IsNumberInteger() const
218 {
219 if (!IsNumber()) {
220 return false;
221 }
222 double value = 0.0;
223 GetTo(value);
224 return ((value - static_cast<int64_t>(value)) == 0);
225 }
226
IsArray() const227 bool JsonItemObject::IsArray() const
228 {
229 if (item_ == nullptr) {
230 return false;
231 }
232 return cJSON_IsArray(item_);
233 }
234
IsBoolean() const235 bool JsonItemObject::IsBoolean() const
236 {
237 if (item_ == nullptr) {
238 return false;
239 }
240 return cJSON_IsBool(item_);
241 }
242
IsObject() const243 bool JsonItemObject::IsObject() const
244 {
245 if (item_ == nullptr) {
246 return false;
247 }
248 return cJSON_IsObject(item_);
249 }
250
Insert(const std::string & key,const JsonItemObject & object)251 void JsonItemObject::Insert(const std::string &key, const JsonItemObject &object)
252 {
253 if (item_ == nullptr || object.item_ == nullptr) {
254 LOGE("invalid item or object item");
255 return;
256 }
257 cJSON *newItem = cJSON_Duplicate(object.item_, cJSON_True);
258 if (newItem == nullptr) {
259 LOGE("copy item fail");
260 return;
261 }
262 if (cJSON_GetObjectItemCaseSensitive(item_, key.c_str()) != nullptr) {
263 cJSON_DeleteItemFromObjectCaseSensitive(item_, key.c_str());
264 }
265 if (!cJSON_AddItemToObject(item_, key.c_str(), newItem)) {
266 LOGE("add new item to object fail");
267 cJSON_Delete(newItem);
268 }
269 }
270
operator =(const JsonItemObject & object)271 JsonItemObject& JsonItemObject::operator=(const JsonItemObject &object)
272 {
273 item_ = object.item_;
274 parent_ = object.parent_;
275 itemName_ = object.itemName_;
276 needDeleteItem_ = object.needDeleteItem_;
277 if (object.needDeleteItem_) {
278 item_ = cJSON_Duplicate(object.item_, cJSON_True);
279 }
280 return *this;
281 }
282
DumpFormated() const283 std::string JsonItemObject::DumpFormated() const
284 {
285 return Dump(true);
286 }
287
Dump() const288 std::string JsonItemObject::Dump() const
289 {
290 return Dump(false);
291 }
292
Dump(bool formatFlag) const293 std::string JsonItemObject::Dump(bool formatFlag) const
294 {
295 if (item_ == nullptr) {
296 LOGE("item_ is nullptr");
297 return "";
298 }
299 char* jsonString = formatFlag ? cJSON_Print(item_) : cJSON_PrintUnformatted(item_);
300 if (jsonString == nullptr) {
301 return "";
302 }
303 std::string out(jsonString);
304 cJSON_free(jsonString);
305 return out;
306 }
307
operator [](const std::string & key)308 JsonItemObject JsonItemObject::operator[](const std::string &key)
309 {
310 JsonItemObject itemObject = At(key);
311 if (itemObject.item_ == nullptr) {
312 itemObject.item_ = cJSON_CreateNull();
313 if (itemObject.item_ == nullptr) {
314 return itemObject;
315 }
316 if (!cJSON_AddItemToObject(item_, key.c_str(), itemObject.item_)) {
317 LOGE("add item to object fail");
318 cJSON_Delete(itemObject.item_);
319 itemObject.item_ = nullptr;
320 } else {
321 itemObject.beValid_ = true;
322 }
323 }
324 return itemObject;
325 }
326
operator [](const std::string & key) const327 const JsonItemObject JsonItemObject::operator[](const std::string &key) const
328 {
329 return At(key);
330 }
331
Contains(const std::string & key) const332 bool JsonItemObject::Contains(const std::string &key) const
333 {
334 if (item_ == nullptr) {
335 LOGE("item_ is nullptr");
336 return false;
337 }
338 cJSON* item = cJSON_GetObjectItemCaseSensitive(item_, key.c_str());
339 return (item != nullptr);
340 }
341
IsDiscarded() const342 bool JsonItemObject::IsDiscarded() const
343 {
344 return (item_ == nullptr);
345 }
346
PushBack(const std::string & strValue)347 bool JsonItemObject::PushBack(const std::string &strValue)
348 {
349 if (item_ == nullptr) {
350 LOGE("item_ is nullptr");
351 return false;
352 }
353 if (item_->type != cJSON_Array) {
354 LOGE("item_ type is not array");
355 return false;
356 }
357 cJSON *newItem = cJSON_CreateString(strValue.c_str());
358 return AddToArray(newItem);
359 }
360
PushBack(const double & value)361 bool JsonItemObject::PushBack(const double &value)
362 {
363 if (item_ == nullptr) {
364 LOGE("item_ is nullptr");
365 return false;
366 }
367 if (item_->type != cJSON_Array) {
368 LOGE("item_ type is not array");
369 return false;
370 }
371 cJSON *newItem = cJSON_CreateNumber(value);
372 return AddToArray(newItem);
373 }
374
PushBack(const JsonItemObject & item)375 bool JsonItemObject::PushBack(const JsonItemObject &item)
376 {
377 if (item_ == nullptr) {
378 LOGE("item_ is nullptr");
379 return false;
380 }
381 if (!item.beValid_ || !beValid_) {
382 return false;
383 }
384 if (item_->type != cJSON_Array) {
385 LOGE("item_ type is not array");
386 return false;
387 }
388 cJSON* newItem = cJSON_Duplicate(item.item_, cJSON_True);
389 return AddToArray(newItem);
390 }
391
AddToArray(cJSON * newItem)392 bool JsonItemObject::AddToArray(cJSON *newItem)
393 {
394 if (item_ == nullptr) {
395 LOGE("item_ is nullptr");
396 return false;
397 }
398 if (!cJSON_AddItemToArray(item_, newItem)) {
399 LOGE("add item to array fail");
400 cJSON_Delete(newItem);
401 return false;
402 }
403 return true;
404 }
405
Key() const406 std::string JsonItemObject::Key() const
407 {
408 if (item_ != nullptr) {
409 return std::string(item_->string);
410 }
411 return itemName_;
412 }
413
At(const std::string & key) const414 JsonItemObject JsonItemObject::At(const std::string &key) const
415 {
416 JsonItemObject operationItem;
417 operationItem.item_ = cJSON_GetObjectItemCaseSensitive(item_, key.c_str());
418 if (operationItem.item_ != nullptr) {
419 operationItem.beValid_ = true;
420 }
421 operationItem.parent_ = item_;
422 operationItem.itemName_ = key;
423 return operationItem;
424 }
425
GetTo(std::string & value) const426 void JsonItemObject::GetTo(std::string &value) const
427 {
428 value = "";
429 if (item_ == nullptr) {
430 LOGE("value item is null");
431 return;
432 }
433 if (!IsString()) {
434 return;
435 }
436 const char* strValue = cJSON_GetStringValue(item_);
437 if (strValue == nullptr) {
438 return;
439 }
440 value = std::string(strValue);
441 }
442
GetTo(double & value) const443 void JsonItemObject::GetTo(double &value) const
444 {
445 value = 0.0;
446 if (item_ == nullptr) {
447 LOGE("value item is null");
448 return;
449 }
450 if (!IsNumber()) {
451 return;
452 }
453 value = cJSON_GetNumberValue(item_);
454 }
455
GetTo(int32_t & value) const456 void JsonItemObject::GetTo(int32_t &value) const
457 {
458 double tmpValue = 0.0;
459 GetTo(tmpValue);
460 value = static_cast<int32_t>(tmpValue);
461 }
462
GetTo(uint32_t & value) const463 void JsonItemObject::GetTo(uint32_t &value) const
464 {
465 double tmpValue = 0.0;
466 GetTo(tmpValue);
467 value = static_cast<uint32_t>(tmpValue);
468 }
469
GetTo(int64_t & value) const470 void JsonItemObject::GetTo(int64_t &value) const
471 {
472 double tmpValue = 0.0;
473 GetTo(tmpValue);
474 value = static_cast<int64_t>(tmpValue);
475 }
476
GetTo(bool & value) const477 void JsonItemObject::GetTo(bool &value) const
478 {
479 value = false;
480 if (item_ == nullptr) {
481 LOGE("value item is null");
482 return;
483 }
484 if (!IsBoolean()) {
485 return;
486 }
487 value = cJSON_IsTrue(item_) ? true : false;
488 }
489
Items() const490 std::vector<JsonItemObject> JsonItemObject::Items() const
491 {
492 std::vector<JsonItemObject> items;
493 if (item_ == nullptr) {
494 return items;
495 }
496 cJSON *current = nullptr;
497 if (item_->type == cJSON_Object || item_->type == cJSON_Array) {
498 cJSON_ArrayForEach(current, item_) {
499 JsonItemObject child;
500 child.item_ = current;
501 child.parent_ = item_;
502 items.push_back(child);
503 }
504 }
505 return items;
506 }
507
InitItem(JsonItemObject & item)508 bool JsonItemObject::InitItem(JsonItemObject &item)
509 {
510 if (!beValid_) {
511 LOGE("invalid item");
512 return false;
513 }
514 item.item_ = cJSON_CreateObject();
515 if (item.item_ == nullptr) {
516 LOGE("create new object item fail");
517 return false;
518 }
519 item.parent_ = parent_;
520 item.beValid_ = true;
521 item.itemName_ = itemName_;
522 item.itemIndex_ = itemIndex_;
523 return true;
524 }
525
InitArray()526 bool JsonItemObject::InitArray()
527 {
528 if (!beValid_) {
529 return false;
530 }
531 cJSON *newItem = cJSON_CreateArray();
532 if (newItem == nullptr) {
533 return false;
534 }
535 if (!ReplaceItem(newItem)) {
536 cJSON_Delete(newItem);
537 return false;
538 }
539 return true;
540 }
541
ReplaceItem(cJSON * newItem)542 bool JsonItemObject::ReplaceItem(cJSON *newItem)
543 {
544 if (parent_ != nullptr) {
545 if (cJSON_IsObject(parent_)) {
546 if (!cJSON_ReplaceItemInObjectCaseSensitive(parent_, itemName_.c_str(), newItem)) {
547 LOGE("replace item in object fail, itemName:%{public}s", itemName_.c_str());
548 return false;
549 }
550 } else if (cJSON_IsArray(parent_) && itemIndex_ >= 0 && itemIndex_ < cJSON_GetArraySize(parent_)) {
551 if (!cJSON_ReplaceItemInArray(parent_, itemIndex_, newItem)) {
552 LOGE("replace item in array fail, itemIndex:%{public}d", itemIndex_);
553 return false;
554 }
555 }
556 } else {
557 cJSON_Delete(item_);
558 }
559 item_ = newItem;
560 return true;
561 }
562
Erase(const std::string & key)563 void JsonItemObject::Erase(const std::string &key)
564 {
565 if (item_ == nullptr) {
566 return;
567 }
568 if (IsObject()) {
569 cJSON_DeleteItemFromObjectCaseSensitive(item_, key.c_str());
570 }
571 }
572
573
JsonObject(JsonCreateType type)574 JsonObject::JsonObject(JsonCreateType type)
575 {
576 needDeleteItem_ = true;
577 beValid_ = true;
578 if (type == JsonCreateType::JSON_CREATE_TYPE_OBJECT) {
579 item_ = cJSON_CreateObject();
580 } else {
581 item_ = cJSON_CreateArray();
582 }
583 }
584
JsonObject(const std::string & strJson)585 JsonObject::JsonObject(const std::string &strJson)
586 {
587 needDeleteItem_ = true;
588 beValid_ = true;
589 Parse(strJson);
590 }
591
~JsonObject()592 JsonObject::~JsonObject()
593 {
594 Delete();
595 }
596
Parse(const std::string & strJson)597 bool JsonObject::Parse(const std::string &strJson)
598 {
599 Delete();
600 if (!strJson.empty()) {
601 item_ = cJSON_Parse(strJson.c_str());
602 return true;
603 }
604 LOGE("strJson is empty");
605 return false;
606 }
607
Duplicate(const JsonObject & object)608 void JsonObject::Duplicate(const JsonObject &object)
609 {
610 Delete();
611 item_ = cJSON_Duplicate(object.item_, cJSON_True);
612 }
613
614 } // namespace DistributedHardware
615 } // namespace OHOS