summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2019-01-11 15:16:33 +0100
committerThomas Haller <thaller@redhat.com>2019-01-22 16:30:23 +0100
commit3a915a020533189788b435032a1cc24b58cfab0e (patch)
tree2e3cfd14ece5e7695b40ca5ee52cfbc04c1aacf1
parentf5a86dee43256efc49ccfa79bcda1d5c6a6f670e (diff)
downloadNetworkManager-3a915a020533189788b435032a1cc24b58cfab0e.tar.gz
libnm: support nm_setting_duplicate() for non-GObject base properties
Add a hook so that we can overwrite the property info. Yes, this is an API/ABI change for NMSettingClass, which is in a header file. But this is not API that we want to support. Users must not use this. Alternatively, I could hook the callback into NMSettInfoSetting, but either works.
-rw-r--r--libnm-core/nm-setting.c114
-rw-r--r--libnm-core/nm-setting.h7
2 files changed, 72 insertions, 49 deletions
diff --git a/libnm-core/nm-setting.c b/libnm-core/nm-setting.c
index 471f5df451..7f2d4d2af1 100644
--- a/libnm-core/nm-setting.c
+++ b/libnm-core/nm-setting.c
@@ -539,12 +539,16 @@ _nm_sett_info_setting_get_property_info (const NMSettInfoSetting *sett_info,
const NMSettInfoSetting *
_nm_setting_class_get_sett_info (NMSettingClass *setting_class)
{
- if ( NM_IS_SETTING_CLASS (setting_class)
- && setting_class->setting_info) {
- nm_assert (setting_class->setting_info->meta_type < G_N_ELEMENTS (_sett_info_settings));
- return &_sett_info_settings[setting_class->setting_info->meta_type];
- }
- return NULL;
+ const NMSettInfoSetting *sett_info;
+
+ if ( !NM_IS_SETTING_CLASS (setting_class)
+ || !setting_class->setting_info)
+ return NULL;
+
+ nm_assert (setting_class->setting_info->meta_type < G_N_ELEMENTS (_sett_info_settings));
+ sett_info = &_sett_info_settings[setting_class->setting_info->meta_type];
+ nm_assert (sett_info->setting_class == setting_class);
+ return sett_info;
}
/*****************************************************************************/
@@ -1070,34 +1074,18 @@ _gobject_copy_property (GObject *src,
g_object_set_property (dst, property_name, &value);
}
-/**
- * nm_setting_duplicate:
- * @setting: the #NMSetting to duplicate
- *
- * Duplicates a #NMSetting.
- *
- * Returns: (transfer full): a new #NMSetting containing the same properties and values as the
- * source #NMSetting
- **/
-NMSetting *
-nm_setting_duplicate (NMSetting *setting)
+static void
+duplicate_copy_properties (const NMSettInfoSetting *sett_info,
+ NMSetting *src,
+ NMSetting *dst)
{
- const NMSettInfoSetting *sett_info;
- GObject *dup;
-
- g_return_val_if_fail (NM_IS_SETTING (setting), NULL);
-
- dup = g_object_new (G_OBJECT_TYPE (setting), NULL);
-
- sett_info = _nm_setting_class_get_sett_info (NM_SETTING_GET_CLASS (setting));
-
if (sett_info->detail.gendata_info) {
- GenData *gendata = _gendata_hash (setting, FALSE);
+ GenData *gendata = _gendata_hash (src, FALSE);
if ( gendata
&& g_hash_table_size (gendata->hash) > 0) {
GHashTableIter iter;
- GHashTable *h = _gendata_hash (NM_SETTING (dup), TRUE)->hash;
+ GHashTable *h = _gendata_hash (dst, TRUE)->hash;
const char *key;
GVariant *val;
@@ -1115,29 +1103,58 @@ nm_setting_duplicate (NMSetting *setting)
guint i;
for (i = 0; i < sett_info->property_infos_len; i++) {
- GParamSpec *prop_spec = sett_info->property_infos[i].param_spec;
+ const NMSettInfoProperty *property_info = &sett_info->property_infos[i];
- if (!prop_spec)
- continue;
- if ((prop_spec->flags & (G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY)) != G_PARAM_WRITABLE)
- continue;
+ if (property_info->param_spec) {
+ if ((property_info->param_spec->flags & (G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY)) != G_PARAM_WRITABLE)
+ continue;
- if (!frozen) {
- g_object_freeze_notify (dup);
- frozen = TRUE;
+ if (!frozen) {
+ g_object_freeze_notify (G_OBJECT (dst));
+ frozen = TRUE;
+ }
+ _gobject_copy_property (G_OBJECT (src),
+ G_OBJECT (dst),
+ property_info->param_spec->name,
+ G_PARAM_SPEC_VALUE_TYPE (property_info->param_spec));
+ continue;
}
-
- _gobject_copy_property (G_OBJECT (setting),
- dup,
- prop_spec->name,
- G_PARAM_SPEC_VALUE_TYPE (prop_spec));
}
if (frozen)
- g_object_thaw_notify (dup);
+ g_object_thaw_notify (G_OBJECT (dst));
}
+}
+
+/**
+ * nm_setting_duplicate:
+ * @setting: the #NMSetting to duplicate
+ *
+ * Duplicates a #NMSetting.
+ *
+ * Returns: (transfer full): a new #NMSetting containing the same properties and values as the
+ * source #NMSetting
+ **/
+NMSetting *
+nm_setting_duplicate (NMSetting *setting)
+{
+ const NMSettInfoSetting *sett_info;
+ NMSettingClass *klass;
+ NMSetting *dst;
+
+ g_return_val_if_fail (NM_IS_SETTING (setting), NULL);
+
+ klass = NM_SETTING_GET_CLASS (setting);
+ nm_assert (NM_IS_SETTING_CLASS (klass));
+ nm_assert (klass->duplicate_copy_properties);
+
+ dst = g_object_new (G_TYPE_FROM_CLASS (klass), NULL);
+
+ sett_info = _nm_setting_class_get_sett_info (klass);
+ nm_assert (sett_info);
- return NM_SETTING (dup);
+ klass->duplicate_copy_properties (sett_info, setting, dst);
+ return dst;
}
/**
@@ -2584,11 +2601,12 @@ nm_setting_class_init (NMSettingClass *setting_class)
object_class->get_property = get_property;
object_class->finalize = finalize;
- setting_class->update_one_secret = update_one_secret;
- setting_class->get_secret_flags = get_secret_flags;
- setting_class->set_secret_flags = set_secret_flags;
- setting_class->compare_property = compare_property;
- setting_class->clear_secrets_with_flags = clear_secrets_with_flags;
+ setting_class->update_one_secret = update_one_secret;
+ setting_class->get_secret_flags = get_secret_flags;
+ setting_class->set_secret_flags = set_secret_flags;
+ setting_class->compare_property = compare_property;
+ setting_class->clear_secrets_with_flags = clear_secrets_with_flags;
+ setting_class->duplicate_copy_properties = duplicate_copy_properties;
/**
* NMSetting:name:
diff --git a/libnm-core/nm-setting.h b/libnm-core/nm-setting.h
index 326b533f12..dfdb6cf177 100644
--- a/libnm-core/nm-setting.h
+++ b/libnm-core/nm-setting.h
@@ -219,10 +219,15 @@ typedef struct {
NMSettingCompareFlags flags);
/*< private >*/
+ void (*duplicate_copy_properties) (const struct _NMSettInfoSetting *sett_info,
+ NMSetting *src,
+ NMSetting *dst);
+
+ /*< private >*/
const struct _NMMetaSettingInfo *setting_info;
/*< private >*/
- gpointer padding[6];
+ gpointer padding[5];
} NMSettingClass;
/**