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 "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,double value) const89 bool PtJson::Add(const char *key, double value) const
90 {
91 ASSERT(key != nullptr && !Contains(key));
92
93 cJSON *node = cJSON_CreateNumber(value);
94 if (node == nullptr) {
95 return false;
96 }
97
98 cJSON_bool ret = cJSON_AddItemToObject(object_, key, node);
99 if (ret == 0) {
100 cJSON_Delete(node);
101 return false;
102 }
103
104 return true;
105 }
106
Add(const char * key,const char * value) const107 bool PtJson::Add(const char *key, const char *value) const
108 {
109 ASSERT(key != nullptr && !Contains(key));
110
111 cJSON *node = cJSON_CreateString(value);
112 if (node == nullptr) {
113 return false;
114 }
115
116 cJSON_bool ret = cJSON_AddItemToObject(object_, key, node);
117 if (ret == 0) {
118 cJSON_Delete(node);
119 return false;
120 }
121
122 return true;
123 }
124
Add(const char * key,const std::unique_ptr<PtJson> & value) const125 bool PtJson::Add(const char *key, const std::unique_ptr<PtJson> &value) const
126 {
127 ASSERT(key != nullptr && !Contains(key));
128
129 cJSON *node = value->GetJson();
130 if (node == nullptr) {
131 return false;
132 }
133
134 cJSON_bool ret = cJSON_AddItemToObject(object_, key, node);
135 if (ret == 0) {
136 return false;
137 }
138
139 return true;
140 }
141
Push(bool value) const142 bool PtJson::Push(bool value) const
143 {
144 cJSON *node = cJSON_CreateBool(value);
145 if (node == nullptr) {
146 return false;
147 }
148
149 cJSON_bool ret = cJSON_AddItemToArray(object_, node);
150 if (ret == 0) {
151 cJSON_Delete(node);
152 return false;
153 }
154
155 return true;
156 }
157
Push(int32_t value) const158 bool PtJson::Push(int32_t value) const
159 {
160 return Push(static_cast<double>(value));
161 }
162
Push(int64_t value) const163 bool PtJson::Push(int64_t value) const
164 {
165 return Push(static_cast<double>(value));
166 }
167
Push(double value) const168 bool PtJson::Push(double value) const
169 {
170 cJSON *node = cJSON_CreateNumber(value);
171 if (node == nullptr) {
172 return false;
173 }
174
175 cJSON_bool ret = cJSON_AddItemToArray(object_, node);
176 if (ret == 0) {
177 cJSON_Delete(node);
178 return false;
179 }
180
181 return true;
182 }
183
Push(const char * value) const184 bool PtJson::Push(const char *value) const
185 {
186 cJSON *node = cJSON_CreateString(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 std::unique_ptr<PtJson> & value) const200 bool PtJson::Push(const std::unique_ptr<PtJson> &value) const
201 {
202 if (value == nullptr) {
203 return false;
204 }
205
206 cJSON *node = value->GetJson();
207 if (node == nullptr) {
208 return false;
209 }
210
211 cJSON_bool ret = cJSON_AddItemToArray(object_, node);
212 if (ret == 0) {
213 return false;
214 }
215
216 return true;
217 }
218
Remove(const char * key) const219 bool PtJson::Remove(const char *key) const
220 {
221 ASSERT(key != nullptr && Contains(key));
222
223 cJSON_DeleteItemFromObject(object_, key);
224 return true;
225 }
226
Contains(const char * key) const227 bool PtJson::Contains(const char *key) const
228 {
229 cJSON *node = cJSON_GetObjectItemCaseSensitive(object_, key);
230 return node != nullptr;
231 }
232
GetKey() const233 std::string PtJson::GetKey() const
234 {
235 if (object_ == nullptr || object_->string == nullptr) {
236 return "";
237 }
238
239 return std::string(object_->string);
240 }
241
GetJson() const242 cJSON *PtJson::GetJson() const
243 {
244 return object_;
245 }
246
IsBool() const247 bool PtJson::IsBool() const
248 {
249 return cJSON_IsBool(object_) != 0;
250 }
251
IsNumber() const252 bool PtJson::IsNumber() const
253 {
254 return cJSON_IsNumber(object_) != 0;
255 }
256
IsString() const257 bool PtJson::IsString() const
258 {
259 return cJSON_IsString(object_) != 0;
260 }
261
IsObject() const262 bool PtJson::IsObject() const
263 {
264 return cJSON_IsObject(object_) != 0;
265 }
266
IsArray() const267 bool PtJson::IsArray() const
268 {
269 return cJSON_IsArray(object_) != 0;
270 }
271
IsNull() const272 bool PtJson::IsNull() const
273 {
274 return cJSON_IsNull(object_) != 0;
275 }
276
GetBool(bool defaultValue) const277 bool PtJson::GetBool(bool defaultValue) const
278 {
279 if (!IsBool()) {
280 return defaultValue;
281 }
282
283 return cJSON_IsTrue(object_) != 0;
284 }
285
GetInt(int32_t defaultValue) const286 int32_t PtJson::GetInt(int32_t defaultValue) const
287 {
288 if (!IsNumber()) {
289 return defaultValue;
290 }
291
292 return static_cast<int32_t>(object_->valuedouble);
293 }
294
GetInt64(int64_t defaultValue) const295 int64_t PtJson::GetInt64(int64_t defaultValue) const
296 {
297 if (!IsNumber()) {
298 return defaultValue;
299 }
300
301 return static_cast<int64_t>(object_->valuedouble);
302 }
303
GetDouble(double defaultValue) const304 double PtJson::GetDouble(double defaultValue) const
305 {
306 if (!IsNumber()) {
307 return defaultValue;
308 }
309
310 return object_->valuedouble;
311 }
312
GetString() const313 std::string PtJson::GetString() const
314 {
315 if (!IsString()) {
316 return "";
317 }
318
319 return std::string(object_->valuestring);
320 }
321
GetSize() const322 int32_t PtJson::GetSize() const
323 {
324 return cJSON_GetArraySize(object_);
325 }
326
Get(int32_t index) const327 std::unique_ptr<PtJson> PtJson::Get(int32_t index) const
328 {
329 return std::make_unique<PtJson>(cJSON_GetArrayItem(object_, index));
330 }
331
GetBool(const char * key,bool * value) const332 Result PtJson::GetBool(const char *key, bool *value) const
333 {
334 cJSON *item = cJSON_GetObjectItem(object_, key);
335 if (item == nullptr) {
336 return Result::NOT_EXIST;
337 }
338 if (cJSON_IsBool(item) == 0) {
339 return Result::TYPE_ERROR;
340 }
341
342 *value = cJSON_IsTrue(item) != 0;
343 return Result::SUCCESS;
344 }
345
GetInt(const char * key,int32_t * value) const346 Result PtJson::GetInt(const char *key, int32_t *value) const
347 {
348 double result;
349 Result ret = GetDouble(key, &result);
350 if (ret == Result::SUCCESS) {
351 *value = static_cast<int32_t>(result);
352 }
353 return ret;
354 }
355
GetInt64(const char * key,int64_t * value) const356 Result PtJson::GetInt64(const char *key, int64_t *value) const
357 {
358 double result;
359 Result ret = GetDouble(key, &result);
360 if (ret == Result::SUCCESS) {
361 *value = static_cast<int64_t>(result);
362 }
363 return ret;
364 }
365
GetDouble(const char * key,double * value) const366 Result PtJson::GetDouble(const char *key, double *value) const
367 {
368 cJSON *item = cJSON_GetObjectItem(object_, key);
369 if (item == nullptr) {
370 return Result::NOT_EXIST;
371 }
372 if (cJSON_IsNumber(item) == 0) {
373 return Result::TYPE_ERROR;
374 }
375
376 *value = item->valuedouble;
377 return Result::SUCCESS;
378 }
379
GetString(const char * key,std::string * value) const380 Result PtJson::GetString(const char *key, std::string *value) const
381 {
382 cJSON *item = cJSON_GetObjectItem(object_, key);
383 if (item == nullptr) {
384 return Result::NOT_EXIST;
385 }
386 if (cJSON_IsString(item) == 0) {
387 return Result::TYPE_ERROR;
388 }
389
390 *value = item->valuestring;
391 return Result::SUCCESS;
392 }
393
GetObject(const char * key,std::unique_ptr<PtJson> * value) const394 Result PtJson::GetObject(const char *key, std::unique_ptr<PtJson> *value) const
395 {
396 cJSON *item = cJSON_GetObjectItem(object_, key);
397 if (item == nullptr) {
398 return Result::NOT_EXIST;
399 }
400 if (cJSON_IsObject(item) == 0) {
401 return Result::TYPE_ERROR;
402 }
403
404 *value = std::make_unique<PtJson>(item);
405 return Result::SUCCESS;
406 }
407
GetArray(const char * key,std::unique_ptr<PtJson> * value) const408 Result PtJson::GetArray(const char *key, std::unique_ptr<PtJson> *value) const
409 {
410 cJSON *item = cJSON_GetObjectItem(object_, key);
411 if (item == nullptr) {
412 return Result::NOT_EXIST;
413 }
414 if (cJSON_IsArray(item) == 0) {
415 return Result::TYPE_ERROR;
416 }
417
418 *value = std::make_unique<PtJson>(item);
419 return Result::SUCCESS;
420 }
421
GetAny(const char * key,std::unique_ptr<PtJson> * value) const422 Result PtJson::GetAny(const char *key, std::unique_ptr<PtJson> *value) const
423 {
424 cJSON *item = cJSON_GetObjectItem(object_, key);
425 if (item == nullptr) {
426 return Result::NOT_EXIST;
427 }
428
429 *value = std::make_unique<PtJson>(item);
430 return Result::SUCCESS;
431 }
432 } // namespace panda::ecmascript
433