diff options
author | Thomas Haller <thaller@redhat.com> | 2019-01-11 15:16:33 +0100 |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2019-01-22 16:30:23 +0100 |
commit | 3a915a020533189788b435032a1cc24b58cfab0e (patch) | |
tree | 2e3cfd14ece5e7695b40ca5ee52cfbc04c1aacf1 | |
parent | f5a86dee43256efc49ccfa79bcda1d5c6a6f670e (diff) | |
download | NetworkManager-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.c | 114 | ||||
-rw-r--r-- | libnm-core/nm-setting.h | 7 |
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; /** |