Make utils-json handle dot keys
authorJosé Bollo <jose.bollo@iot.bzh>
Thu, 26 Jan 2017 17:56:19 +0000 (18:56 +0100)
committerJosé Bollo <jose.bollo@iot.bzh>
Thu, 26 Jan 2017 17:56:19 +0000 (18:56 +0100)
Change-Id: I8b9b91accc0e30726e3be7f287b8312b0d7f3d02
Signed-off-by: José Bollo <jose.bollo@iot.bzh>
src/utils-json.c
src/utils-json.h

index 96da660..fe98c3c 100644 (file)
  limitations under the License.
 */
 
+#define _GNU_SOURCE
+
 #include <errno.h>
+#include <string.h>
+#include <stdarg.h>
 
 #include <json-c/json.h>
 
@@ -52,6 +56,11 @@ int j_integer(struct json_object *obj, int defval)
        return j_is_integer(obj) ? json_object_get_int(obj) : defval;
 }
 
+int j_has(struct json_object *obj, const char *key)
+{
+       return json_object_object_get_ex(obj, key, NULL);
+}
+
 int j_read_object_at(struct json_object *obj, const char *key, struct json_object **value)
 {
        return json_object_object_get_ex(obj, key, value);
@@ -140,3 +149,145 @@ struct json_object *j_add_new_object(struct json_object *obj, const char *key)
        return result;
 }
 
+int j_enter_m(struct json_object **obj, const char **mkey, int create)
+{
+       char *n;
+       struct json_object *o, *x;
+       const char *f, *k;
+
+       k = *mkey;
+       f = strchr(k, '.');
+       if (f) {
+               o = *obj;
+               do {
+                       n = strndupa(k, (size_t)(f - k));
+                       if (!json_object_object_get_ex(o, n, &x)) {
+                               if (!create)
+                                       return -ENOENT;
+                               x = j_add_new_object(o, n);
+                               if (!x)
+                                       return -ENOMEM;
+                       }
+                       o = x;
+                       k = f + 1;
+                       f = strchr(k, '.');
+               } while(f);
+               *obj = o;
+               *mkey = k;
+       }
+       return 0;
+}
+
+
+int j_has_m(struct json_object *obj, const char *mkey)
+{
+       return !j_enter_m(&obj, &mkey, 0) && j_has(obj, mkey);
+}
+
+int j_read_object_at_m(struct json_object *obj, const char *mkey, struct json_object **value)
+{
+       return !j_enter_m(&obj, &mkey, 0) && j_read_object_at(obj, mkey, value);
+}
+
+int j_read_string_at_m(struct json_object *obj, const char *mkey, const char **value)
+{
+       json_object *data;
+       return j_read_object_at_m(obj, mkey, &data) && j_read_string(data, value);
+}
+
+int j_read_boolean_at_m(struct json_object *obj, const char *mkey, int *value)
+{
+       json_object *data;
+       return j_read_object_at_m(obj, mkey, &data) && j_read_boolean(data, value);
+}
+
+int j_read_integer_at_m(struct json_object *obj, const char *mkey, int *value)
+{
+       json_object *data;
+       return j_read_object_at_m(obj, mkey, &data) && j_read_integer(data, value);
+}
+
+const char *j_string_at_m(struct json_object *obj, const char *mkey, const char *defval)
+{
+       struct json_object *data;
+       return j_read_object_at_m(obj, mkey, &data) ? j_string(data, defval) : defval;
+}
+
+int j_boolean_at_m(struct json_object *obj, const char *mkey, int defval)
+{
+       struct json_object *data;
+       return j_read_object_at_m(obj, mkey, &data) ? j_boolean(data, defval) : defval;
+}
+
+int j_integer_at_m(struct json_object *obj, const char *mkey, int defval)
+{
+       struct json_object *data;
+       return j_read_object_at_m(obj, mkey, &data) ? j_integer(data, defval) : defval;
+}
+
+int j_add_m(struct json_object *obj, const char *mkey, struct json_object *val)
+{
+       if (mkey)
+               return !j_enter_m(&obj, &mkey, 1) && j_add(obj, mkey, val);
+       json_object_array_add(obj, val);
+       return 1;
+}
+
+int j_add_string_m(struct json_object *obj, const char *mkey, const char *val)
+{
+       struct json_object *str = json_object_new_string (val ? val : "");
+       return str ? j_add_m(obj, mkey, str) : (errno = ENOMEM, 0);
+}
+
+int j_add_boolean_m(struct json_object *obj, const char *mkey, int val)
+{
+       struct json_object *str = json_object_new_boolean (val);
+       return str ? j_add_m(obj, mkey, str) : (errno = ENOMEM, 0);
+}
+
+int j_add_integer_m(struct json_object *obj, const char *mkey, int val)
+{
+       struct json_object *str = json_object_new_int (val);
+       return str ? j_add_m(obj, mkey, str) : (errno = ENOMEM, 0);
+}
+
+struct json_object *j_add_new_array_m(struct json_object *obj, const char *mkey)
+{
+       struct json_object *result = json_object_new_array();
+       if (result != NULL && !j_add_m(obj, mkey, result)) {
+               json_object_put(result);
+               result = NULL;
+       }
+       return result;
+}
+
+struct json_object *j_add_new_object_m(struct json_object *obj, const char *mkey)
+{
+       struct json_object *result = json_object_new_object();
+       if (result != NULL && !j_add_m(obj, mkey, result)) {
+               json_object_put(result);
+               result = NULL;
+       }
+       return result;
+}
+
+int j_add_many_strings_m(struct json_object *obj, ...)
+{
+       const char *key, *val;
+       va_list ap;
+       int rc, rc2;
+
+       rc = 1;
+       va_start(ap, obj);
+       key = va_arg(ap, const char *);
+       while (key) {
+               val = va_arg(ap, const char *);
+               if (val) {
+                       if (!j_add_string_m(obj, key, val))
+                               rc = 0;
+               }
+               key = va_arg(ap, const char *);
+       }
+       va_end(ap);
+       return rc;
+}
index 5f1151c..de98e10 100644 (file)
@@ -42,6 +42,7 @@ extern int j_integer(struct json_object *obj, int defval);
  * Read the value of the entry of key in object if exist and of the good type and return true.
  * Returns false if the key does not exist or if the type is not correct.
  */
+extern int j_has(struct json_object *obj, const char *key);
 extern int j_read_object_at(struct json_object *obj, const char *key, struct json_object **value);
 extern int j_read_string_at(struct json_object *obj, const char *key, const char **value);
 extern int j_read_boolean_at(struct json_object *obj, const char *key, int *value);
@@ -65,3 +66,29 @@ extern int j_add_integer(struct json_object *obj, const char *key, int val);
 extern struct json_object *j_add_new_array(struct json_object *obj, const char *key);
 extern struct json_object *j_add_new_object(struct json_object *obj, const char *key);
 
+/*
+ * functions below interpret the key 'mkey' as a dot separated
+ * path specification.
+ */
+extern int j_enter_m(struct json_object **obj, const char **mkey, int create);
+
+extern int j_has_m(struct json_object *obj, const char *mkey);
+
+extern int j_read_object_at_m(struct json_object *obj, const char *mkey, struct json_object **value);
+extern int j_read_string_at_m(struct json_object *obj, const char *mkey, const char **value);
+extern int j_read_boolean_at_m(struct json_object *obj, const char *mkey, int *value);
+extern int j_read_integer_at_m(struct json_object *obj, const char *mkey, int *value);
+
+extern const char *j_string_at_m(struct json_object *obj, const char *mkey, const char *defval);
+extern int j_boolean_at_m(struct json_object *obj, const char *mkey, int defval);
+extern int j_integer_at_m(struct json_object *obj, const char *mkey, int defval);
+
+extern int j_add_m(struct json_object *obj, const char *mkey, struct json_object *val);
+extern int j_add_string_m(struct json_object *obj, const char *mkey, const char *val);
+extern int j_add_many_strings_m(struct json_object *obj, ...);
+extern int j_add_boolean_m(struct json_object *obj, const char *mkey, int val);
+extern int j_add_integer_m(struct json_object *obj, const char *mkey, int val);
+extern struct json_object *j_add_new_array_m(struct json_object *obj, const char *mkey);
+extern struct json_object *j_add_new_object_m(struct json_object *obj, const char *mkey);
+
+