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