+struct extend_map_element_data {
+ struct bt_value *extended_obj;
+ bt_bool got_error;
+};
+
+static
+bt_bool extend_map_element(const char *key,
+ struct bt_value *extension_obj_elem, void *data)
+{
+ bt_bool ret = BT_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)) {
+ BT_LOGE("Cannot replace value in extended value: key=\"%s\", "
+ "extended-value-addr=%p, element-value-addr=%p",
+ key, extend_data->extended_obj,
+ extension_obj_elem_copy);
+ goto error;
+ }
+
+ goto end;
+
+error:
+ ret = BT_FALSE;
+ extend_data->got_error = BT_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 (!base_map_obj || !extension_obj) {
+ BT_LOGW("Invalid parameter: base value or extension value is NULL: "
+ "base-value-addr=%p, extension-value-addr=%p",
+ base_map_obj, extension_obj);
+ goto error;
+ }
+
+ if (!bt_value_is_map(base_map_obj)) {
+ BT_LOGW("Invalid parameter: value is not a map value: addr=%p, "
+ "type=%s", base_map_obj,
+ bt_value_type_string(base_map_obj->type));
+ goto error;
+ }
+
+ if (!bt_value_is_map(extension_obj)) {
+ BT_LOGW("Invalid parameter: value is not a map value: addr=%p, "
+ "type=%s", extension_obj,
+ bt_value_type_string(extension_obj->type));
+ goto error;
+ }
+
+ BT_LOGD("Extending map value: base-value-addr=%p, extension-value-addr=%p",
+ base_map_obj, extension_obj);
+
+ /* Create copy of base map object to start with */
+ extended_obj = bt_value_copy(base_map_obj);
+ if (!extended_obj) {
+ BT_LOGE("Cannot copy base value: base-value-addr=%p",
+ base_map_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)) {
+ BT_LOGE("Cannot iterate on the extension object's elements: "
+ "extension-value-addr=%p", extension_obj);
+ goto error;
+ }
+
+ if (extend_data.got_error) {
+ BT_LOGE("Failed to successfully iterate on the extension object's elements: "
+ "extension-value-addr=%p", extension_obj);
+ goto error;
+ }
+
+ BT_LOGD("Extended map value: extended-value-addr=%p",
+ extended_obj);
+ goto end;
+
+error:
+ BT_PUT(extended_obj);
+
+end:
+ return extended_obj;
+}
+