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