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 #include "nlohmann/json.hpp"
19 #include "dm_log.h"
20
21 namespace OHOS {
22 namespace DistributedHardware {
GetJsonPointer(void * pointer)23 static nlohmann::json *GetJsonPointer(void *pointer)
24 {
25 return static_cast<nlohmann::json*>(pointer);
26 }
27
ToJson(JsonItemObject & itemObject,const std::string & value)28 void ToJson(JsonItemObject &itemObject, const std::string &value)
29 {
30 if (itemObject.item_ != nullptr) {
31 *GetJsonPointer(itemObject.item_) = value;
32 }
33 }
34
ToJson(JsonItemObject & itemObject,const char * value)35 void ToJson(JsonItemObject &itemObject, const char *value)
36 {
37 if (itemObject.item_ != nullptr && value != nullptr) {
38 *GetJsonPointer(itemObject.item_) = std::string(value);
39 }
40 }
41
ToJson(JsonItemObject & itemObject,const double & value)42 void ToJson(JsonItemObject &itemObject, const double &value)
43 {
44 if (itemObject.item_ != nullptr) {
45 *GetJsonPointer(itemObject.item_) = value;
46 }
47 }
48
ToJson(JsonItemObject & itemObject,const bool & value)49 void ToJson(JsonItemObject &itemObject, const bool &value)
50 {
51 if (itemObject.item_ != nullptr) {
52 *GetJsonPointer(itemObject.item_) = value;
53 }
54 }
55
ToJson(JsonItemObject & itemObject,const uint8_t & value)56 void ToJson(JsonItemObject &itemObject, const uint8_t &value)
57 {
58 if (itemObject.item_ != nullptr) {
59 *GetJsonPointer(itemObject.item_) = (int)value;
60 }
61 }
62
ToJson(JsonItemObject & itemObject,const int16_t & value)63 void ToJson(JsonItemObject &itemObject, const int16_t &value)
64 {
65 if (itemObject.item_ != nullptr) {
66 *GetJsonPointer(itemObject.item_) = value;
67 }
68 }
69
ToJson(JsonItemObject & itemObject,const uint16_t & value)70 void ToJson(JsonItemObject &itemObject, const uint16_t &value)
71 {
72 if (itemObject.item_ != nullptr) {
73 *GetJsonPointer(itemObject.item_) = value;
74 }
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 *GetJsonPointer(itemObject.item_) = value;
81 }
82 }
83
ToJson(JsonItemObject & itemObject,const uint32_t & value)84 void ToJson(JsonItemObject &itemObject, const uint32_t &value)
85 {
86 if (itemObject.item_ != nullptr) {
87 *GetJsonPointer(itemObject.item_) = value;
88 }
89 }
90
ToJson(JsonItemObject & itemObject,const int64_t & value)91 void ToJson(JsonItemObject &itemObject, const int64_t &value)
92 {
93 if (itemObject.item_ != nullptr) {
94 *GetJsonPointer(itemObject.item_) = value;
95 }
96 }
97
ToJson(JsonItemObject & itemObject,const uint64_t & value)98 void ToJson(JsonItemObject &itemObject, const uint64_t &value)
99 {
100 if (itemObject.item_ != nullptr) {
101 *GetJsonPointer(itemObject.item_) = value;
102 }
103 }
104
FromJson(const JsonItemObject & itemObject,std::string & value)105 void FromJson(const JsonItemObject &itemObject, std::string &value)
106 {
107 itemObject.GetTo(value);
108 }
109
FromJson(const JsonItemObject & itemObject,double & value)110 void FromJson(const JsonItemObject &itemObject, double &value)
111 {
112 itemObject.GetTo(value);
113 }
114
FromJson(const JsonItemObject & itemObject,bool & value)115 void FromJson(const JsonItemObject &itemObject, bool &value)
116 {
117 itemObject.GetTo(value);
118 }
119
FromJson(const JsonItemObject & itemObject,uint8_t & value)120 void FromJson(const JsonItemObject &itemObject, uint8_t &value)
121 {
122 int32_t tmpValue = 0;
123 itemObject.GetTo(tmpValue);
124 value = static_cast<uint8_t>(tmpValue);
125 }
126
FromJson(const JsonItemObject & itemObject,int16_t & value)127 void FromJson(const JsonItemObject &itemObject, int16_t &value)
128 {
129 int32_t tmpValue = 0;
130 itemObject.GetTo(tmpValue);
131 value = static_cast<int16_t>(tmpValue);
132 }
133
FromJson(const JsonItemObject & itemObject,uint16_t & value)134 void FromJson(const JsonItemObject &itemObject, uint16_t &value)
135 {
136 int32_t tmpValue = 0;
137 itemObject.GetTo(tmpValue);
138 value = static_cast<uint16_t>(tmpValue);
139 }
140
FromJson(const JsonItemObject & itemObject,int32_t & value)141 void FromJson(const JsonItemObject &itemObject, int32_t &value)
142 {
143 itemObject.GetTo(value);
144 }
145
FromJson(const JsonItemObject & itemObject,uint32_t & value)146 void FromJson(const JsonItemObject &itemObject, uint32_t &value)
147 {
148 int32_t tmpValue = 0;
149 itemObject.GetTo(tmpValue);
150 value = static_cast<uint32_t>(tmpValue);
151 }
152
FromJson(const JsonItemObject & itemObject,int64_t & value)153 void FromJson(const JsonItemObject &itemObject, int64_t &value)
154 {
155 itemObject.GetTo(value);
156 }
157
FromJson(const JsonItemObject & itemObject,uint64_t & value)158 void FromJson(const JsonItemObject &itemObject, uint64_t &value)
159 {
160 int64_t tmpValue = 0;
161 itemObject.GetTo(tmpValue);
162 value = static_cast<uint64_t>(tmpValue);
163 }
164
ToString(const JsonItemObject & jsonItem)165 std::string ToString(const JsonItemObject &jsonItem)
166 {
167 return jsonItem.Dump();
168 }
169
JsonItemObject()170 JsonItemObject::JsonItemObject()
171 {}
172
JsonItemObject(const JsonItemObject & object)173 JsonItemObject::JsonItemObject(const JsonItemObject &object)
174 {
175 parent_ = object.parent_;
176 itemName_ = object.itemName_;
177 itemIndex_ = object.itemIndex_;
178 needDeleteItem_ = object.needDeleteItem_;
179 if (object.needDeleteItem_ && object.item_ != nullptr) {
180 item_ = new nlohmann::json();
181 if (item_ != nullptr) {
182 *GetJsonPointer(item_) = *GetJsonPointer(object.item_);
183 }
184 } else {
185 item_ = object.item_;
186 }
187 }
188
~JsonItemObject()189 JsonItemObject::~JsonItemObject()
190 {
191 Delete();
192 }
193
Delete()194 void JsonItemObject::Delete()
195 {
196 if (needDeleteItem_ && item_ != nullptr) {
197 nlohmann::json *item = GetJsonPointer(item_);
198 delete item;
199 }
200 item_ = nullptr;
201 }
202
IsString() const203 bool JsonItemObject::IsString() const
204 {
205 if (item_ == nullptr) {
206 return false;
207 }
208 return GetJsonPointer(item_)->is_string();
209 }
210
IsNumber() const211 bool JsonItemObject::IsNumber() const
212 {
213 if (item_ == nullptr) {
214 return false;
215 }
216 return GetJsonPointer(item_)->is_number();
217 }
218
IsNumberInteger() const219 bool JsonItemObject::IsNumberInteger() const
220 {
221 if (item_ == nullptr) {
222 return false;
223 }
224 return GetJsonPointer(item_)->is_number_integer();
225 }
226
IsArray() const227 bool JsonItemObject::IsArray() const
228 {
229 if (item_ == nullptr) {
230 return false;
231 }
232 return GetJsonPointer(item_)->is_array();
233 }
234
IsBoolean() const235 bool JsonItemObject::IsBoolean() const
236 {
237 if (item_ == nullptr) {
238 return false;
239 }
240 return GetJsonPointer(item_)->is_boolean();
241 }
242
IsObject() const243 bool JsonItemObject::IsObject() const
244 {
245 if (item_ == nullptr) {
246 return false;
247 }
248 return GetJsonPointer(item_)->is_object();
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 (*GetJsonPointer(item_))[key] = *GetJsonPointer(object.item_);
258 }
259
operator =(const JsonItemObject & object)260 JsonItemObject& JsonItemObject::operator=(const JsonItemObject &object)
261 {
262 parent_ = object.parent_;
263 itemName_ = object.itemName_;
264 itemIndex_ = object.itemIndex_;
265 needDeleteItem_ = object.needDeleteItem_;
266 if (object.needDeleteItem_ && object.item_ != nullptr) {
267 if (item_ == nullptr) {
268 item_ = new nlohmann::json();
269 }
270 if (item_ != nullptr) {
271 *GetJsonPointer(item_) = *GetJsonPointer(object.item_);
272 }
273 } else {
274 item_ = object.item_;
275 }
276 return *this;
277 }
278
DumpFormated() const279 std::string JsonItemObject::DumpFormated() const
280 {
281 return Dump(true, true);
282 }
283
Dump() const284 std::string JsonItemObject::Dump() const
285 {
286 return Dump(false, true);
287 }
288
Dump(bool formatFlag,bool isIgnoreError) const289 std::string JsonItemObject::Dump(bool formatFlag, bool isIgnoreError) const
290 {
291 if (item_ == nullptr) {
292 LOGE("item_ is nullptr");
293 return "";
294 }
295 int indent = -1;
296 char indent_char = ' ';
297 bool ensure_ascii = false;
298 nlohmann::detail::error_handler_t error_handler = nlohmann::detail::error_handler_t::strict;
299 if (formatFlag) {
300 indent = 1;
301 indent_char = '\t';
302 }
303 if (isIgnoreError) {
304 error_handler = nlohmann::detail::error_handler_t::ignore;
305 }
306 return GetJsonPointer(item_)->dump(indent, indent_char, ensure_ascii, error_handler);
307 }
308
operator [](const std::string & key)309 JsonItemObject JsonItemObject::operator[](const std::string &key)
310 {
311 JsonItemObject itemObject = At(key);
312 if (itemObject.item_ == nullptr) {
313 auto& newItem = (*GetJsonPointer(item_))[key];
314 itemObject.item_ = &newItem;
315 itemObject.beValid_ = true;
316 }
317 return itemObject;
318 }
319
operator [](const std::string & key) const320 const JsonItemObject JsonItemObject::operator[](const std::string &key) const
321 {
322 return At(key);
323 }
324
Contains(const std::string & key) const325 bool JsonItemObject::Contains(const std::string &key) const
326 {
327 if (item_ == nullptr) {
328 LOGE("item_ is nullptr");
329 return false;
330 }
331 return GetJsonPointer(item_)->contains(key);
332 }
333
IsDiscarded() const334 bool JsonItemObject::IsDiscarded() const
335 {
336 if (item_ == nullptr) {
337 LOGE("item_ is nullptr");
338 return true;
339 }
340 return GetJsonPointer(item_)->is_discarded();
341 }
342
PushBack(const std::string & strValue)343 bool JsonItemObject::PushBack(const std::string &strValue)
344 {
345 if (item_ == nullptr) {
346 LOGE("item_ is nullptr");
347 return false;
348 }
349 if (!GetJsonPointer(item_)->is_array()) {
350 LOGE("item_ type is not array");
351 return false;
352 }
353 GetJsonPointer(item_)->push_back(strValue);
354 return true;
355 }
356
PushBack(const double & value)357 bool JsonItemObject::PushBack(const double &value)
358 {
359 if (item_ == nullptr) {
360 LOGE("item_ is nullptr");
361 return false;
362 }
363 if (!GetJsonPointer(item_)->is_array()) {
364 LOGE("item_ type is not array");
365 return false;
366 }
367 GetJsonPointer(item_)->push_back(value);
368 return true;
369 }
370
PushBack(const int64_t & value)371 bool JsonItemObject::PushBack(const int64_t &value)
372 {
373 if (item_ == nullptr) {
374 LOGE("item_ is nullptr");
375 return false;
376 }
377 if (!GetJsonPointer(item_)->is_array()) {
378 LOGE("item_ type is not array");
379 return false;
380 }
381 GetJsonPointer(item_)->push_back(value);
382 return true;
383 }
384
PushBack(const JsonItemObject & item)385 bool JsonItemObject::PushBack(const JsonItemObject &item)
386 {
387 if (item_ == nullptr || item.item_ == nullptr) {
388 LOGE("item_ or item.item_ is nullptr");
389 return false;
390 }
391 if (!GetJsonPointer(item_)->is_array()) {
392 LOGE("item_ type is not array");
393 return false;
394 }
395 GetJsonPointer(item_)->push_back(*GetJsonPointer(item.item_));
396 return true;
397 }
398
AddItemToArray(JsonItemObject & item)399 void JsonItemObject::AddItemToArray(JsonItemObject &item)
400 {
401 PushBack(item);
402 }
403
Key() const404 std::string JsonItemObject::Key() const
405 {
406 return itemName_;
407 }
408
At(const std::string & key) const409 JsonItemObject JsonItemObject::At(const std::string &key) const
410 {
411 JsonItemObject operationItem;
412 if (item_ == nullptr) {
413 LOGE("item_ is nullptr");
414 return operationItem;
415 }
416 if (Contains(key)) {
417 auto& findItem = GetJsonPointer(item_)->at(key);
418 operationItem.item_ = &findItem;
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 GetJsonPointer(item_)->get_to(value);
437 }
438
GetTo(double & value) const439 void JsonItemObject::GetTo(double &value) const
440 {
441 value = 0.0;
442 if (item_ == nullptr) {
443 LOGE("value item is null");
444 return;
445 }
446 if (!IsNumber()) {
447 return;
448 }
449 GetJsonPointer(item_)->get_to(value);
450 }
451
GetTo(int32_t & value) const452 void JsonItemObject::GetTo(int32_t &value) const
453 {
454 int64_t tmpValue = 0;
455 GetTo(tmpValue);
456 value = static_cast<int32_t>(tmpValue);
457 }
458
GetTo(uint32_t & value) const459 void JsonItemObject::GetTo(uint32_t &value) const
460 {
461 int64_t tmpValue = 0;
462 GetTo(tmpValue);
463 value = static_cast<uint32_t>(tmpValue);
464 }
465
GetTo(int64_t & value) const466 void JsonItemObject::GetTo(int64_t &value) const
467 {
468 value = 0;
469 if (item_ == nullptr) {
470 LOGE("value item is null");
471 return;
472 }
473 if (!IsNumberInteger()) {
474 return;
475 }
476 GetJsonPointer(item_)->get_to(value);
477 }
478
GetTo(bool & value) const479 void JsonItemObject::GetTo(bool &value) const
480 {
481 value = false;
482 if (item_ == nullptr) {
483 LOGE("value item is null");
484 return;
485 }
486 if (!IsBoolean()) {
487 return;
488 }
489 GetJsonPointer(item_)->get_to(value);
490 }
491
Items() const492 std::vector<JsonItemObject> JsonItemObject::Items() const
493 {
494 std::vector<JsonItemObject> items;
495 if (item_ == nullptr) {
496 return items;
497 }
498 for (auto &element : GetJsonPointer(item_)->items()) {
499 JsonItemObject newItem;
500 newItem.itemName_ = element.key();
501 newItem.item_ = &(element.value());
502 newItem.parent_ = item_;
503 items.push_back(newItem);
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 if (item.item_ == nullptr) {
515 item.needDeleteItem_ = true;
516 item.item_ = new nlohmann::json();
517 if (item.item_ == nullptr) {
518 LOGE("new item fail");
519 return false;
520 }
521 }
522 item.parent_ = parent_;
523 item.beValid_ = true;
524 item.itemName_ = itemName_;
525 item.itemIndex_ = itemIndex_;
526 return true;
527 }
528
InitArray()529 bool JsonItemObject::InitArray()
530 {
531 if (!beValid_ || item_ == nullptr) {
532 return false;
533 }
534 *GetJsonPointer(item_) = nlohmann::json::array({});
535 return true;
536 }
537
ReplaceItem(void * newItem)538 bool JsonItemObject::ReplaceItem(void *newItem)
539 {
540 if (newItem == nullptr) {
541 LOGE("newItem is null");
542 return false;
543 }
544 if (item_ == nullptr) {
545 needDeleteItem_ = true;
546 item_ = new nlohmann::json();
547 if (item_ == nullptr) {
548 LOGE("new item fail");
549 return false;
550 }
551 }
552 *GetJsonPointer(item_) = *GetJsonPointer(newItem);
553 return true;
554 }
555
Erase(const std::string & key)556 void JsonItemObject::Erase(const std::string &key)
557 {
558 if (item_ == nullptr) {
559 return;
560 }
561 if (IsObject()) {
562 GetJsonPointer(item_)->erase(key);
563 }
564 }
565
566
JsonObject(JsonCreateType type)567 JsonObject::JsonObject(JsonCreateType type)
568 {
569 needDeleteItem_ = true;
570 item_ = new nlohmann::json();
571 if (item_ != nullptr) {
572 beValid_ = true;
573 if (type == JsonCreateType::JSON_CREATE_TYPE_ARRAY) {
574 *GetJsonPointer(item_) = nlohmann::json::array({});
575 }
576 }
577 }
578
JsonObject(const std::string & strJson)579 JsonObject::JsonObject(const std::string &strJson)
580 {
581 needDeleteItem_ = true;
582 item_ = new nlohmann::json();
583 if (item_ != nullptr) {
584 beValid_ = true;
585 Parse(strJson);
586 }
587 }
588
~JsonObject()589 JsonObject::~JsonObject()
590 {
591 Delete();
592 }
593
Parse(const std::string & strJson)594 bool JsonObject::Parse(const std::string &strJson)
595 {
596 if (item_ == nullptr) {
597 return false;
598 }
599 if (!strJson.empty()) {
600 *GetJsonPointer(item_) = nlohmann::json::parse(strJson, nullptr, false);
601 return true;
602 }
603 LOGE("strJson is empty");
604 *GetJsonPointer(item_) = nlohmann::json::parse(strJson, nullptr, false);
605 return false;
606 }
607
Duplicate(const JsonObject & object)608 void JsonObject::Duplicate(const JsonObject &object)
609 {
610 if (item_ != nullptr && object.item_ != nullptr) {
611 *GetJsonPointer(item_) = *GetJsonPointer(object.item_);
612 }
613 }
614
615 } // namespace DistributedHardware
616 } // namespace OHOS