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_parser.h"
17
18 #include <cstdint>
19 #include <cmath>
20
21 #include "fi_log.h"
22 #include "devicestatus_define.h"
23
24 #undef LOG_TAG
25 #define LOG_TAG "JsonParser"
26
27 namespace OHOS {
28 namespace Msdp {
29 namespace DeviceStatus {
30
JsonParser(const char * jsonStr)31 JsonParser::JsonParser(const char *jsonStr)
32 {
33 json_ = cJSON_Parse(jsonStr);
34 CHKPV(json_);
35 }
36
~JsonParser()37 JsonParser::~JsonParser()
38 {
39 if (json_ != nullptr) {
40 cJSON_Delete(json_);
41 json_ = nullptr;
42 }
43 }
44
JsonParser(JsonParser && other)45 JsonParser::JsonParser(JsonParser&& other) noexcept : json_(other.json_)
46 {
47 other.json_ = nullptr;
48 }
49
operator =(JsonParser && other)50 JsonParser& JsonParser::operator=(JsonParser&& other) noexcept
51 {
52 if (this == &other) {
53 return *this;
54 }
55 if (json_ != nullptr) {
56 cJSON_Delete(json_);
57 }
58 json_ = other.json_;
59 other.json_ = nullptr;
60 return *this;
61 }
62
Get() const63 const cJSON* JsonParser::Get() const
64 {
65 return json_;
66 }
67
IsInteger(const cJSON * json)68 bool JsonParser::IsInteger(const cJSON *json)
69 {
70 if (json == nullptr || json->type != cJSON_Number) {
71 return false;
72 }
73 return json->valuedouble == json->valueint;
74 }
75
ParseInt32(const cJSON * json,const std::string & key,int32_t & value)76 int32_t JsonParser::ParseInt32(const cJSON *json, const std::string &key, int32_t &value)
77 {
78 cJSON *jsonNode = cJSON_GetObjectItemCaseSensitive(json, key.c_str());
79 CHKPR(jsonNode, RET_ERR);
80 if (!cJSON_IsNumber(jsonNode)) {
81 FI_HILOGE("value is not number");
82 return RET_ERR;
83 }
84 if (!IsInteger(jsonNode)) {
85 FI_HILOGE("value is not integer");
86 return RET_ERR;
87 }
88 if (jsonNode->valueint < std::numeric_limits<int32_t>::min() ||
89 jsonNode->valueint > std::numeric_limits<int32_t>::max()) {
90 FI_HILOGE("value is out of int32_t bounds");
91 return RET_ERR;
92 }
93 value = jsonNode->valueint;
94 return RET_OK;
95 }
96
ParseString(const cJSON * json,const std::string & key,std::string & value)97 int32_t JsonParser::ParseString(const cJSON *json, const std::string &key, std::string &value)
98 {
99 cJSON *jsonNode = cJSON_GetObjectItemCaseSensitive(json, key.c_str());
100 CHKPR(jsonNode, RET_ERR);
101 if (!cJSON_IsString(jsonNode)) {
102 FI_HILOGE("value is not str");
103 return RET_ERR;
104 }
105 value = jsonNode->valuestring;
106 return RET_OK;
107 }
108
ParseBool(const cJSON * json,const std::string & key,bool & value)109 int32_t JsonParser::ParseBool(const cJSON *json, const std::string &key, bool &value)
110 {
111 cJSON *jsonNode = cJSON_GetObjectItemCaseSensitive(json, key.c_str());
112 CHKPR(jsonNode, RET_ERR);
113 if (!cJSON_IsBool(jsonNode)) {
114 FI_HILOGE("value is not bool");
115 return RET_ERR;
116 }
117 value = cJSON_IsTrue(jsonNode);
118 return RET_OK;
119 }
120
ParseStringArray(const cJSON * json,const std::string & key,std::vector<std::string> & value,int32_t maxSize)121 int32_t JsonParser::ParseStringArray(const cJSON *json, const std::string &key, std::vector<std::string> &value,
122 int32_t maxSize)
123 {
124 cJSON *jsonNode = cJSON_GetObjectItemCaseSensitive(json, key.c_str());
125 CHKPR(jsonNode, RET_ERR);
126 if (!cJSON_IsArray(jsonNode)) {
127 FI_HILOGE("jsonNode is not array");
128 return RET_ERR;
129 }
130 int32_t arraySize = cJSON_GetArraySize(jsonNode);
131 if (arraySize > maxSize) {
132 FI_HILOGW("arraySize is too much, truncate it");
133 }
134 value.clear();
135 for (int32_t i = 0; i < std::min(maxSize, arraySize); i++) {
136 cJSON* arrayItem = cJSON_GetArrayItem(jsonNode, i);
137 if (!cJSON_IsString(arrayItem)) {
138 FI_HILOGE("The arrayItem is not string");
139 return RET_ERR;
140 }
141 value.push_back(arrayItem->valuestring);
142 }
143 return RET_OK;
144 }
145 } // namespace JSON_PARSER_H
146 } // namespace Msdp
147 } // namespace OHOS