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 "effect_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 auto element = GetElement(key);
236 if (element == nullptr || element->IsNull() || !element->IsArray()) {
237 return {};
238 }
239
240 return element->GetArray();
241 }
242
DeleteJson(cJSON * json,bool isAllowDelete=true)243 void DeleteJson(cJSON *json, bool isAllowDelete = true)
244 {
245 if (isAllowDelete && json != nullptr) {
246 cJSON_Delete(json);
247 }
248 }
249
Put(const std::string & key,Json * json,bool isAllowDelete)250 bool EffectJson::Put(const std::string &key, Json *json, bool isAllowDelete)
251 {
252 EFFECT_JSON_FALSE_RETURN(json != nullptr && json_ != nullptr);
253
254 bool res = static_cast<bool>(cJSON_AddItemToObject(json_, key.c_str(), json));
255 EFFECT_JSON_FALSE_RETURN_WITH_WORK(res, DeleteJson(json, isAllowDelete));
256 return true;
257 }
258
Put(const std::string & key,EffectJsonPtr & json)259 bool EffectJson::Put(const std::string &key, EffectJsonPtr &json)
260 {
261 EFFECT_JSON_FALSE_RETURN(json != nullptr && json->json_ != nullptr);
262
263 cJSON *jsonObject = json->json_;
264 bool isAllowDelete = false;
265 if (json->isRoot_) {
266 jsonObject = cJSON_Duplicate(json->json_, true);
267 isAllowDelete = true;
268 }
269 return Put(key, jsonObject, isAllowDelete);
270 }
271
Put(const std::string & key,int32_t value)272 bool EffectJson::Put(const std::string &key, int32_t value)
273 {
274 return Put(key, static_cast<double>(value));
275 }
276
Put(const std::string & key,uint32_t value)277 bool EffectJson::Put(const std::string &key, uint32_t value)
278 {
279 return Put(key, static_cast<double>(value));
280 }
281
Put(const std::string & key,float value)282 bool EffectJson::Put(const std::string &key, float value)
283 {
284 return Put(key, static_cast<double>(value));
285 }
286
Put(const std::string & key,double value)287 bool EffectJson::Put(const std::string &key, double value)
288 {
289 cJSON *child = cJSON_CreateNumber(value);
290 return Put(key, child);
291 }
292
Put(const std::string & key,bool value)293 bool EffectJson::Put(const std::string &key, bool value)
294 {
295 cJSON *child = cJSON_CreateBool(value);
296 return Put(key, child);
297 }
298
Put(const std::string & key,const std::string & value)299 bool EffectJson::Put(const std::string &key, const std::string &value)
300 {
301 cJSON *child = cJSON_CreateString(value.c_str());
302 return Put(key, child);
303 }
304
Put(const std::string & key,const char * value)305 bool EffectJson::Put(const std::string &key, const char *value)
306 {
307 EFFECT_JSON_FALSE_RETURN(value != nullptr);
308 cJSON *child = cJSON_CreateString(value);
309 return Put(key, child);
310 }
311
Add(Json * json,bool isAllowDelete) const312 bool EffectJson::Add(Json *json, bool isAllowDelete) const
313 {
314 EFFECT_JSON_FALSE_RETURN(json != nullptr && json_ != nullptr);
315
316 bool res = static_cast<bool>(cJSON_AddItemToArray(json_, json));
317 EFFECT_JSON_FALSE_RETURN_WITH_WORK(res, DeleteJson(json, isAllowDelete));
318 return true;
319 }
320
Add(EffectJsonPtr & json) const321 bool EffectJson::Add(EffectJsonPtr &json) const
322 {
323 EFFECT_JSON_FALSE_RETURN(json != nullptr && json->json_ != nullptr);
324
325 cJSON *jsonObject = json->json_;
326 bool isAllowDelete = false;
327 if (json->isRoot_) {
328 jsonObject = cJSON_Duplicate(json->json_, true);
329 isAllowDelete = true;
330 }
331 return Add(jsonObject, isAllowDelete);
332 }
333
Add(int32_t value) const334 bool EffectJson::Add(int32_t value) const
335 {
336 return Add(static_cast<double>(value));
337 }
338
Add(uint32_t value) const339 bool EffectJson::Add(uint32_t value) const
340 {
341 return Add(static_cast<double>(value));
342 }
343
Add(float value) const344 bool EffectJson::Add(float value) const
345 {
346 return Add(static_cast<double>(value));
347 }
348
Add(double value) const349 bool EffectJson::Add(double value) const
350 {
351 EFFECT_JSON_FALSE_RETURN(IsArray());
352
353 cJSON *child = cJSON_CreateNumber(value);
354 return Add(child);
355 }
356
Add(bool value) const357 bool EffectJson::Add(bool value) const
358 {
359 EFFECT_JSON_FALSE_RETURN(IsArray());
360
361 cJSON *child = cJSON_CreateBool(value);
362 return Add(child);
363 }
364
Add(const std::string & value) const365 bool EffectJson::Add(const std::string &value) const
366 {
367 EFFECT_JSON_FALSE_RETURN(IsArray());
368
369 cJSON *child = cJSON_CreateString(value.c_str());
370 return Add(child);
371 }
372
Add(const char * value) const373 bool EffectJson::Add(const char *value) const
374 {
375 EFFECT_JSON_FALSE_RETURN(IsArray());
376 EFFECT_JSON_FALSE_RETURN(value != nullptr);
377
378 cJSON *child = cJSON_CreateString(value);
379 return Add(child);
380 }
381
Replace(const std::string & key,Json * json,bool jsonObject)382 bool EffectJson::Replace(const std::string &key, Json *json, bool jsonObject)
383 {
384 EFFECT_JSON_FALSE_RETURN(json != nullptr && json_ != nullptr);
385
386 bool res =
387 static_cast<bool>(cJSON_ReplaceItemInObjectCaseSensitive(json_, key.c_str(), json));
388 EFFECT_JSON_FALSE_RETURN_WITH_WORK(res, DeleteJson(json, jsonObject));
389 return true;
390 }
391
Replace(const std::string & key,EffectJsonPtr & json)392 bool EffectJson::Replace(const std::string &key, EffectJsonPtr &json)
393 {
394 EFFECT_JSON_FALSE_RETURN(json != nullptr && json->json_ != nullptr);
395
396 cJSON *jsonObject = json->json_;
397 bool isAllowDelete = false;
398 if (json->isRoot_) {
399 jsonObject = cJSON_Duplicate(json->json_, true);
400 isAllowDelete = true;
401 }
402 return Replace(key, jsonObject, isAllowDelete);
403 }
404
Replace(const std::string & key,int32_t value)405 bool EffectJson::Replace(const std::string &key, int32_t value)
406 {
407 return Replace(key, static_cast<double>(value));
408 }
409
Replace(const std::string & key,uint32_t value)410 bool EffectJson::Replace(const std::string &key, uint32_t value)
411 {
412 return Replace(key, static_cast<double>(value));
413 }
414
Replace(const std::string & key,float value)415 bool EffectJson::Replace(const std::string &key, float value)
416 {
417 return Replace(key, static_cast<double>(value));
418 }
419
Replace(const std::string & key,double value)420 bool EffectJson::Replace(const std::string &key, double value)
421 {
422 cJSON *child = cJSON_CreateNumber(value);
423 return Replace(key, child);
424 }
425
Replace(const std::string & key,bool value)426 bool EffectJson::Replace(const std::string &key, bool value)
427 {
428 cJSON *child = cJSON_CreateBool(value);
429 return Replace(key, child);
430 }
431
Replace(const std::string & key,const std::string & value)432 bool EffectJson::Replace(const std::string &key, const std::string &value)
433 {
434 cJSON *child = cJSON_CreateString(value.c_str());
435 return Replace(key, child);
436 }
437
Replace(const std::string & key,const char * value)438 bool EffectJson::Replace(const std::string &key, const char *value)
439 {
440 EFFECT_JSON_FALSE_RETURN(value != nullptr);
441 cJSON *child = cJSON_CreateString(value);
442 return Replace(key, child);
443 }
444
ToString() const445 std::string EffectJson::ToString() const
446 {
447 std::string ret;
448 if (json_ == nullptr) {
449 return ret;
450 }
451 char *jsonData = cJSON_PrintUnformatted(json_);
452 if (jsonData != nullptr) {
453 ret = jsonData;
454 cJSON_free(jsonData);
455 }
456 return ret;
457 }
458
ParseJsonData(const std::string & data)459 EffectJsonPtr EffectJsonHelper::ParseJsonData(const std::string &data)
460 {
461 cJSON *json = cJSON_Parse(data.c_str());
462 return std::make_shared<EffectJson>(json);
463 }
464
CreateObject(bool isRoot)465 EffectJsonPtr EffectJsonHelper::CreateObject(bool isRoot)
466 {
467 cJSON *json = cJSON_CreateObject();
468 return std::make_shared<EffectJson>(json, isRoot);
469 }
470
CreateArray(bool isRoot)471 EffectJsonPtr EffectJsonHelper::CreateArray(bool isRoot)
472 {
473 cJSON *json = cJSON_CreateArray();
474 return std::make_shared<EffectJson>(json, isRoot);
475 }
476
477 } // namespace Effect
478 } // namespace Media
479 } // namespace OHOS