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