diff options
author | Christian Grothoff <christian@grothoff.org> | 2023-04-30 16:17:04 +0200 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2023-04-30 16:17:04 +0200 |
commit | cbc7ea55a23073c606bc9284b0a68fe9471e7d46 (patch) | |
tree | e3c6f6d3532f16cf3338a1db5fccb36f6a964d25 | |
parent | 6d676cbe03368223204e01053cf392fa107922be (diff) | |
download | gnunet-cbc7ea55a23073c606bc9284b0a68fe9471e7d46.tar.gz gnunet-cbc7ea55a23073c606bc9284b0a68fe9471e7d46.zip |
JSON: add const json parsers for objects/arrays
NEWS: adds GNUNET_JSON_spec_object_const() and GNUNET_JSON_spec_array_const()
-rw-r--r-- | src/include/gnunet_json_lib.h | 25 | ||||
-rw-r--r-- | src/json/json_helper.c | 96 |
2 files changed, 113 insertions, 8 deletions
diff --git a/src/include/gnunet_json_lib.h b/src/include/gnunet_json_lib.h index a65293a7c..26c68fed3 100644 --- a/src/include/gnunet_json_lib.h +++ b/src/include/gnunet_json_lib.h | |||
@@ -246,7 +246,8 @@ GNUNET_JSON_spec_string (const char *name, | |||
246 | 246 | ||
247 | 247 | ||
248 | /** | 248 | /** |
249 | * JSON object. | 249 | * JSON object or array. Reference counter is |
250 | * incremented. | ||
250 | * | 251 | * |
251 | * @param name name of the JSON field | 252 | * @param name name of the JSON field |
252 | * @param[out] jsonp where to store the JSON found under @a name | 253 | * @param[out] jsonp where to store the JSON found under @a name |
@@ -257,6 +258,28 @@ GNUNET_JSON_spec_json (const char *name, | |||
257 | 258 | ||
258 | 259 | ||
259 | /** | 260 | /** |
261 | * JSON object, reference counter not incremented. | ||
262 | * | ||
263 | * @param name name of the JSON field | ||
264 | * @param[out] jsonp where to store the JSON found under @a name | ||
265 | */ | ||
266 | struct GNUNET_JSON_Specification | ||
267 | GNUNET_JSON_spec_object_const (const char *name, | ||
268 | const json_t **jsonp); | ||
269 | |||
270 | |||
271 | /** | ||
272 | * JSON array, reference counter not incremented. | ||
273 | * | ||
274 | * @param name name of the JSON field | ||
275 | * @param[out] jsonp where to store the JSON found under @a name | ||
276 | */ | ||
277 | struct GNUNET_JSON_Specification | ||
278 | GNUNET_JSON_spec_array_const (const char *name, | ||
279 | const json_t **jsonp); | ||
280 | |||
281 | |||
282 | /** | ||
260 | * boolean. | 283 | * boolean. |
261 | * | 284 | * |
262 | * @param name name of the JSON field | 285 | * @param name name of the JSON field |
diff --git a/src/json/json_helper.c b/src/json/json_helper.c index aadc6804d..61257e62a 100644 --- a/src/json/json_helper.c +++ b/src/json/json_helper.c | |||
@@ -301,9 +301,9 @@ GNUNET_JSON_spec_string (const char *name, | |||
301 | * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error | 301 | * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error |
302 | */ | 302 | */ |
303 | static enum GNUNET_GenericReturnValue | 303 | static enum GNUNET_GenericReturnValue |
304 | parse_object (void *cls, | 304 | parse_json (void *cls, |
305 | json_t *root, | 305 | json_t *root, |
306 | struct GNUNET_JSON_Specification *spec) | 306 | struct GNUNET_JSON_Specification *spec) |
307 | { | 307 | { |
308 | if (! (json_is_object (root) || json_is_array (root))) | 308 | if (! (json_is_object (root) || json_is_array (root))) |
309 | { | 309 | { |
@@ -323,8 +323,8 @@ parse_object (void *cls, | |||
323 | * @param[out] spec where to free the data | 323 | * @param[out] spec where to free the data |
324 | */ | 324 | */ |
325 | static void | 325 | static void |
326 | clean_object (void *cls, | 326 | clean_json (void *cls, |
327 | struct GNUNET_JSON_Specification *spec) | 327 | struct GNUNET_JSON_Specification *spec) |
328 | { | 328 | { |
329 | json_t **ptr = (json_t **) spec->ptr; | 329 | json_t **ptr = (json_t **) spec->ptr; |
330 | 330 | ||
@@ -341,8 +341,90 @@ GNUNET_JSON_spec_json (const char *name, | |||
341 | json_t **jsonp) | 341 | json_t **jsonp) |
342 | { | 342 | { |
343 | struct GNUNET_JSON_Specification ret = { | 343 | struct GNUNET_JSON_Specification ret = { |
344 | .parser = &parse_object, | 344 | .parser = &parse_json, |
345 | .cleaner = &clean_object, | 345 | .cleaner = &clean_json, |
346 | .cls = NULL, | ||
347 | .field = name, | ||
348 | .ptr = jsonp, | ||
349 | .ptr_size = 0, | ||
350 | .size_ptr = NULL | ||
351 | }; | ||
352 | |||
353 | *jsonp = NULL; | ||
354 | return ret; | ||
355 | } | ||
356 | |||
357 | |||
358 | /** | ||
359 | * Parse given JSON object to a JSON object. | ||
360 | * | ||
361 | * @param cls closure, NULL | ||
362 | * @param root the json object representing data | ||
363 | * @param[out] spec where to write the data | ||
364 | * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error | ||
365 | */ | ||
366 | static enum GNUNET_GenericReturnValue | ||
367 | parse_object_const (void *cls, | ||
368 | json_t *root, | ||
369 | struct GNUNET_JSON_Specification *spec) | ||
370 | { | ||
371 | if (! json_is_object (root)) | ||
372 | { | ||
373 | GNUNET_break_op (0); | ||
374 | return GNUNET_SYSERR; | ||
375 | } | ||
376 | *(const json_t **) spec->ptr = (const json_t *) root; | ||
377 | return GNUNET_OK; | ||
378 | } | ||
379 | |||
380 | |||
381 | struct GNUNET_JSON_Specification | ||
382 | GNUNET_JSON_spec_object_const (const char *name, | ||
383 | const json_t **jsonp) | ||
384 | { | ||
385 | struct GNUNET_JSON_Specification ret = { | ||
386 | .parser = &parse_object_const, | ||
387 | .cls = NULL, | ||
388 | .field = name, | ||
389 | .ptr = jsonp, | ||
390 | .ptr_size = 0, | ||
391 | .size_ptr = NULL | ||
392 | }; | ||
393 | |||
394 | *jsonp = NULL; | ||
395 | return ret; | ||
396 | } | ||
397 | |||
398 | |||
399 | /** | ||
400 | * Parse given JSON to a JSON array. | ||
401 | * | ||
402 | * @param cls closure, NULL | ||
403 | * @param root the json object representing data | ||
404 | * @param[out] spec where to write the data | ||
405 | * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error | ||
406 | */ | ||
407 | static enum GNUNET_GenericReturnValue | ||
408 | parse_array_const (void *cls, | ||
409 | json_t *root, | ||
410 | struct GNUNET_JSON_Specification *spec) | ||
411 | { | ||
412 | if (! json_is_array (root)) | ||
413 | { | ||
414 | GNUNET_break_op (0); | ||
415 | return GNUNET_SYSERR; | ||
416 | } | ||
417 | *(const json_t **) spec->ptr = (const json_t *) root; | ||
418 | return GNUNET_OK; | ||
419 | } | ||
420 | |||
421 | |||
422 | struct GNUNET_JSON_Specification | ||
423 | GNUNET_JSON_spec_array_const (const char *name, | ||
424 | const json_t **jsonp) | ||
425 | { | ||
426 | struct GNUNET_JSON_Specification ret = { | ||
427 | .parser = &parse_array_const, | ||
346 | .cls = NULL, | 428 | .cls = NULL, |
347 | .field = name, | 429 | .field = name, |
348 | .ptr = jsonp, | 430 | .ptr = jsonp, |