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 namespace panda::ecmascript::tooling {
CreateObject()19 std::unique_ptr<PtJson> PtJson::CreateObject()
20 {
21 return std::make_unique<PtJson>(cJSON_CreateObject());
22 }
23
CreateArray()24 std::unique_ptr<PtJson> PtJson::CreateArray()
25 {
26 return std::make_unique<PtJson>(cJSON_CreateArray());
27 }
28
ReleaseRoot()29 void PtJson::ReleaseRoot()
30 {
31 if (object_ != nullptr) {
32 cJSON_Delete(object_);
33 object_ = nullptr;
34 }
35 }
36
Parse(const std::string & data)37 std::unique_ptr<PtJson> PtJson::Parse(const std::string &data)
38 {
39 cJSON *value = cJSON_ParseWithOpts(data.c_str(), nullptr, true);
40 return std::make_unique<PtJson>(value);
41 }
42
Stringify() const43 std::string PtJson::Stringify() const
44 {
45 if (object_ == nullptr) {
46 return "";
47 }
48
49 char *str = cJSON_PrintUnformatted(object_);
50 if (str == nullptr) {
51 return "";
52 }
53
54 std::string result(str);
55 cJSON_free(str);
56 return result;
57 }
58
Add(const char * key,bool value) const59 bool PtJson::Add(const char *key, bool value) const
60 {
61 if (key == nullptr || Contains(key)) {
62 return false;
63 }
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 if (key == nullptr || Contains(key)) {
97 return false;
98 }
99
100 cJSON *node = cJSON_CreateNumber(value);
101 if (node == nullptr) {
102 return false;
103 }
104
105 cJSON_bool ret = cJSON_AddItemToObject(object_, key, node);
106 if (ret == 0) {
107 cJSON_Delete(node);
108 return false;
109 }
110
111 return true;
112 }
113
Add(const char * key,const char * value) const114 bool PtJson::Add(const char *key, const char *value) const
115 {
116 if (key == nullptr || Contains(key)) {
117 return false;
118 }
119
120 cJSON *node = cJSON_CreateString(value);
121 if (node == nullptr) {
122 return false;
123 }
124
125 cJSON_bool ret = cJSON_AddItemToObject(object_, key, node);
126 if (ret == 0) {
127 cJSON_Delete(node);
128 return false;
129 }
130
131 return true;
132 }
133
Add(const char * key,const std::unique_ptr<PtJson> & value) const134 bool PtJson::Add(const char *key, const std::unique_ptr<PtJson> &value) const
135 {
136 if (key == nullptr || Contains(key)) {
137 return false;
138 }
139
140 cJSON *node = value->GetJson();
141 if (node == nullptr) {
142 return false;
143 }
144
145 cJSON_bool ret = cJSON_AddItemToObject(object_, key, node);
146 if (ret == 0) {
147 return false;
148 }
149
150 return true;
151 }
152
Push(bool value) const153 bool PtJson::Push(bool value) const
154 {
155 cJSON *node = cJSON_CreateBool(value);
156 if (node == nullptr) {
157 return false;
158 }
159
160 cJSON_bool ret = cJSON_AddItemToArray(object_, node);
161 if (ret == 0) {
162 cJSON_Delete(node);
163 return false;
164 }
165
166 return true;
167 }
168
Push(int32_t value) const169 bool PtJson::Push(int32_t value) const
170 {
171 return Push(static_cast<double>(value));
172 }
173
Push(int64_t value) const174 bool PtJson::Push(int64_t value) const
175 {
176 return Push(static_cast<double>(value));
177 }
178
Push(uint32_t value) const179 bool PtJson::Push(uint32_t value) const
180 {
181 return Push(static_cast<double>(value));
182 }
183
Push(double value) const184 bool PtJson::Push(double value) const
185 {
186 cJSON *node = cJSON_CreateNumber(value);
187 if (node == nullptr) {
188 return false;
189 }
190
191 cJSON_bool ret = cJSON_AddItemToArray(object_, node);
192 if (ret == 0) {
193 cJSON_Delete(node);
194 return false;
195 }
196
197 return true;
198 }
199
Push(const char * value) const200 bool PtJson::Push(const char *value) const
201 {
202 cJSON *node = cJSON_CreateString(value);
203 if (node == nullptr) {
204 return false;
205 }
206
207 cJSON_bool ret = cJSON_AddItemToArray(object_, node);
208 if (ret == 0) {
209 cJSON_Delete(node);
210 return false;
211 }
212
213 return true;
214 }
215
Push(const std::unique_ptr<PtJson> & value) const216 bool PtJson::Push(const std::unique_ptr<PtJson> &value) const
217 {
218 if (value == nullptr) {
219 return false;
220 }
221
222 cJSON *node = value->GetJson();
223 if (node == nullptr) {
224 return false;
225 }
226
227 cJSON_bool ret = cJSON_AddItemToArray(object_, node);
228 if (ret == 0) {
229 return false;
230 }
231
232 return true;
233 }
234
Remove(const char * key) const235 bool PtJson::Remove(const char *key) const
236 {
237 if (key == nullptr || !Contains(key)) {
238 return false;
239 }
240
241 cJSON_DeleteItemFromObject(object_, key);
242 return true;
243 }
244
Contains(const char * key) const245 bool PtJson::Contains(const char *key) const
246 {
247 cJSON *node = cJSON_GetObjectItemCaseSensitive(object_, key);
248 return node != nullptr;
249 }
250
GetKey() const251 std::string PtJson::GetKey() const
252 {
253 if (object_ == nullptr || object_->string == nullptr) {
254 return "";
255 }
256
257 return std::string(object_->string);
258 }
259
GetKeysArray() const260 std::vector<std::string> PtJson::GetKeysArray() const
261 {
262 std::vector<std::string> result;
263 if (object_ == nullptr) {
264 return result;
265 }
266 cJSON *node = object_->child;
267 while (node != nullptr) {
268 if (node->string != nullptr) {
269 result.emplace_back(std::string(node->string));
270 }
271 node = node->next;
272 }
273 return result;
274 }
275
GetJson() const276 cJSON *PtJson::GetJson() const
277 {
278 return object_;
279 }
280
IsBool() const281 bool PtJson::IsBool() const
282 {
283 return cJSON_IsBool(object_) != 0;
284 }
285
IsNumber() const286 bool PtJson::IsNumber() const
287 {
288 return cJSON_IsNumber(object_) != 0;
289 }
290
IsString() const291 bool PtJson::IsString() const
292 {
293 return cJSON_IsString(object_) != 0;
294 }
295
IsObject() const296 bool PtJson::IsObject() const
297 {
298 return cJSON_IsObject(object_) != 0;
299 }
300
IsArray() const301 bool PtJson::IsArray() const
302 {
303 return cJSON_IsArray(object_) != 0;
304 }
305
IsNull() const306 bool PtJson::IsNull() const
307 {
308 return cJSON_IsNull(object_) != 0;
309 }
310
GetBool(bool defaultValue) const311 bool PtJson::GetBool(bool defaultValue) const
312 {
313 if (!IsBool()) {
314 return defaultValue;
315 }
316
317 return cJSON_IsTrue(object_) != 0;
318 }
319
GetInt(int32_t defaultValue) const320 int32_t PtJson::GetInt(int32_t defaultValue) const
321 {
322 if (!IsNumber()) {
323 return defaultValue;
324 }
325
326 return static_cast<int32_t>(object_->valuedouble);
327 }
328
GetInt64(int64_t defaultValue) const329 int64_t PtJson::GetInt64(int64_t defaultValue) const
330 {
331 if (!IsNumber()) {
332 return defaultValue;
333 }
334
335 return static_cast<int64_t>(object_->valuedouble);
336 }
337
GetUInt(uint32_t defaultValue) const338 uint32_t PtJson::GetUInt(uint32_t defaultValue) const
339 {
340 if (!IsNumber()) {
341 return defaultValue;
342 }
343
344 return static_cast<uint32_t>(object_->valuedouble);
345 }
346
GetUInt64(uint64_t defaultValue) const347 uint64_t PtJson::GetUInt64(uint64_t defaultValue) const
348 {
349 if (!IsNumber()) {
350 return defaultValue;
351 }
352
353 return static_cast<uint64_t>(object_->valuedouble);
354 }
355
GetDouble(double defaultValue) const356 double PtJson::GetDouble(double defaultValue) const
357 {
358 if (!IsNumber()) {
359 return defaultValue;
360 }
361
362 return object_->valuedouble;
363 }
364
GetString() const365 std::string PtJson::GetString() const
366 {
367 if (!IsString()) {
368 return "";
369 }
370
371 return std::string(object_->valuestring);
372 }
373
GetSize() const374 int32_t PtJson::GetSize() const
375 {
376 return cJSON_GetArraySize(object_);
377 }
378
Get(int32_t index) const379 std::unique_ptr<PtJson> PtJson::Get(int32_t index) const
380 {
381 return std::make_unique<PtJson>(cJSON_GetArrayItem(object_, index));
382 }
383
GetBool(const char * key,bool * value) const384 Result PtJson::GetBool(const char *key, bool *value) const
385 {
386 cJSON *item = cJSON_GetObjectItem(object_, key);
387 if (item == nullptr) {
388 return Result::NOT_EXIST;
389 }
390 if (cJSON_IsBool(item) == 0) {
391 return Result::TYPE_ERROR;
392 }
393
394 *value = cJSON_IsTrue(item) != 0;
395 return Result::SUCCESS;
396 }
397
GetInt(const char * key,int32_t * value) const398 Result PtJson::GetInt(const char *key, int32_t *value) const
399 {
400 double result;
401 Result ret = GetDouble(key, &result);
402 if (ret == Result::SUCCESS) {
403 *value = static_cast<int32_t>(result);
404 }
405 return ret;
406 }
407
GetInt64(const char * key,int64_t * value) const408 Result PtJson::GetInt64(const char *key, int64_t *value) const
409 {
410 double result;
411 Result ret = GetDouble(key, &result);
412 if (ret == Result::SUCCESS) {
413 *value = static_cast<int64_t>(result);
414 }
415 return ret;
416 }
417
GetUInt(const char * key,uint32_t * value) const418 Result PtJson::GetUInt(const char *key, uint32_t *value) const
419 {
420 double result;
421 Result ret = GetDouble(key, &result);
422 if (ret == Result::SUCCESS) {
423 *value = static_cast<uint32_t>(result);
424 }
425 return ret;
426 }
427
GetUInt64(const char * key,uint64_t * value) const428 Result PtJson::GetUInt64(const char *key, uint64_t *value) const
429 {
430 double result;
431 Result ret = GetDouble(key, &result);
432 if (ret == Result::SUCCESS) {
433 *value = static_cast<uint64_t>(result);
434 }
435 return ret;
436 }
437
GetDouble(const char * key,double * value) const438 Result PtJson::GetDouble(const char *key, double *value) const
439 {
440 cJSON *item = cJSON_GetObjectItem(object_, key);
441 if (item == nullptr) {
442 return Result::NOT_EXIST;
443 }
444 if (cJSON_IsNumber(item) == 0) {
445 return Result::TYPE_ERROR;
446 }
447
448 *value = item->valuedouble;
449 return Result::SUCCESS;
450 }
451
GetString(const char * key,std::string * value) const452 Result PtJson::GetString(const char *key, std::string *value) const
453 {
454 cJSON *item = cJSON_GetObjectItem(object_, key);
455 if (item == nullptr) {
456 return Result::NOT_EXIST;
457 }
458 if (cJSON_IsString(item) == 0) {
459 return Result::TYPE_ERROR;
460 }
461
462 *value = item->valuestring;
463 return Result::SUCCESS;
464 }
465
GetObject(const char * key,std::unique_ptr<PtJson> * value) const466 Result PtJson::GetObject(const char *key, std::unique_ptr<PtJson> *value) const
467 {
468 cJSON *item = cJSON_GetObjectItem(object_, key);
469 if (item == nullptr) {
470 return Result::NOT_EXIST;
471 }
472 if (cJSON_IsObject(item) == 0) {
473 return Result::TYPE_ERROR;
474 }
475
476 *value = std::make_unique<PtJson>(item);
477 return Result::SUCCESS;
478 }
479
GetArray(const char * key,std::unique_ptr<PtJson> * value) const480 Result PtJson::GetArray(const char *key, std::unique_ptr<PtJson> *value) const
481 {
482 cJSON *item = cJSON_GetObjectItem(object_, key);
483 if (item == nullptr) {
484 return Result::NOT_EXIST;
485 }
486 if (cJSON_IsArray(item) == 0) {
487 return Result::TYPE_ERROR;
488 }
489
490 *value = std::make_unique<PtJson>(item);
491 return Result::SUCCESS;
492 }
493
GetAny(const char * key,std::unique_ptr<PtJson> * value) const494 Result PtJson::GetAny(const char *key, std::unique_ptr<PtJson> *value) const
495 {
496 cJSON *item = cJSON_GetObjectItem(object_, key);
497 if (item == nullptr) {
498 return Result::NOT_EXIST;
499 }
500
501 *value = std::make_unique<PtJson>(item);
502 return Result::SUCCESS;
503 }
504 } // namespace panda::ecmascript
505