values: add bt_value_map_extend()
authorPhilippe Proulx <eeppeliteloop@gmail.com>
Fri, 26 Feb 2016 06:27:47 +0000 (01:27 -0500)
committerJérémie Galarneau <jeremie.galarneau@efficios.com>
Sat, 27 May 2017 18:09:07 +0000 (14:09 -0400)
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Signed-off-by: Jérémie Galarneau <jeremie.galarneau@efficios.com>
include/babeltrace/values.h
lib/values.c

index 78fa4e5da0cb69c427b622bb0cf537e6246ad172..d5ffef0b94bd0dada2201102d227e9db6799bd42 100644 (file)
@@ -1422,6 +1422,69 @@ On success, \p key is copied.
 extern enum bt_value_status bt_value_map_insert_empty_map(
                struct bt_value *map_obj, const char *key);
 
+/**
+@brief  Creates a copy of the base map value object \p base_map_obj
+       superficially extended with the entries of the extension map
+       value object \p extension_map_obj.
+
+This function creates a superficial extension of \p base_map_obj with
+\p extension_map_obj by adding new entries to it and replacing the
+ones that share the keys in the extension object. The extension is
+\em superficial because it does not merge internal array and map
+value objects.
+
+For example, consider the following \p base_map_obj (JSON representation):
+
+@code{.unparsed}
+{
+  "hello": 23,
+  "code": -17,
+  "em": false,
+  "return": [5, 6, null]
+}
+@endcode
+
+and the following \p extension_map_obj (JSON representation):
+
+@code{.unparsed}
+{
+  "comma": ",",
+  "code": 22,
+  "return": 17.88
+}
+@endcode
+
+The extended object is (JSON representation):
+
+@code{.unparsed}
+{
+  "hello": 23,
+  "code": 22,
+  "em": false,
+  "return": 17.88,
+  "comma": ","
+}
+@endcode
+
+@param[in] base_map_obj                Base map value object with initial
+                               entries.
+@param[in] extension_map_obj   Extension map value object containing
+                               the entries to add to or replace in
+                               \p base_map_obj.
+@returns                       Created extended map value object, or
+                               \c NULL on error.
+
+@prenotnull{base_map_obj}
+@prenotnull{extension_map_obj}
+@pre \p base_map_obj is a map value object.
+@pre \p extension_map_obj is a map value object.
+@postrefcountsame{base_map_obj}
+@postrefcountsame{extension_map_obj}
+@postsuccessrefcountret1
+*/
+extern struct bt_value *bt_value_map_extend(struct bt_value *base_map_obj,
+               struct bt_value *extension_map_obj);
+
 /** @} */
 
 /** @} */
index bd217bf61ce5fa8f1cc6ad577ae3cb0f2ad96d3a..cea4b10bdc2e3e7b99be948b9dde0618b4392841 100644 (file)
@@ -1168,6 +1168,81 @@ end:
        return ret;
 }
 
+struct extend_map_element_data {
+       struct bt_value *extended_obj;
+       bool got_error;
+};
+
+static
+bool extend_map_element(const char *key,
+               struct bt_value *extension_obj_elem, void *data)
+{
+       bool ret = true;
+
+       struct extend_map_element_data *extend_data = data;
+
+       /* Copy object which is to replace the current one */
+       struct bt_value *extension_obj_elem_copy =
+               bt_value_copy(extension_obj_elem);
+
+       /* Replace in extended object */
+       if (bt_value_map_insert(extend_data->extended_obj, key,
+                       extension_obj_elem_copy)) {
+               goto error;
+       }
+
+       goto end;
+
+error:
+       ret = false;
+       extend_data->got_error = true;
+
+end:
+       BT_PUT(extension_obj_elem_copy);
+
+       return ret;
+}
+
+struct bt_value *bt_value_map_extend(struct bt_value *base_map_obj,
+               struct bt_value *extension_obj)
+{
+       struct bt_value *extended_obj = NULL;
+       struct extend_map_element_data extend_data = { 0 };
+
+       if (!bt_value_is_map(base_map_obj) || !bt_value_is_map(extension_obj)) {
+               goto error;
+       }
+
+       /* Create copy of base map object to start with */
+       extended_obj = bt_value_copy(base_map_obj);
+       if (!extended_obj) {
+               goto error;
+       }
+
+       /*
+        * For each key in the extension map object, replace this key
+        * in the copied map object.
+        */
+       extend_data.extended_obj = extended_obj;
+
+       if (bt_value_map_foreach(extension_obj, extend_map_element,
+                       &extend_data)) {
+               goto error;
+       }
+
+       if (extend_data.got_error) {
+               goto error;
+       }
+
+       goto end;
+
+error:
+       BT_PUT(extended_obj);
+
+end:
+       return extended_obj;
+}
+
 struct bt_value *bt_value_copy(const struct bt_value *object)
 {
        struct bt_value *copy_obj = NULL;
This page took 0.029343 seconds and 4 git commands to generate.