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