1 /*
2 * Copyright (c) 2022 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 "tooling/base/pt_json.h"
17
18 #include "libpandabase/macros.h"
19
20 namespace panda::ecmascript::tooling {
CreateObject()21 std::unique_ptr<PtJson> PtJson::CreateObject()
22 {
23 return std::make_unique<PtJson>(cJSON_CreateObject());
24 }
25
CreateArray()26 std::unique_ptr<PtJson> PtJson::CreateArray()
27 {
28 return std::make_unique<PtJson>(cJSON_CreateArray());
29 }
30
ReleaseRoot()31 void PtJson::ReleaseRoot()
32 {
33 if (object_ != nullptr) {
34 cJSON_Delete(object_);
35 object_ = nullptr;
36 }
37 }
38
Parse(const std::string & data)39 std::unique_ptr<PtJson> PtJson::Parse(const std::string &data)
40 {
41 cJSON *value = cJSON_ParseWithOpts(data.c_str(), nullptr, true);
42 return std::make_unique<PtJson>(value);
43 }
44
Stringify() const45 std::string PtJson::Stringify() const
46 {
47 if (object_ == nullptr) {
48 return "";
49 }
50
51 char *str = cJSON_PrintUnformatted(object_);
52 if (str == nullptr) {
53 return "";
54 }
55
56 std::string result(str);
57 cJSON_free(str);
58 return result;
59 }
60
Add(const char * key,bool value) const61 bool PtJson::Add(const char *key, bool value) const
62 {
63 ASSERT(key != nullptr && !Contains(key));
64
65 cJSON *node = cJSON_CreateBool(value);
66 if (node == nullptr) {
67 return false;
68 }
69
70 cJSON_bool ret = cJSON_AddItemToObject(object_, key, node);
71 if (ret == 0) {
72 cJSON_Delete(node);
73 return false;
74 }
75
76 return true;
77 }
78
Add(const char * key,int32_t value) const79 bool PtJson::Add(const char *key, int32_t value) const
80 {
81 return Add(key, static_cast<double>(value));
82 }
83
Add(const char * key,int64_t value) const84 bool PtJson::Add(const char *key, int64_t value) const
85 {
86 return Add(key, static_cast<double>(value));
87 }
88
Add(const char * key,uint32_t value) const89 bool PtJson::Add(const char *key, uint32_t value) const
90 {
91 return Add(key, static_cast<double>(value));
92 }
93
Add(const char * key,double value) const94 bool PtJson::Add(const char *key, double value) const
95 {
96 ASSERT(key != nullptr && !Contains(key));
97
98 cJSON *node = cJSON_CreateNumber(value);
99 if (node == nullptr) {
100 return false;
101 }
102
103 cJSON_bool ret = cJSON_AddItemToObject(object_, key, node);
104 if (ret == 0) {
105 cJSON_Delete(node);
106 return false;
107 }
108
109 return true;
110 }
111
Add(const char * key,const char * value) const112 bool PtJson::Add(const char *key, const char *value) const
113 {
114 ASSERT(key != nullptr && !Contains(key));
115
116 cJSON *node = cJSON_CreateString(value);
117 if (node == nullptr) {
118 return false;
119 }
120
121 cJSON_bool ret = cJSON_AddItemToObject(object_, key, node);
122 if (ret == 0) {
123 cJSON_Delete(node);
124 return false;
125 }
126
127 return true;
128 }
129
Add(const char * key,const std::unique_ptr<PtJson> & value) const130 bool PtJson::Add(const char *key, const std::unique_ptr<PtJson> &value) const
131 {
132 ASSERT(key != nullptr && !Contains(key));
133
134 cJSON *node = value->GetJson();
135 if (node == nullptr) {
136 return false;
137 }
138
139 cJSON_bool ret = cJSON_AddItemToObject(object_, key, node);
140 if (ret == 0) {
141 return false;
142 }
143
144 return true;
145 }
146
Push(bool value) const147 bool PtJson::Push(bool value) const
148 {
149 cJSON *node = cJSON_CreateBool(value);
150 if (node == nullptr) {
151 return false;
152 }
153
154 cJSON_bool ret = cJSON_AddItemToArray(object_, node);
155 if (ret == 0) {
156 cJSON_Delete(node);
157 return false;
158 }
159
160 return true;
161 }
162
Push(int32_t value) const163 bool PtJson::Push(int32_t value) const
164 {
165 return Push(static_cast<double>(value));
166 }
167
Push(int64_t value) const168 bool PtJson::Push(int64_t value) const
169 {
170 return Push(static_cast<double>(value));
171 }
172
Push(uint32_t value) const173 bool PtJson::Push(uint32_t value) const
174 {
175 return Push(static_cast<double>(value));
176 }
177
Push(double value) const178 bool PtJson::Push(double value) const
179 {
180 cJSON *node = cJSON_CreateNumber(value);
181 if (node == nullptr) {
182 return false;
183 }
184
185 cJSON_bool ret = cJSON_AddItemToArray(object_, node);
186 if (ret == 0) {
187 cJSON_Delete(node);
188 return false;
189 }
190
191 return true;
192 }
193
Push(const char * value) const194 bool PtJson::Push(const char *value) const
195 {
196 cJSON *node = cJSON_CreateString(value);
197 if (node == nullptr) {
198 return false;
199 }
200
201 cJSON_bool ret = cJSON_AddItemToArray(object_, node);
202 if (ret == 0) {
203 cJSON_Delete(node);
204 return false;
205 }
206
207 return true;
208 }
209
Push(const std::unique_ptr<PtJson> & value) const210 bool PtJson::Push(const std::unique_ptr<PtJson> &value) const
211 {
212 if (value == nullptr) {
213 return false;
214 }
215
216 cJSON *node = value->GetJson();
217 if (node == nullptr) {
218 return false;
219 }
220
221 cJSON_bool ret = cJSON_AddItemToArray(object_, node);
222 if (ret == 0) {
223 return false;
224 }
225
226 return true;
227 }
228
Remove(const char * key) const229 bool PtJson::Remove(const char *key) const
230 {
231 ASSERT(key != nullptr && Contains(key));
232
233 cJSON_DeleteItemFromObject(object_, key);
234 return true;
235 }
236
Contains(const char * key) const237 bool PtJson::Contains(const char *key) const
238 {
239 cJSON *node = cJSON_GetObjectItemCaseSensitive(object_, key);
240 return node != nullptr;
241 }
242
GetKey() const243 std::string PtJson::GetKey() const
244 {
245 if (object_ == nullptr || object_->string == nullptr) {
246 return "";
247 }
248
249 return std::string(object_->string);
250 }
251
GetKeysArray() const252 std::vector<std::string> PtJson::GetKeysArray() const
253 {
254 std::vector<std::string> result;
255 if (object_ == nullptr) {
256 return result;
257 }
258 cJSON *node = object_->child;
259 while (node != nullptr) {
260 if (node->string != nullptr) {
261 result.emplace_back(std::string(node->string));
262 }
263 node = node->next;
264 }
265 return result;
266 }
267
GetJson() const268 cJSON *PtJson::GetJson() const
269 {
270 return object_;
271 }
272
IsBool() const273 bool PtJson::IsBool() const
274 {
275 return cJSON_IsBool(object_) != 0;
276 }
277
IsNumber() const278 bool PtJson::IsNumber() const
279 {
280 return cJSON_IsNumber(object_) != 0;
281 }
282
IsString() const283 bool PtJson::IsString() const
284 {
285 return cJSON_IsString(object_) != 0;
286 }
287
IsObject() const288 bool PtJson::IsObject() const
289 {
290 return cJSON_IsObject(object_) != 0;
291 }
292
IsArray() const293 bool PtJson::IsArray() const
294 {
295 return cJSON_IsArray(object_) != 0;
296 }
297
IsNull() const298 bool PtJson::IsNull() const
299 {
300 return cJSON_IsNull(object_) != 0;
301 }
302
GetBool(bool defaultValue) const303 bool PtJson::GetBool(bool defaultValue) const
304 {
305 if (!IsBool()) {
306 return defaultValue;
307 }
308
309 return cJSON_IsTrue(object_) != 0;
310 }
311
GetInt(int32_t defaultValue) const312 int32_t PtJson::GetInt(int32_t defaultValue) const
313 {
314 if (!IsNumber()) {
315 return defaultValue;
316 }
317
318 return static_cast<int32_t>(object_->valuedouble);
319 }
320
GetInt64(int64_t defaultValue) const321 int64_t PtJson::GetInt64(int64_t defaultValue) const
322 {
323 if (!IsNumber()) {
324 return defaultValue;
325 }
326
327 return static_cast<int64_t>(object_->valuedouble);
328 }
329
GetUInt(uint32_t defaultValue) const330 uint32_t PtJson::GetUInt(uint32_t defaultValue) const
331 {
332 if (!IsNumber()) {
333 return defaultValue;
334 }
335
336 return static_cast<uint32_t>(object_->valuedouble);
337 }
338
GetUInt64(uint64_t defaultValue) const339 uint64_t PtJson::GetUInt64(uint64_t defaultValue) const
340 {
341 if (!IsNumber()) {
342 return defaultValue;
343 }
344
345 return static_cast<uint64_t>(object_->valuedouble);
346 }
347
GetDouble(double defaultValue) const348 double PtJson::GetDouble(double defaultValue) const
349 {
350 if (!IsNumber()) {
351 return defaultValue;
352 }
353
354 return object_->valuedouble;
355 }
356
GetString() const357 std::string PtJson::GetString() const
358 {
359 if (!IsString()) {
360 return "";
361 }
362
363 return std::string(object_->valuestring);
364 }
365
GetSize() const366 int32_t PtJson::GetSize() const
367 {
368 return cJSON_GetArraySize(object_);
369 }
370
Get(int32_t index) const371 std::unique_ptr<PtJson> PtJson::Get(int32_t index) const
372 {
373 return std::make_unique<PtJson>(cJSON_GetArrayItem(object_, index));
374 }
375
GetBool(const char * key,bool * value) const376 Result PtJson::GetBool(const char *key, bool *value) const
377 {
378 cJSON *item = cJSON_GetObjectItem(object_, key);
379 if (item == nullptr) {
380 return Result::NOT_EXIST;
381 }
382 if (cJSON_IsBool(item) == 0) {
383 return Result::TYPE_ERROR;
384 }
385
386 *value = cJSON_IsTrue(item) != 0;
387 return Result::SUCCESS;
388 }
389
GetInt(const char * key,int32_t * value) const390 Result PtJson::GetInt(const char *key, int32_t *value) const
391 {
392 double result;
393 Result ret = GetDouble(key, &result);
394 if (ret == Result::SUCCESS) {
395 *value = static_cast<int32_t>(result);
396 }
397 return ret;
398 }
399
GetInt64(const char * key,int64_t * value) const400 Result PtJson::GetInt64(const char *key, int64_t *value) const
401 {
402 double result;
403 Result ret = GetDouble(key, &result);
404 if (ret == Result::SUCCESS) {
405 *value = static_cast<int64_t>(result);
406 }
407 return ret;
408 }
409
GetUInt(const char * key,uint32_t * value) const410 Result PtJson::GetUInt(const char *key, uint32_t *value) const
411 {
412 double result;
413 Result ret = GetDouble(key, &result);
414 if (ret == Result::SUCCESS) {
415 *value = static_cast<uint32_t>(result);
416 }
417 return ret;
418 }
419
GetUInt64(const char * key,uint64_t * value) const420 Result PtJson::GetUInt64(const char *key, uint64_t *value) const
421 {
422 double result;
423 Result ret = GetDouble(key, &result);
424 if (ret == Result::SUCCESS) {
425 *value = static_cast<uint64_t>(result);
426 }
427 return ret;
428 }
429
GetDouble(const char * key,double * value) const430 Result PtJson::GetDouble(const char *key, double *value) const
431 {
432 cJSON *item = cJSON_GetObjectItem(object_, key);
433 if (item == nullptr) {
434 return Result::NOT_EXIST;
435 }
436 if (cJSON_IsNumber(item) == 0) {
437 return Result::TYPE_ERROR;
438 }
439
440 *value = item->valuedouble;
441 return Result::SUCCESS;
442 }
443
GetString(const char * key,std::string * value) const444 Result PtJson::GetString(const char *key, std::string *value) const
445 {
446 cJSON *item = cJSON_GetObjectItem(object_, key);
447 if (item == nullptr) {
448 return Result::NOT_EXIST;
449 }
450 if (cJSON_IsString(item) == 0) {
451 return Result::TYPE_ERROR;
452 }
453
454 *value = item->valuestring;
455 return Result::SUCCESS;
456 }
457
GetObject(const char * key,std::unique_ptr<PtJson> * value) const458 Result PtJson::GetObject(const char *key, std::unique_ptr<PtJson> *value) const
459 {
460 cJSON *item = cJSON_GetObjectItem(object_, key);
461 if (item == nullptr) {
462 return Result::NOT_EXIST;
463 }
464 if (cJSON_IsObject(item) == 0) {
465 return Result::TYPE_ERROR;
466 }
467
468 *value = std::make_unique<PtJson>(item);
469 return Result::SUCCESS;
470 }
471
GetArray(const char * key,std::unique_ptr<PtJson> * value) const472 Result PtJson::GetArray(const char *key, std::unique_ptr<PtJson> *value) const
473 {
474 cJSON *item = cJSON_GetObjectItem(object_, key);
475 if (item == nullptr) {
476 return Result::NOT_EXIST;
477 }
478 if (cJSON_IsArray(item) == 0) {
479 return Result::TYPE_ERROR;
480 }
481
482 *value = std::make_unique<PtJson>(item);
483 return Result::SUCCESS;
484 }
485
GetAny(const char * key,std::unique_ptr<PtJson> * value) const486 Result PtJson::GetAny(const char *key, std::unique_ptr<PtJson> *value) const
487 {
488 cJSON *item = cJSON_GetObjectItem(object_, key);
489 if (item == nullptr) {
490 return Result::NOT_EXIST;
491 }
492
493 *value = std::make_unique<PtJson>(item);
494 return Result::SUCCESS;
495 }
496 } // namespace panda::ecmascript
497