1 /*
2 * Copyright (C) 2024 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_helper.h"
17
18 #include "cJSON.h"
19 #include "effect_log.h"
20
21 namespace OHOS {
22 namespace Media {
23 namespace Effect {
24
25 namespace {
26 #define EFFECT_JSON_FALSE_RETURN(cond) \
27 do { \
28 if (!(cond)) { \
29 EFFECT_LOGE("[%{public}s:%{public}d] Effect json cond false!", __FUNCTION__, __LINE__); \
30 return false; \
31 } \
32 } while (0)
33
34 #define EFFECT_JSON_FALSE_RETURN_WITH_WORK(cond, work) \
35 do { \
36 if (!(cond)) { \
37 EFFECT_LOGE("[%{public}s:%{public}d] Effect json cond false!", __FUNCTION__, __LINE__); \
38 work; \
39 return false; \
40 } \
41 } while (0)
42 }
43
EffectJson(Json * json,bool isRoot)44 EffectJson::EffectJson(Json *json, bool isRoot) : json_(json), isRoot_(isRoot) {}
45
~EffectJson()46 EffectJson::~EffectJson()
47 {
48 if (json_ != nullptr && isRoot_) {
49 cJSON_Delete(json_);
50 }
51 json_ = nullptr;
52 }
53
IsBool() const54 bool EffectJson::IsBool() const
55 {
56 EFFECT_JSON_FALSE_RETURN(json_ != nullptr);
57 return static_cast<bool>(cJSON_IsBool(json_));
58 }
59
IsNumber() const60 bool EffectJson::IsNumber() const
61 {
62 EFFECT_JSON_FALSE_RETURN(json_ != nullptr);
63 return static_cast<bool>(cJSON_IsNumber(json_));
64 }
65
IsString() const66 bool EffectJson::IsString() const
67 {
68 EFFECT_JSON_FALSE_RETURN(json_ != nullptr);
69 return static_cast<bool>(cJSON_IsString(json_));
70 }
71
IsArray() const72 bool EffectJson::IsArray() const
73 {
74 EFFECT_JSON_FALSE_RETURN(json_ != nullptr);
75 return static_cast<bool>(cJSON_IsArray(json_));
76 }
77
IsObject() const78 bool EffectJson::IsObject() const
79 {
80 EFFECT_JSON_FALSE_RETURN(json_ != nullptr);
81 return static_cast<bool>(cJSON_IsObject(json_));
82 }
83
IsValid() const84 bool EffectJson::IsValid() const
85 {
86 EFFECT_JSON_FALSE_RETURN(json_ != nullptr);
87 return !static_cast<bool>(cJSON_IsInvalid(json_));
88 }
89
IsNull() const90 bool EffectJson::IsNull() const
91 {
92 EFFECT_JSON_FALSE_RETURN(json_ != nullptr);
93 return static_cast<bool>(cJSON_IsNull(json_));
94 }
95
HasElement(const std::string & key) const96 bool EffectJson::HasElement(const std::string &key) const
97 {
98 EFFECT_JSON_FALSE_RETURN(json_ != nullptr);
99 return static_cast<bool>(cJSON_HasObjectItem(json_, key.c_str()));
100 }
101
GetElement(const std::string & key)102 EffectJsonPtr EffectJson::GetElement(const std::string &key)
103 {
104 if (!HasElement(key)) {
105 return nullptr;
106 }
107 cJSON *element = cJSON_GetObjectItemCaseSensitive(json_, key.c_str());
108 return std::make_shared<EffectJson>(element, false);
109 }
110
GetInt()111 int32_t EffectJson::GetInt()
112 {
113 if (!IsNumber()) {
114 return 0;
115 }
116 return static_cast<int32_t>(cJSON_GetNumberValue(json_));
117 }
118
GetInt(const std::string & key,int32_t defaultValue)119 int32_t EffectJson::GetInt(const std::string &key, int32_t defaultValue)
120 {
121 auto element = GetElement(key);
122 if (element == nullptr || element->IsNull() || !element->IsNumber()) {
123 return defaultValue;
124 }
125
126 return element->GetInt();
127 }
128
GetUInt()129 uint32_t EffectJson::GetUInt()
130 {
131 if (!IsNumber()) {
132 return 0;
133 }
134 return static_cast<int32_t>(cJSON_GetNumberValue(json_));
135 }
136
GetUInt(const std::string & key,uint32_t defaultValue)137 uint32_t EffectJson::GetUInt(const std::string &key, uint32_t defaultValue)
138 {
139 auto element = GetElement(key);
140 if (element == nullptr || element->IsNull() || !element->IsNumber()) {
141 return defaultValue;
142 }
143
144 return element->GetUInt();
145 }
146
GetFloat()147 float EffectJson::GetFloat()
148 {
149 if (!IsNumber()) {
150 return 0.0f;
151 }
152 return static_cast<float>(cJSON_GetNumberValue(json_));
153 }
154
GetFloat(const std::string & key,float defaultValue)155 float EffectJson::GetFloat(const std::string &key, float defaultValue)
156 {
157 auto element = GetElement(key);
158 if (element == nullptr || element->IsNull() || !element->IsNumber()) {
159 return defaultValue;
160 }
161
162 return element->GetFloat();
163 }
164
GetDouble()165 double EffectJson::GetDouble()
166 {
167 if (!IsNumber()) {
168 return 0;
169 }
170 return cJSON_GetNumberValue(json_);
171 }
172
GetDouble(const std::string & key,double defaultValue)173 double EffectJson::GetDouble(const std::string &key, double defaultValue)
174 {
175 auto element = GetElement(key);
176 if (element == nullptr || element->IsNull() || !element->IsNumber()) {
177 return defaultValue;
178 }
179
180 return element->GetDouble();
181 }
182
GetBool()183 bool EffectJson::GetBool()
184 {
185 if (!IsBool()) {
186 return false;
187 }
188 return static_cast<bool>(cJSON_IsTrue(json_));
189 }
190
GetBool(const std::string & key,bool defaultValue)191 bool EffectJson::GetBool(const std::string &key, bool defaultValue)
192 {
193 auto element = GetElement(key);
194 if (element == nullptr || element->IsNull() || !element->IsBool()) {
195 return defaultValue;
196 }
197
198 return element->GetBool();
199 }
200
GetString()201 std::string EffectJson::GetString()
202 {
203 if (!IsString()) {
204 return "";
205 }
206 return cJSON_GetStringValue(json_);
207 }
208
GetString(const std::string & key,const std::string & defaultValue)209 std::string EffectJson::GetString(const std::string &key, const std::string &defaultValue)
210 {
211 auto element = GetElement(key);
212 if (element == nullptr || element->IsNull() || !element->IsString()) {
213 return defaultValue;
214 }
215
216 return element->GetString();
217 }
218
GetArray()219 std::vector<EffectJsonPtr> EffectJson::GetArray()
220 {
221 std::vector<EffectJsonPtr> elements;
222 if (!IsArray()) {
223 return elements;
224 }
225
226 cJSON *element = nullptr;
227 cJSON_ArrayForEach(element, json_) {
228 elements.push_back(std::make_shared<EffectJson>(element, false));
229 }
230 return elements;
231 }
232
GetArray(const std::string & key)233 std::vector<EffectJsonPtr> EffectJson::GetArray(const std::string &key)
234 {
235 std::vector<EffectJsonPtr> elements;
236 auto element = GetElement(key);
237 if (element == nullptr || element->IsNull() || !element->IsArray()) {
238 return elements;
239 }
240
241 return element->GetArray();
242 }
243
DeleteJson(cJSON * json,bool isAllowDelete=true)244 void DeleteJson(cJSON *json, bool isAllowDelete = true)
245 {
246 if (isAllowDelete && json != nullptr) {
247 cJSON_Delete(json);
248 }
249 }
250
Put(const std::string & key,Json * json,bool isAllowDelete)251 bool EffectJson::Put(const std::string &key, Json *json, bool isAllowDelete)
252 {
253 EFFECT_JSON_FALSE_RETURN(json != nullptr && json_ != nullptr);
254
255 bool res = static_cast<bool>(cJSON_AddItemToObject(json_, key.c_str(), json));
256 EFFECT_JSON_FALSE_RETURN_WITH_WORK(res, DeleteJson(json, isAllowDelete));
257 return true;
258 }
259
Put(const std::string & key,EffectJsonPtr & json)260 bool EffectJson::Put(const std::string &key, EffectJsonPtr &json)
261 {
262 EFFECT_JSON_FALSE_RETURN(json != nullptr && json->json_ != nullptr);
263
264 cJSON *jsonObject = json->json_;
265 bool isAllowDelete = false;
266 if (json->isRoot_) {
267 jsonObject = cJSON_Duplicate(json->json_, true);
268 isAllowDelete = true;
269 }
270 return Put(key, jsonObject, isAllowDelete);
271 }
272
Put(const std::string & key,int32_t value)273 bool EffectJson::Put(const std::string &key, int32_t value)
274 {
275 return Put(key, static_cast<double>(value));
276 }
277
Put(const std::string & key,uint32_t value)278 bool EffectJson::Put(const std::string &key, uint32_t value)
279 {
280 return Put(key, static_cast<double>(value));
281 }
282
Put(const std::string & key,float value)283 bool EffectJson::Put(const std::string &key, float value)
284 {
285 return Put(key, static_cast<double>(value));
286 }
287
Put(const std::string & key,double value)288 bool EffectJson::Put(const std::string &key, double value)
289 {
290 cJSON *child = cJSON_CreateNumber(value);
291 return Put(key, child);
292 }
293
Put(const std::string & key,bool value)294 bool EffectJson::Put(const std::string &key, bool value)
295 {
296 cJSON *child = cJSON_CreateBool(value);
297 return Put(key, child);
298 }
299
Put(const std::string & key,const std::string & value)300 bool EffectJson::Put(const std::string &key, const std::string &value)
301 {
302 cJSON *child = cJSON_CreateString(value.c_str());
303 return Put(key, child);
304 }
305
Put(const std::string & key,const char * value)306 bool EffectJson::Put(const std::string &key, const char *value)
307 {
308 EFFECT_JSON_FALSE_RETURN(value != nullptr);
309 cJSON *child = cJSON_CreateString(value);
310 return Put(key, child);
311 }
312
Add(Json * json,bool isAllowDelete) const313 bool EffectJson::Add(Json *json, bool isAllowDelete) const
314 {
315 EFFECT_JSON_FALSE_RETURN(json != nullptr && json_ != nullptr);
316
317 bool res = static_cast<bool>(cJSON_AddItemToArray(json_, json));
318 EFFECT_JSON_FALSE_RETURN_WITH_WORK(res, DeleteJson(json, isAllowDelete));
319 return true;
320 }
321
Add(EffectJsonPtr & json) const322 bool EffectJson::Add(EffectJsonPtr &json) const
323 {
324 EFFECT_JSON_FALSE_RETURN(json != nullptr && json->json_ != nullptr);
325
326 cJSON *jsonObject = json->json_;
327 bool isAllowDelete = false;
328 if (json->isRoot_) {
329 jsonObject = cJSON_Duplicate(json->json_, true);
330 isAllowDelete = true;
331 }
332 return Add(jsonObject, isAllowDelete);
333 }
334
Add(int32_t value) const335 bool EffectJson::Add(int32_t value) const
336 {
337 return Add(static_cast<double>(value));
338 }
339
Add(uint32_t value) const340 bool EffectJson::Add(uint32_t value) const
341 {
342 return Add(static_cast<double>(value));
343 }
344
Add(float value) const345 bool EffectJson::Add(float value) const
346 {
347 return Add(static_cast<double>(value));
348 }
349
Add(double value) const350 bool EffectJson::Add(double value) const
351 {
352 EFFECT_JSON_FALSE_RETURN(IsArray());
353
354 cJSON *child = cJSON_CreateNumber(value);
355 return Add(child);
356 }
357
Add(bool value) const358 bool EffectJson::Add(bool value) const
359 {
360 EFFECT_JSON_FALSE_RETURN(IsArray());
361
362 cJSON *child = cJSON_CreateBool(value);
363 return Add(child);
364 }
365
Add(const std::string & value) const366 bool EffectJson::Add(const std::string &value) const
367 {
368 EFFECT_JSON_FALSE_RETURN(IsArray());
369
370 cJSON *child = cJSON_CreateString(value.c_str());
371 return Add(child);
372 }
373
Add(const char * value) const374 bool EffectJson::Add(const char *value) const
375 {
376 EFFECT_JSON_FALSE_RETURN(IsArray());
377 EFFECT_JSON_FALSE_RETURN(value != nullptr);
378
379 cJSON *child = cJSON_CreateString(value);
380 return Add(child);
381 }
382
Replace(const std::string & key,Json * json,bool jsonObject)383 bool EffectJson::Replace(const std::string &key, Json *json, bool jsonObject)
384 {
385 EFFECT_JSON_FALSE_RETURN(json != nullptr && json_ != nullptr);
386
387 bool res =
388 static_cast<bool>(cJSON_ReplaceItemInObjectCaseSensitive(json_, key.c_str(), json));
389 EFFECT_JSON_FALSE_RETURN_WITH_WORK(res, DeleteJson(json, jsonObject));
390 return true;
391 }
392
Replace(const std::string & key,EffectJsonPtr & json)393 bool EffectJson::Replace(const std::string &key, EffectJsonPtr &json)
394 {
395 EFFECT_JSON_FALSE_RETURN(json != nullptr && json->json_ != nullptr);
396
397 cJSON *jsonObject = json->json_;
398 bool isAllowDelete = false;
399 if (json->isRoot_) {
400 jsonObject = cJSON_Duplicate(json->json_, true);
401 isAllowDelete = true;
402 }
403 return Replace(key, jsonObject, isAllowDelete);
404 }
405
Replace(const std::string & key,int32_t value)406 bool EffectJson::Replace(const std::string &key, int32_t value)
407 {
408 return Replace(key, static_cast<double>(value));
409 }
410
Replace(const std::string & key,uint32_t value)411 bool EffectJson::Replace(const std::string &key, uint32_t value)
412 {
413 return Replace(key, static_cast<double>(value));
414 }
415
Replace(const std::string & key,float value)416 bool EffectJson::Replace(const std::string &key, float value)
417 {
418 return Replace(key, static_cast<double>(value));
419 }
420
Replace(const std::string & key,double value)421 bool EffectJson::Replace(const std::string &key, double value)
422 {
423 cJSON *child = cJSON_CreateNumber(value);
424 return Replace(key, child);
425 }
426
Replace(const std::string & key,bool value)427 bool EffectJson::Replace(const std::string &key, bool value)
428 {
429 cJSON *child = cJSON_CreateBool(value);
430 return Replace(key, child);
431 }
432
Replace(const std::string & key,const std::string & value)433 bool EffectJson::Replace(const std::string &key, const std::string &value)
434 {
435 cJSON *child = cJSON_CreateString(value.c_str());
436 return Replace(key, child);
437 }
438
Replace(const std::string & key,const char * value)439 bool EffectJson::Replace(const std::string &key, const char *value)
440 {
441 EFFECT_JSON_FALSE_RETURN(value != nullptr);
442 cJSON *child = cJSON_CreateString(value);
443 return Replace(key, child);
444 }
445
ToString() const446 std::string EffectJson::ToString() const
447 {
448 std::string ret;
449 if (json_ == nullptr) {
450 return ret;
451 }
452 char *jsonData = cJSON_PrintUnformatted(json_);
453 if (jsonData != nullptr) {
454 ret = jsonData;
455 cJSON_free(jsonData);
456 }
457 return ret;
458 }
459
ParseJsonData(const std::string & data)460 EffectJsonPtr JsonHelper::ParseJsonData(const std::string &data)
461 {
462 cJSON *json = cJSON_Parse(data.c_str());
463 return std::make_shared<EffectJson>(json);
464 }
465
CreateObject(bool isRoot)466 EffectJsonPtr JsonHelper::CreateObject(bool isRoot)
467 {
468 cJSON *json = cJSON_CreateObject();
469 return std::make_shared<EffectJson>(json, isRoot);
470 }
471
CreateArray(bool isRoot)472 EffectJsonPtr JsonHelper::CreateArray(bool isRoot)
473 {
474 cJSON *json = cJSON_CreateArray();
475 return std::make_shared<EffectJson>(json, isRoot);
476 }
477
478 } // namespace Effect
479 } // namespace Media
480 } // namespace OHOS