FreeRDP
Loading...
Searching...
No Matches
jansson.c
1
20#include <winpr/file.h>
21#include <winpr/json.h>
22#include <winpr/assert.h>
23
24#include "../log.h"
25#define TAG WINPR_TAG("utils.json.jansson")
26
27#if !defined(WITH_JANSSON)
28#error "This file must only be compiled if jansson library is linked in"
29#endif
30#include <jansson.h>
31
32#if !defined(JANSSON_VERSION_HEX) || (JANSSON_VERSION_HEX < 0x020d00)
33#error "The library detected is too old, need >= 2.13.0"
34#endif
35
36static WINPR_TLS char lasterror[256] = WINPR_C_ARRAY_INIT;
37
38#if defined(WITH_DEBUG_JANSSON)
39#include "../log.h"
40#define TAG WINPR_TAG("jansson")
41
42#define ccast(json) ccast_((json), __func__)
43static const json_t* ccast_(const WINPR_JSON* json, const char* fkt)
44{
45 const json_t* jansson = (const json_t*)json;
46 if (!jansson)
47 WLog_DBG(TAG, "%s: nullptr", fkt);
48 else
49 {
50 WLog_DBG(TAG, "%s: %" PRIuz, fkt, jansson->refcount);
51 }
52 return jansson;
53}
54
55#define cast(json) cast_((json), __func__)
56static json_t* cast_(WINPR_JSON* json, const char* fkt)
57{
58 json_t* jansson = (json_t*)json;
59 if (!jansson)
60 WLog_DBG(TAG, "%s: nullptr", fkt);
61 else
62 {
63 WLog_DBG(TAG, "%s: %" PRIuz, fkt, jansson->refcount);
64 }
65 return jansson;
66}
67
68#define revcast(json) revcast_((json), __func__)
69static WINPR_JSON* revcast_(json_t* json, const char* fkt)
70{
71 json_t* jansson = (json_t*)json;
72 if (!jansson)
73 WLog_DBG(TAG, "%s: nullptr", fkt);
74 else
75 {
76 WLog_DBG(TAG, "%s: %" PRIuz, fkt, jansson->refcount);
77 }
78 return jansson;
79}
80#else
81WINPR_ATTR_NODISCARD
82static inline const json_t* ccast(const WINPR_JSON* json)
83{
84 return WINPR_CXX_COMPAT_CAST(const json_t*, json);
85}
86
87WINPR_ATTR_NODISCARD
88static inline json_t* cast(WINPR_JSON* json)
89{
90 return WINPR_CXX_COMPAT_CAST(json_t*, json);
91}
92
93WINPR_ATTR_NODISCARD
94static inline WINPR_JSON* revcast(json_t* json)
95{
96 return WINPR_CXX_COMPAT_CAST(WINPR_JSON*, json);
97}
98#endif
99
100int WINPR_JSON_version(char* buffer, size_t len)
101{
102 return _snprintf(buffer, len, "jansson %s", jansson_version_str());
103}
104
105static WINPR_JSON* updateError(WINPR_JSON* json, const json_error_t* error)
106{
107 lasterror[0] = '\0';
108 if (!json)
109 (void)_snprintf(lasterror, sizeof(lasterror), "[%d:%d:%d] %s [%s]", error->line,
110 error->column, error->position, error->text, error->source);
111 return json;
112}
113
114WINPR_JSON* WINPR_JSON_Parse(const char* value)
115{
116 json_error_t error = WINPR_C_ARRAY_INIT;
117 WINPR_JSON* json = revcast(json_loads(value, JSON_DECODE_ANY, &error));
118 return updateError(json, &error);
119}
120
121WINPR_JSON* WINPR_JSON_ParseWithLength(const char* value, size_t buffer_length)
122{
123 if (!value || (buffer_length == 0))
124 return nullptr;
125
126 json_error_t error = WINPR_C_ARRAY_INIT;
127 const size_t slen = strnlen(value, buffer_length);
128 WINPR_JSON* json = revcast(json_loadb(value, slen, JSON_DECODE_ANY, &error));
129 return updateError(json, &error);
130}
131
132void WINPR_JSON_Delete(WINPR_JSON* item)
133{
134 json_delete(cast(item));
135}
136
137WINPR_JSON* WINPR_JSON_GetArrayItem(const WINPR_JSON* array, size_t index)
138{
139 return revcast(json_array_get(ccast(array), index));
140}
141
142size_t WINPR_JSON_GetArraySize(const WINPR_JSON* array)
143{
144 return json_array_size(ccast(array));
145}
146
147WINPR_JSON* WINPR_JSON_GetObjectItem(const WINPR_JSON* object, const char* string)
148{
149 json_t* json = cast(WINPR_CAST_CONST_PTR_AWAY(object, WINPR_JSON*));
150 void* it = json_object_iter(json);
151 while (it)
152 {
153 const char* name = json_object_iter_key(it);
154 if (_stricmp(name, string) == 0)
155 return revcast(json_object_iter_value(it));
156 it = json_object_iter_next(json, it);
157 }
158 return nullptr;
159}
160
161WINPR_JSON* WINPR_JSON_GetObjectItemCaseSensitive(const WINPR_JSON* object, const char* string)
162{
163 return revcast(json_object_get(ccast(object), string));
164}
165
166BOOL WINPR_JSON_HasObjectItem(const WINPR_JSON* object, const char* string)
167{
168 return json_object_get(ccast(object), string) != nullptr;
169}
170
171const char* WINPR_JSON_GetErrorPtr(void)
172{
173 return lasterror;
174}
175
176const char* WINPR_JSON_GetStringValue(WINPR_JSON* item)
177{
178 return json_string_value(cast(item));
179}
180
181double WINPR_JSON_GetNumberValue(const WINPR_JSON* item)
182{
183 return json_number_value(ccast(item));
184}
185
186BOOL WINPR_JSON_IsInvalid(const WINPR_JSON* item)
187{
188 const json_t* jitem = ccast(item);
189 if (WINPR_JSON_IsArray(jitem))
190 return FALSE;
191 if (WINPR_JSON_IsObject(jitem))
192 return FALSE;
193 if (WINPR_JSON_IsNull(jitem))
194 return FALSE;
195 if (WINPR_JSON_IsNumber(jitem))
196 return FALSE;
197 if (WINPR_JSON_IsBool(jitem))
198 return FALSE;
199 if (WINPR_JSON_IsString(jitem))
200 return FALSE;
201 return TRUE;
202}
203
204BOOL WINPR_JSON_IsFalse(const WINPR_JSON* item)
205{
206 return json_is_false(ccast(item));
207}
208
209BOOL WINPR_JSON_IsTrue(const WINPR_JSON* item)
210{
211 return json_is_true(ccast(item));
212}
213
214BOOL WINPR_JSON_IsBool(const WINPR_JSON* item)
215{
216 return json_is_boolean(ccast(item));
217}
218
219BOOL WINPR_JSON_IsNull(const WINPR_JSON* item)
220{
221 return json_is_null(ccast(item));
222}
223
224BOOL WINPR_JSON_IsNumber(const WINPR_JSON* item)
225{
226 return json_is_number(ccast(item));
227}
228
229BOOL WINPR_JSON_IsString(const WINPR_JSON* item)
230{
231 return json_is_string(ccast(item));
232}
233
234BOOL WINPR_JSON_IsArray(const WINPR_JSON* item)
235{
236 return json_is_array(ccast(item));
237}
238
239BOOL WINPR_JSON_IsObject(const WINPR_JSON* item)
240{
241 return json_is_object(ccast(item));
242}
243
244WINPR_JSON* WINPR_JSON_CreateNull(void)
245{
246 return revcast(json_null());
247}
248
249WINPR_JSON* WINPR_JSON_CreateTrue(void)
250{
251 return revcast(json_true());
252}
253
254WINPR_JSON* WINPR_JSON_CreateFalse(void)
255{
256 return revcast(json_false());
257}
258
259WINPR_JSON* WINPR_JSON_CreateBool(BOOL boolean)
260{
261 return revcast(json_boolean(boolean));
262}
263
264WINPR_JSON* WINPR_JSON_CreateNumber(double num)
265{
266 return revcast(json_real(num));
267}
268
269WINPR_JSON* WINPR_JSON_CreateString(const char* string)
270{
271 return revcast(json_string(string));
272}
273
274WINPR_JSON* WINPR_JSON_CreateArray(void)
275{
276 return revcast(json_array());
277}
278
279WINPR_JSON* WINPR_JSON_CreateObject(void)
280{
281 return revcast(json_object());
282}
283
284static WINPR_JSON* add_to_object(WINPR_JSON* object, const char* name, json_t* obj)
285{
286 if (!obj)
287 return nullptr;
288 const int rc = json_object_set_new(cast(object), name, obj);
289 if (rc != 0)
290 return nullptr;
291 return revcast(obj);
292}
293
294WINPR_JSON* WINPR_JSON_AddNullToObject(WINPR_JSON* object, const char* name)
295{
296 json_t* obj = json_null();
297 return add_to_object(object, name, obj);
298}
299
300WINPR_JSON* WINPR_JSON_AddTrueToObject(WINPR_JSON* object, const char* name)
301{
302 json_t* obj = json_true();
303 return add_to_object(object, name, obj);
304}
305
306WINPR_JSON* WINPR_JSON_AddFalseToObject(WINPR_JSON* object, const char* name)
307{
308 json_t* obj = json_false();
309 return add_to_object(object, name, obj);
310}
311
312WINPR_JSON* WINPR_JSON_AddBoolToObject(WINPR_JSON* object, const char* name, BOOL boolean)
313{
314 json_t* obj = json_boolean(boolean);
315 return add_to_object(object, name, obj);
316}
317
318WINPR_JSON* WINPR_JSON_AddNumberToObject(WINPR_JSON* object, const char* name, double number)
319{
320 json_t* obj = json_real(number);
321 return add_to_object(object, name, obj);
322}
323
324WINPR_JSON* WINPR_JSON_AddIntegerToObject(WINPR_JSON* object, const char* name, int64_t number)
325{
326 json_t* obj = json_integer(number);
327 return add_to_object(object, name, obj);
328}
329
330WINPR_JSON* WINPR_JSON_AddUIntegerToObject(WINPR_JSON* object, const char* name, uint64_t number)
331{
332 if (number > INT64_MAX)
333 {
334 WLog_ERR(TAG, "jansson does not support integers > %" PRId64, INT64_MAX);
335 return nullptr;
336 }
337
338 json_t* obj = json_integer((int64_t)number);
339 return add_to_object(object, name, obj);
340}
341
342WINPR_JSON* WINPR_JSON_AddStringToObject(WINPR_JSON* object, const char* name, const char* string)
343{
344 json_t* obj = json_string(string);
345 return add_to_object(object, name, obj);
346}
347
348WINPR_JSON* WINPR_JSON_AddObjectToObject(WINPR_JSON* object, const char* name)
349{
350 json_t* obj = json_object();
351 return add_to_object(object, name, obj);
352}
353
354BOOL WINPR_JSON_AddItemToArray(WINPR_JSON* array, WINPR_JSON* item)
355{
356 return json_array_append_new(cast(array), item) == 0;
357}
358
359WINPR_JSON* WINPR_JSON_AddArrayToObject(WINPR_JSON* object, const char* name)
360{
361 json_t* obj = json_array();
362 return add_to_object(object, name, obj);
363}
364
365char* WINPR_JSON_Print(WINPR_JSON* item)
366{
367 return json_dumps(cast(item), JSON_INDENT(2) | JSON_ENSURE_ASCII | JSON_SORT_KEYS);
368}
369
370char* WINPR_JSON_PrintUnformatted(WINPR_JSON* item)
371{
372 return json_dumps(cast(item), JSON_COMPACT | JSON_ENSURE_ASCII | JSON_SORT_KEYS);
373}
WINPR_JSON * WINPR_JSON_CreateString(const char *string)
WINPR_JSON_CreateString.
Definition jansson.c:269
WINPR_JSON * WINPR_JSON_CreateNull(void)
WINPR_JSON_CreateNull.
Definition jansson.c:244
BOOL WINPR_JSON_IsNull(const WINPR_JSON *item)
Check if JSON item is Null.
Definition jansson.c:219
WINPR_JSON * WINPR_JSON_CreateTrue(void)
WINPR_JSON_CreateTrue.
Definition jansson.c:249
WINPR_JSON * WINPR_JSON_CreateNumber(double num)
WINPR_JSON_CreateNumber.
Definition jansson.c:264
WINPR_JSON * WINPR_JSON_AddObjectToObject(WINPR_JSON *object, const char *name)
WINPR_JSON_AddObjectToObject.
Definition jansson.c:348
WINPR_JSON * WINPR_JSON_CreateObject(void)
WINPR_JSON_CreateObject.
Definition jansson.c:279
BOOL WINPR_JSON_HasObjectItem(const WINPR_JSON *object, const char *string)
Check if JSON has an object matching the name.
Definition jansson.c:166
BOOL WINPR_JSON_IsBool(const WINPR_JSON *item)
Check if JSON item is of type BOOL.
Definition jansson.c:214
BOOL WINPR_JSON_AddItemToArray(WINPR_JSON *array, WINPR_JSON *item)
Add an item to an existing array.
Definition jansson.c:354
BOOL WINPR_JSON_IsInvalid(const WINPR_JSON *item)
Check if JSON item is valid.
Definition jansson.c:186
BOOL WINPR_JSON_IsNumber(const WINPR_JSON *item)
Check if JSON item is of type Number.
Definition jansson.c:224
int WINPR_JSON_version(char *buffer, size_t len)
Get the library version string.
Definition jansson.c:100
size_t WINPR_JSON_GetArraySize(const WINPR_JSON *array)
Get the number of arrayitems from an array.
Definition jansson.c:142
WINPR_JSON * WINPR_JSON_CreateFalse(void)
WINPR_JSON_CreateFalse.
Definition jansson.c:254
WINPR_JSON * WINPR_JSON_AddIntegerToObject(WINPR_JSON *object, const char *name, int64_t number)
WINPR_JSON_AddIntegerToObject.
Definition jansson.c:324
WINPR_JSON * WINPR_JSON_AddFalseToObject(WINPR_JSON *object, const char *name)
WINPR_JSON_AddFalseToObject.
Definition jansson.c:306
char * WINPR_JSON_Print(WINPR_JSON *item)
Serialize a JSON instance to string for minimal size without formatting see WINPR_JSON_PrintUnformatt...
Definition jansson.c:365
BOOL WINPR_JSON_IsTrue(const WINPR_JSON *item)
Check if JSON item is BOOL value True.
Definition jansson.c:209
WINPR_JSON * WINPR_JSON_AddTrueToObject(WINPR_JSON *object, const char *name)
WINPR_JSON_AddTrueToObject.
Definition jansson.c:300
WINPR_JSON * WINPR_JSON_GetObjectItemCaseSensitive(const WINPR_JSON *object, const char *string)
Same as WINPR_JSON_GetObjectItem but with case sensitive matching.
Definition jansson.c:161
WINPR_JSON * WINPR_JSON_AddNumberToObject(WINPR_JSON *object, const char *name, double number)
WINPR_JSON_AddNumberToObject.
Definition jansson.c:318
WINPR_JSON * WINPR_JSON_GetObjectItem(const WINPR_JSON *object, const char *string)
Return a pointer to an JSON object item.
Definition jansson.c:147
BOOL WINPR_JSON_IsFalse(const WINPR_JSON *item)
Check if JSON item is BOOL value False.
Definition jansson.c:204
WINPR_JSON * WINPR_JSON_ParseWithLength(const char *value, size_t buffer_length)
Parse a JSON string.
Definition jansson.c:121
WINPR_JSON * WINPR_JSON_AddUIntegerToObject(WINPR_JSON *object, const char *name, uint64_t number)
WINPR_JSON_AddUIntegerToObject.
Definition jansson.c:330
const char * WINPR_JSON_GetErrorPtr(void)
Return an error string.
Definition jansson.c:171
WINPR_JSON * WINPR_JSON_AddArrayToObject(WINPR_JSON *object, const char *name)
WINPR_JSON_AddArrayToObject.
Definition jansson.c:359
BOOL WINPR_JSON_IsString(const WINPR_JSON *item)
Check if JSON item is of type String.
Definition jansson.c:229
WINPR_JSON * WINPR_JSON_GetArrayItem(const WINPR_JSON *array, size_t index)
Return a pointer to an item in the array.
Definition jansson.c:137
char * WINPR_JSON_PrintUnformatted(WINPR_JSON *item)
Serialize a JSON instance to string without formatting for human readable formatted output see WINPR_...
Definition jansson.c:370
double WINPR_JSON_GetNumberValue(const WINPR_JSON *item)
Return the Number value of a JSON item.
Definition jansson.c:181
WINPR_JSON * WINPR_JSON_CreateBool(BOOL boolean)
WINPR_JSON_CreateBool.
Definition jansson.c:259
BOOL WINPR_JSON_IsArray(const WINPR_JSON *item)
Check if JSON item is of type Array.
Definition jansson.c:234
BOOL WINPR_JSON_IsObject(const WINPR_JSON *item)
Check if JSON item is of type Object.
Definition jansson.c:239
WINPR_JSON * WINPR_JSON_AddNullToObject(WINPR_JSON *object, const char *name)
WINPR_JSON_AddNullToObject.
Definition jansson.c:294
WINPR_JSON * WINPR_JSON_AddStringToObject(WINPR_JSON *object, const char *name, const char *string)
WINPR_JSON_AddStringToObject.
Definition jansson.c:342
void WINPR_JSON_Delete(WINPR_JSON *item)
Delete a WinPR JSON wrapper object.
Definition jansson.c:132
WINPR_JSON * WINPR_JSON_CreateArray(void)
WINPR_JSON_CreateArray.
Definition jansson.c:274
const char * WINPR_JSON_GetStringValue(WINPR_JSON *item)
Return the String value of a JSON item.
Definition jansson.c:176
WINPR_JSON * WINPR_JSON_AddBoolToObject(WINPR_JSON *object, const char *name, BOOL boolean)
WINPR_JSON_AddBoolToObject.
Definition jansson.c:312
WINPR_JSON * WINPR_JSON_Parse(const char *value)
Parse a '\0' terminated JSON string.
Definition jansson.c:114