summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2023-04-30 16:17:04 +0200
committerChristian Grothoff <christian@grothoff.org>2023-04-30 16:17:04 +0200
commitcbc7ea55a23073c606bc9284b0a68fe9471e7d46 (patch)
treee3c6f6d3532f16cf3338a1db5fccb36f6a964d25
parent6d676cbe03368223204e01053cf392fa107922be (diff)
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.h25
-rw-r--r--src/json/json_helper.c96
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,
/**
- * JSON object.
+ * JSON object or array. Reference counter is
+ * incremented.
*
* @param name name of the JSON field
* @param[out] jsonp where to store the JSON found under @a name
@@ -257,6 +258,28 @@ GNUNET_JSON_spec_json (const char *name,
/**
+ * JSON object, reference counter not incremented.
+ *
+ * @param name name of the JSON field
+ * @param[out] jsonp where to store the JSON found under @a name
+ */
+struct GNUNET_JSON_Specification
+GNUNET_JSON_spec_object_const (const char *name,
+ const json_t **jsonp);
+
+
+/**
+ * JSON array, reference counter not incremented.
+ *
+ * @param name name of the JSON field
+ * @param[out] jsonp where to store the JSON found under @a name
+ */
+struct GNUNET_JSON_Specification
+GNUNET_JSON_spec_array_const (const char *name,
+ const json_t **jsonp);
+
+
+/**
* boolean.
*
* @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,
* @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
*/
static enum GNUNET_GenericReturnValue
-parse_object (void *cls,
- json_t *root,
- struct GNUNET_JSON_Specification *spec)
+parse_json (void *cls,
+ json_t *root,
+ struct GNUNET_JSON_Specification *spec)
{
if (! (json_is_object (root) || json_is_array (root)))
{
@@ -323,8 +323,8 @@ parse_object (void *cls,
* @param[out] spec where to free the data
*/
static void
-clean_object (void *cls,
- struct GNUNET_JSON_Specification *spec)
+clean_json (void *cls,
+ struct GNUNET_JSON_Specification *spec)
{
json_t **ptr = (json_t **) spec->ptr;
@@ -341,8 +341,90 @@ GNUNET_JSON_spec_json (const char *name,
json_t **jsonp)
{
struct GNUNET_JSON_Specification ret = {
- .parser = &parse_object,
- .cleaner = &clean_object,
+ .parser = &parse_json,
+ .cleaner = &clean_json,
+ .cls = NULL,
+ .field = name,
+ .ptr = jsonp,
+ .ptr_size = 0,
+ .size_ptr = NULL
+ };
+
+ *jsonp = NULL;
+ return ret;
+}
+
+
+/**
+ * Parse given JSON object to a JSON object.
+ *
+ * @param cls closure, NULL
+ * @param root the json object representing data
+ * @param[out] spec where to write the data
+ * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
+ */
+static enum GNUNET_GenericReturnValue
+parse_object_const (void *cls,
+ json_t *root,
+ struct GNUNET_JSON_Specification *spec)
+{
+ if (! json_is_object (root))
+ {
+ GNUNET_break_op (0);
+ return GNUNET_SYSERR;
+ }
+ *(const json_t **) spec->ptr = (const json_t *) root;
+ return GNUNET_OK;
+}
+
+
+struct GNUNET_JSON_Specification
+GNUNET_JSON_spec_object_const (const char *name,
+ const json_t **jsonp)
+{
+ struct GNUNET_JSON_Specification ret = {
+ .parser = &parse_object_const,
+ .cls = NULL,
+ .field = name,
+ .ptr = jsonp,
+ .ptr_size = 0,
+ .size_ptr = NULL
+ };
+
+ *jsonp = NULL;
+ return ret;
+}
+
+
+/**
+ * Parse given JSON to a JSON array.
+ *
+ * @param cls closure, NULL
+ * @param root the json object representing data
+ * @param[out] spec where to write the data
+ * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
+ */
+static enum GNUNET_GenericReturnValue
+parse_array_const (void *cls,
+ json_t *root,
+ struct GNUNET_JSON_Specification *spec)
+{
+ if (! json_is_array (root))
+ {
+ GNUNET_break_op (0);
+ return GNUNET_SYSERR;
+ }
+ *(const json_t **) spec->ptr = (const json_t *) root;
+ return GNUNET_OK;
+}
+
+
+struct GNUNET_JSON_Specification
+GNUNET_JSON_spec_array_const (const char *name,
+ const json_t **jsonp)
+{
+ struct GNUNET_JSON_Specification ret = {
+ .parser = &parse_array_const,
.cls = NULL,
.field = name,
.ptr = jsonp,