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
GetDouble() const97 double JsonValue::GetDouble() const
98 {
99 return (object_ == nullptr) ? 0.0 : object_->valuedouble;
100 }
101
GetDouble(const std::string & key,double defaultVal) const102 double JsonValue::GetDouble(const std::string& key, double defaultVal) const
103 {
104 auto value = GetValue(key);
105 if (value && value->IsNumber()) {
106 return value->GetDouble();
107 }
108 return defaultVal;
109 }
110
GetString() const111 std::string JsonValue::GetString() const
112 {
113 return ((object_ == nullptr) || (object_->valuestring == nullptr)) ? "" : std::string(object_->valuestring);
114 }
115
GetNext() const116 std::unique_ptr<JsonValue> JsonValue::GetNext() const
117 {
118 if (object_ == nullptr) {
119 return std::make_unique<JsonValue>(nullptr);
120 }
121 return std::make_unique<JsonValue>(object_->next);
122 }
123
GetChild() const124 std::unique_ptr<JsonValue> JsonValue::GetChild() const
125 {
126 if (object_ == nullptr) {
127 return std::make_unique<JsonValue>(nullptr);
128 }
129 return std::make_unique<JsonValue>(object_->child);
130 }
131
GetKey() const132 std::string JsonValue::GetKey() const
133 {
134 return ((object_ == nullptr) || (object_->string == nullptr)) ? "" : std::string(object_->string);
135 }
GetValue(const std::string & key) const136 std::unique_ptr<JsonValue> JsonValue::GetValue(const std::string& key) const
137 {
138 return std::make_unique<JsonValue>(cJSON_GetObjectItem(object_, key.c_str()));
139 }
140
GetObject(const std::string & key) const141 std::unique_ptr<JsonValue> JsonValue::GetObject(const std::string& key) const
142 {
143 if (Contains(key) && GetValue(key)->IsObject()) {
144 return GetValue(key);
145 }
146 return std::make_unique<JsonValue>();
147 }
148
GetArraySize() const149 int32_t JsonValue::GetArraySize() const
150 {
151 return cJSON_GetArraySize(object_);
152 }
153
GetArrayItem(int32_t index) const154 std::unique_ptr<JsonValue> JsonValue::GetArrayItem(int32_t index) const
155 {
156 return std::make_unique<JsonValue>(cJSON_GetArrayItem(object_, index));
157 }
158
Put(const char * key,const char * value)159 bool JsonValue::Put(const char* key, const char* value)
160 {
161 if (!value || !key) {
162 return false;
163 }
164
165 cJSON* child = cJSON_CreateString(value);
166 if (child == nullptr) {
167 return false;
168 }
169 cJSON_AddItemToObject(object_, key, child);
170 return true;
171 }
172
GetJsonObject() const173 const JsonObject* JsonValue::GetJsonObject() const
174 {
175 return object_;
176 }
177
Put(const char * key,const std::unique_ptr<JsonValue> & value)178 bool JsonValue::Put(const char* key, const std::unique_ptr<JsonValue>& value)
179 {
180 if (!value || !key) {
181 return false;
182 }
183 cJSON* jsonObject = cJSON_Duplicate(value->GetJsonObject(), true);
184 if (jsonObject == nullptr) {
185 return false;
186 }
187
188 cJSON_AddItemToObject(object_, key, jsonObject);
189 return true;
190 }
191
192 // add item to array
Put(const std::unique_ptr<JsonValue> & value)193 bool JsonValue::Put(const std::unique_ptr<JsonValue>& value)
194 {
195 if (!value) {
196 return false;
197 }
198 cJSON* jsonObject = cJSON_Duplicate(value->GetJsonObject(), true);
199 if (jsonObject == nullptr) {
200 return false;
201 }
202
203 cJSON_AddItemToArray(object_, jsonObject);
204 return true;
205 }
206
Put(const char * key,size_t value)207 bool JsonValue::Put(const char* key, size_t value)
208 {
209 if (key == nullptr) {
210 return false;
211 }
212
213 cJSON* child = cJSON_CreateNumber(static_cast<double>(value));
214 if (child == nullptr) {
215 return false;
216 }
217 cJSON_AddItemToObject(object_, key, child);
218 return true;
219 }
220
Put(const char * key,int32_t value)221 bool JsonValue::Put(const char* key, int32_t value)
222 {
223 if (key == nullptr) {
224 return false;
225 }
226
227 cJSON* child = cJSON_CreateNumber(static_cast<double>(value));
228 if (child == nullptr) {
229 return false;
230 }
231 cJSON_AddItemToObject(object_, key, child);
232 return true;
233 }
234
Put(const char * key,int64_t value)235 bool JsonValue::Put(const char* key, int64_t value)
236 {
237 return Put(key, static_cast<double>(value));
238 }
239
Put(const char * key,double value)240 bool JsonValue::Put(const char* key, double value)
241 {
242 if (key == nullptr) {
243 return false;
244 }
245
246 cJSON* child = cJSON_CreateNumber(value);
247 if (child == nullptr) {
248 return false;
249 }
250 cJSON_AddItemToObject(object_, key, child);
251 return true;
252 }
253
Replace(const char * key,double value)254 bool JsonValue::Replace(const char* key, double value)
255 {
256 if (key == nullptr) {
257 return false;
258 }
259
260 cJSON* child = cJSON_CreateNumber(value);
261 if (child == nullptr) {
262 return false;
263 }
264 if (!cJSON_ReplaceItemInObject(object_, key, child)) {
265 cJSON_Delete(child);
266 return false;
267 }
268 return true;
269 }
270
Put(const char * key,bool value)271 bool JsonValue::Put(const char* key, bool value)
272 {
273 if (key == nullptr) {
274 return false;
275 }
276
277 cJSON* child = cJSON_CreateBool(value);
278 if (child == nullptr) {
279 return false;
280 }
281 cJSON_AddItemToObject(object_, key, child);
282 return true;
283 }
284
Replace(const char * key,bool value)285 bool JsonValue::Replace(const char* key, bool value)
286 {
287 if (key == nullptr) {
288 return false;
289 }
290
291 cJSON* child = cJSON_CreateBool(value);
292 if (child == nullptr) {
293 return false;
294 }
295 if (!cJSON_ReplaceItemInObject(object_, key, child)) {
296 cJSON_Delete(child);
297 return false;
298 }
299 return true;
300 }
301
Replace(const char * key,const char * value)302 bool JsonValue::Replace(const char* key, const char* value)
303 {
304 if ((value == nullptr) || (key == nullptr)) {
305 return false;
306 }
307
308 cJSON* child = cJSON_CreateString(value);
309 if (child == nullptr) {
310 return false;
311 }
312 if (!cJSON_ReplaceItemInObject(object_, key, child)) {
313 cJSON_Delete(child);
314 return false;
315 }
316 return true;
317 }
318
Replace(const char * key,int32_t value)319 bool JsonValue::Replace(const char* key, int32_t value)
320 {
321 if (key == nullptr) {
322 return false;
323 }
324
325 cJSON* child = cJSON_CreateNumber(static_cast<double>(value));
326 if (child == nullptr) {
327 return false;
328 }
329 if (!cJSON_ReplaceItemInObject(object_, key, child)) {
330 cJSON_Delete(child);
331 return false;
332 }
333 return true;
334 }
335
Replace(const char * key,const std::unique_ptr<JsonValue> & value)336 bool JsonValue::Replace(const char* key, const std::unique_ptr<JsonValue>& value)
337 {
338 if ((value == nullptr) || (key == nullptr)) {
339 return false;
340 }
341 cJSON* jsonObject = cJSON_Duplicate(value->GetJsonObject(), true);
342 if (jsonObject == nullptr) {
343 return false;
344 }
345
346 if (!cJSON_ReplaceItemInObject(object_, key, jsonObject)) {
347 cJSON_Delete(jsonObject);
348 return false;
349 }
350 return true;
351 }
352
Delete(const char * key)353 bool JsonValue::Delete(const char* key)
354 {
355 if (key == nullptr) {
356 return false;
357 }
358 cJSON_DeleteItemFromObject(object_, key);
359 return true;
360 }
361
ToString()362 std::string JsonValue::ToString()
363 {
364 std::string result;
365 if (!object_) {
366 return result;
367 }
368
369 // It is null-terminated.
370 char* unformatted = cJSON_PrintUnformatted(object_);
371 if (unformatted != nullptr) {
372 result = unformatted;
373 cJSON_free(unformatted);
374 }
375 return result;
376 }
377
GetString(const std::string & key,const std::string & defaultVal) const378 std::string JsonValue::GetString(const std::string& key, const std::string& defaultVal) const
379 {
380 auto value = GetValue(key);
381 if (value && value->IsString()) {
382 return value->GetString();
383 }
384 return defaultVal;
385 }
386
GetInt(const std::string & key,int32_t defaultVal) const387 int32_t JsonValue::GetInt(const std::string& key, int32_t defaultVal) const
388 {
389 auto value = GetValue(key);
390 if (value && value->IsNumber()) {
391 return value->GetInt();
392 }
393 return defaultVal;
394 }
395
GetUInt(const std::string & key,uint32_t defaultVal) const396 uint32_t JsonValue::GetUInt(const std::string& key, uint32_t defaultVal) const
397 {
398 auto value = GetValue(key);
399 if (value && value->IsNumber()) {
400 return value->GetUInt();
401 }
402 return defaultVal;
403 }
404
ParseJsonData(const char * data,const char ** parseEnd)405 std::unique_ptr<JsonValue> JsonUtil::ParseJsonData(const char* data, const char** parseEnd)
406 {
407 return std::make_unique<JsonValue>(cJSON_ParseWithOpts(data, parseEnd, true), true);
408 }
409
ParseJsonString(const std::string & content,const char ** parseEnd)410 std::unique_ptr<JsonValue> JsonUtil::ParseJsonString(const std::string& content, const char** parseEnd)
411 {
412 return ParseJsonData(content.c_str(), parseEnd);
413 }
414
Create(bool isRoot)415 std::unique_ptr<JsonValue> JsonUtil::Create(bool isRoot)
416 {
417 return std::make_unique<JsonValue>(cJSON_CreateObject(), isRoot);
418 }
419
CreateArray(bool isRoot)420 std::unique_ptr<JsonValue> JsonUtil::CreateArray(bool isRoot)
421 {
422 return std::make_unique<JsonValue>(cJSON_CreateArray(), isRoot);
423 }
424
425 } // namespace OHOS::Ace
426