• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 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 "softbus_adapter_json.h"
17 
18 #include "nlohmann/json.hpp"
19 #include "securec.h"
20 #include "softbus_adapter_log.h"
21 #include "softbus_adapter_mem.h"
22 
23 #define JSON_LOGE(fmt, ...) HILOG_ERROR(SOFTBUS_HILOG_ID, "[%{public}s()] " fmt, __FUNCTION__, ##__VA_ARGS__)
24 
JSON_CreateObject(void)25 JsonObj *JSON_CreateObject(void)
26 {
27     JsonObj *obj = new (std::nothrow) JsonObj();
28     if (obj == nullptr) {
29         JSON_LOGE("new JsonObj fail");
30         return nullptr;
31     }
32     nlohmann::json *json = new (std::nothrow) nlohmann::json();
33     if (json == nullptr) {
34         JSON_LOGE("new nlohmann fail");
35         delete obj;
36         obj = nullptr;
37         return nullptr;
38     }
39     obj->context = reinterpret_cast<void *>(json);
40     return obj;
41 }
42 
JSON_Delete(JsonObj * obj)43 void JSON_Delete(JsonObj *obj)
44 {
45     if (obj == nullptr) {
46         return;
47     }
48     if (obj->context != nullptr) {
49         nlohmann::json *json = reinterpret_cast<nlohmann::json *>(obj->context);
50         if (json != nullptr) {
51             delete json;
52         }
53         obj->context = nullptr;
54     }
55     delete obj;
56     obj = nullptr;
57 }
58 
JSON_Free(void * obj)59 void JSON_Free(void *obj)
60 {
61     if (obj != nullptr) {
62         SoftBusFree(obj);
63     }
64 }
65 
JSON_PrintUnformatted(const JsonObj * obj)66 char *JSON_PrintUnformatted(const JsonObj *obj)
67 {
68     if (obj == nullptr) {
69         JSON_LOGE("invalid param");
70         return nullptr;
71     }
72     nlohmann::json *json = reinterpret_cast<nlohmann::json *>(obj->context);
73     if (json == nullptr) {
74         return nullptr;
75     }
76     std::string jsonString = json->dump();
77 
78     char *result = (char *)SoftBusCalloc(jsonString.length() + 1); /* 1 for '\0' */
79     if (result == nullptr) {
80         JSON_LOGE("malloc array fail");
81         return nullptr;
82     }
83     if (strcpy_s(result, jsonString.length() + 1, jsonString.c_str()) != EOK) {
84         SoftBusFree(result);
85         return nullptr;
86     }
87     return result;
88 }
89 
JSON_Parse(const char * str,uint32_t len)90 JsonObj *JSON_Parse(const char *str, uint32_t len)
91 {
92     JsonObj *obj = JSON_CreateObject();
93     if (obj == nullptr) {
94         JSON_LOGE("create json object fail");
95         return nullptr;
96     }
97     nlohmann::json *json = reinterpret_cast<nlohmann::json *>(obj->context);
98     if (json == nullptr) {
99         JSON_Delete(obj);
100         JSON_LOGE("cast json fail");
101         return nullptr;
102     }
103     std::string jsonString(str, len);
104     nlohmann::json entity = nlohmann::json::parse(jsonString, nullptr, false);
105     if (entity.is_discarded()) {
106         JSON_Delete(obj);
107         JSON_LOGE("parse json fail");
108         return nullptr;
109     }
110     for (auto &item : entity.items()) {
111         (*json)[item.key()] = item.value();
112     }
113     return obj;
114 }
115 
JSON_AddBoolToObject(JsonObj * obj,const char * key,bool value)116 bool JSON_AddBoolToObject(JsonObj *obj, const char *key, bool value)
117 {
118     if (obj == nullptr || key == nullptr) {
119         JSON_LOGE("invalid param");
120         return false;
121     }
122     nlohmann::json *json = reinterpret_cast<nlohmann::json *>(obj->context);
123     if (json == nullptr) {
124         return false;
125     }
126     (*json)[key] = value;
127     return true;
128 }
129 
JSON_GetBoolFromOject(const JsonObj * obj,const char * key,bool * value)130 bool JSON_GetBoolFromOject(const JsonObj *obj, const char *key, bool *value)
131 {
132     if (obj == nullptr || key == nullptr || value == nullptr) {
133         JSON_LOGE("invalid param");
134         return false;
135     }
136     nlohmann::json *json = reinterpret_cast<nlohmann::json *>(obj->context);
137     if (json == nullptr) {
138         return false;
139     }
140     nlohmann::json item = (*json)[key];
141     if (!item.is_boolean()) {
142         JSON_LOGE("Cannot find or invalid [%{public}s]", key);
143         return false;
144     }
145     *value = item.get<bool>();
146     return true;
147 }
148 
149 template<typename Integer>
JSON_AddIntegerToObject(JsonObj * obj,const char * key,Integer num)150 static bool JSON_AddIntegerToObject(JsonObj *obj, const char *key, Integer num)
151 {
152     if (obj == nullptr || key == nullptr) {
153         JSON_LOGE("invalid param");
154         return false;
155     }
156     nlohmann::json *json = reinterpret_cast<nlohmann::json *>(obj->context);
157     if (json == nullptr) {
158         return false;
159     }
160     (*json)[key] = num;
161     return true;
162 }
163 
164 template<typename Integer>
JSON_GetIntegerFromObject(const JsonObj * obj,const char * key,Integer & value)165 static bool JSON_GetIntegerFromObject(const JsonObj *obj, const char *key, Integer &value)
166 {
167     if (obj == nullptr || key == nullptr) {
168         JSON_LOGE("invalid param");
169         return false;
170     }
171     nlohmann::json *json = reinterpret_cast<nlohmann::json *>(obj->context);
172     if (json == nullptr) {
173         return false;
174     }
175     nlohmann::json item = (*json)[key];
176     if (!item.is_number()) {
177         JSON_LOGE("Cannot find or invalid [%{public}s]", key);
178         return false;
179     }
180     value = item.get<Integer>();
181     return true;
182 }
183 
JSON_AddInt16ToObject(JsonObj * obj,const char * key,int16_t value)184 bool JSON_AddInt16ToObject(JsonObj *obj, const char *key, int16_t value)
185 {
186     return JSON_AddIntegerToObject(obj, key, value);
187 }
188 
JSON_GetInt16FromOject(const JsonObj * obj,const char * key,int16_t * value)189 bool JSON_GetInt16FromOject(const JsonObj *obj, const char *key, int16_t *value)
190 {
191     if (value == nullptr) {
192         JSON_LOGE("invalid param");
193         return false;
194     }
195     return JSON_GetIntegerFromObject(obj, key, *value);
196 }
197 
JSON_AddInt32ToObject(JsonObj * obj,const char * key,int32_t value)198 bool JSON_AddInt32ToObject(JsonObj *obj, const char *key, int32_t value)
199 {
200     return JSON_AddIntegerToObject(obj, key, value);
201 }
202 
JSON_GetInt32FromOject(const JsonObj * obj,const char * key,int32_t * value)203 bool JSON_GetInt32FromOject(const JsonObj *obj, const char *key, int32_t *value)
204 {
205     if (value == nullptr) {
206         JSON_LOGE("invalid param");
207         return false;
208     }
209     return JSON_GetIntegerFromObject(obj, key, *value);
210 }
211 
JSON_AddInt64ToObject(JsonObj * obj,const char * key,int64_t value)212 bool JSON_AddInt64ToObject(JsonObj *obj, const char *key, int64_t value)
213 {
214     return JSON_AddIntegerToObject(obj, key, value);
215 }
216 
JSON_GetInt64FromOject(const JsonObj * obj,const char * key,int64_t * value)217 bool JSON_GetInt64FromOject(const JsonObj *obj, const char *key, int64_t *value)
218 {
219     if (value == nullptr) {
220         JSON_LOGE("invalid param");
221         return false;
222     }
223     return JSON_GetIntegerFromObject(obj, key, *value);
224 }
225 
JSON_AddStringToObject(JsonObj * obj,const char * key,const char * value)226 bool JSON_AddStringToObject(JsonObj *obj, const char *key, const char *value)
227 {
228     if (obj == nullptr || key == nullptr || value == nullptr) {
229         JSON_LOGE("invalid param");
230         return false;
231     }
232     nlohmann::json *json = reinterpret_cast<nlohmann::json *>(obj->context);
233     if (json == nullptr) {
234         return false;
235     }
236     (*json)[key] = std::string(value);
237     return true;
238 }
239 
JSON_GetStringFromOject(const JsonObj * obj,const char * key,char * value,uint32_t size)240 bool JSON_GetStringFromOject(const JsonObj *obj, const char *key, char *value, uint32_t size)
241 {
242     if (obj == nullptr || key == nullptr || value == nullptr) {
243         JSON_LOGE("invalid param");
244         return false;
245     }
246     nlohmann::json *json = reinterpret_cast<nlohmann::json *>(obj->context);
247     if (json == nullptr) {
248         return false;
249     }
250     nlohmann::json item = (*json)[key];
251     if (!item.is_string()) {
252         JSON_LOGE("cannot find or invalid [%{public}s]", key);
253         return false;
254     }
255     std::string valueString = item.get<std::string>();
256     if (strcpy_s(value, size, valueString.c_str()) != EOK) {
257         JSON_LOGE("strcpy [%{public}s] value err, size=%{public}u, value=%{public}s",
258             key, size, valueString.c_str());
259         return false;
260     }
261     return true;
262 }
263 
JSON_AddStringArrayToObject(JsonObj * obj,const char * const key,const char ** value,int32_t len)264 bool JSON_AddStringArrayToObject(JsonObj *obj, const char * const key, const char **value, int32_t len)
265 {
266     if (value == NULL || obj == NULL || key == NULL || len == 0) {
267         JSON_LOGE("input invalid");
268         return false;
269     }
270     nlohmann::json *json = reinterpret_cast<nlohmann::json *>(obj->context);
271     if (json == nullptr) {
272         return false;
273     }
274     nlohmann::json valueStringArray = nlohmann::json::array();
275     for (int32_t i = 0; i < len; i++) {
276         valueStringArray.push_back(value[i]);
277     }
278     (*json)[key] = valueStringArray;
279     return true;
280 }
281 
JSON_GetStringArrayFromOject(const JsonObj * obj,const char * const key,char ** value,int32_t * len)282 bool JSON_GetStringArrayFromOject(const JsonObj *obj, const char * const key, char **value, int32_t *len)
283 {
284     if (value == NULL || obj == NULL || key == NULL || len == NULL || *len <= 0) {
285         JSON_LOGE("input invalid");
286         return false;
287     }
288     nlohmann::json *json = reinterpret_cast<nlohmann::json *>(obj->context);
289     if (json == nullptr) {
290         return false;
291     }
292     nlohmann::json item = (*json)[key];
293     if (!item.is_array()) {
294         JSON_LOGE("cannot find or invalid [%{public}s]", key);
295         return false;
296     }
297     if (*len < item.size()) {
298         JSON_LOGE("item size invalid, size=%lu.", (unsigned long)item.size());
299         return false;
300     }
301     int32_t i = 0;
302     for (nlohmann::json::iterator it = item.begin(); it != item.end(); ++it) {
303         std::string str = it.value().get<std::string>();
304         const char *valueString = str.c_str();
305         uint32_t len = strlen(valueString) + 1;
306         value[i] = (char*)SoftBusCalloc(len);
307         if (value[i] == NULL) {
308             return false;
309         }
310         if (strcpy_s(value[i], len, valueString) != EOK) {
311             JSON_LOGE("strcpy [%{public}s] value err, value=%{public}s", key, valueString);
312             return false;
313         }
314         i++;
315     }
316     *len = item.size();
317     return true;
318 }