From 69db8a462a0f7f5d3fcfc0a4ecc2502a76fbe48d Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Mon, 28 Jun 2021 20:48:40 +0200 Subject: [PATCH] libnm: add generic GObject property getter/setter If we only have simple, direct properties, then we have all the information we need for a generic get_property()/set_property() implmenentation. --- src/libnm-core-impl/nm-setting-6lowpan.c | 39 +-------- src/libnm-core-impl/nm-setting-private.h | 10 +++ src/libnm-core-impl/nm-setting.c | 107 +++++++++++++++++++++++ 3 files changed, 119 insertions(+), 37 deletions(-) diff --git a/src/libnm-core-impl/nm-setting-6lowpan.c b/src/libnm-core-impl/nm-setting-6lowpan.c index 1fc2a2d4a9..c7f1aca66e 100644 --- a/src/libnm-core-impl/nm-setting-6lowpan.c +++ b/src/libnm-core-impl/nm-setting-6lowpan.c @@ -128,41 +128,6 @@ verify(NMSetting *setting, NMConnection *connection, GError **error) /*****************************************************************************/ -static void -get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) -{ - NMSetting6Lowpan * setting = NM_SETTING_6LOWPAN(object); - NMSetting6LowpanPrivate *priv = NM_SETTING_6LOWPAN_GET_PRIVATE(setting); - - switch (prop_id) { - case PROP_PARENT: - g_value_set_string(value, priv->parent); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); - break; - } -} - -static void -set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) -{ - NMSetting6Lowpan * setting = NM_SETTING_6LOWPAN(object); - NMSetting6LowpanPrivate *priv = NM_SETTING_6LOWPAN_GET_PRIVATE(setting); - - switch (prop_id) { - case PROP_PARENT: - g_free(priv->parent); - priv->parent = g_value_dup_string(value); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); - break; - } -} - -/*****************************************************************************/ - static void nm_setting_6lowpan_init(NMSetting6Lowpan *setting) {} @@ -202,8 +167,8 @@ nm_setting_6lowpan_class_init(NMSetting6LowpanClass *klass) g_type_class_add_private(klass, sizeof(NMSetting6LowpanPrivate)); - object_class->get_property = get_property; - object_class->set_property = set_property; + object_class->get_property = _nm_setting_property_get_property_direct; + object_class->set_property = _nm_setting_property_set_property_direct; object_class->finalize = finalize; setting_class->verify = verify; diff --git a/src/libnm-core-impl/nm-setting-private.h b/src/libnm-core-impl/nm-setting-private.h index 39e5992126..e35543e170 100644 --- a/src/libnm-core-impl/nm-setting-private.h +++ b/src/libnm-core-impl/nm-setting-private.h @@ -301,6 +301,16 @@ gboolean _nm_setting_aggregate(NMSetting *setting, NMConnectionAggregateType typ gboolean _nm_setting_slave_type_is_valid(const char *slave_type, const char **out_port_type); +void _nm_setting_property_get_property_direct(GObject * object, + guint prop_id, + GValue * value, + GParamSpec *pspec); + +void _nm_setting_property_set_property_direct(GObject * object, + guint prop_id, + const GValue *value, + GParamSpec * pspec); + GVariant *_nm_setting_property_to_dbus_fcn_gprop(const NMSettInfoSetting * sett_info, guint property_idx, NMConnection * connection, diff --git a/src/libnm-core-impl/nm-setting.c b/src/libnm-core-impl/nm-setting.c index eef2a30d5c..faad3bcae6 100644 --- a/src/libnm-core-impl/nm-setting.c +++ b/src/libnm-core-impl/nm-setting.c @@ -623,6 +623,113 @@ _nm_setting_use_legacy_property(NMSetting * setting, /*****************************************************************************/ +void +_nm_setting_property_get_property_direct(GObject * object, + guint prop_id, + GValue * value, + GParamSpec *pspec) +{ + NMSetting * setting = NM_SETTING(object); + const NMSettInfoSetting * sett_info; + const NMSettInfoProperty *property_info; + + sett_info = _nm_setting_class_get_sett_info(NM_SETTING_GET_CLASS(setting)); + nm_assert(sett_info); + + property_info = _nm_sett_info_property_lookup_by_param_spec(sett_info, pspec); + if (!property_info) + goto out_fail; + + nm_assert(property_info->param_spec == pspec); + + switch (property_info->property_type->direct_type) { + case NM_VALUE_TYPE_BOOL: + { + const bool *p_val = + _nm_setting_get_private(setting, sett_info, property_info->direct_offset); + + g_value_set_boolean(value, *p_val); + return; + } + case NM_VALUE_TYPE_STRING: + { + const char *const *p_val = + _nm_setting_get_private(setting, sett_info, property_info->direct_offset); + + g_value_set_string(value, *p_val); + return; + } + default: + goto out_fail; + } + + return; + +out_fail: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); +} + +void +_nm_setting_property_set_property_direct(GObject * object, + guint prop_id, + const GValue *value, + GParamSpec * pspec) +{ + NMSetting * setting = NM_SETTING(object); + const NMSettInfoSetting * sett_info; + const NMSettInfoProperty *property_info; + + sett_info = _nm_setting_class_get_sett_info(NM_SETTING_GET_CLASS(setting)); + nm_assert(sett_info); + + property_info = _nm_sett_info_property_lookup_by_param_spec(sett_info, pspec); + if (!property_info) + goto out_fail; + + nm_assert(property_info->param_spec == pspec); + + /* properties with special setters are not yet implemented! */ + nm_assert(!property_info->direct_has_special_setter); + + switch (property_info->property_type->direct_type) { + case NM_VALUE_TYPE_BOOL: + { + bool * p_val = _nm_setting_get_private(setting, sett_info, property_info->direct_offset); + gboolean v; + + v = g_value_get_boolean(value); + if (*p_val == v) + return; + *p_val = v; + goto out_notify; + } + case NM_VALUE_TYPE_STRING: + { + char **p_val = _nm_setting_get_private(setting, sett_info, property_info->direct_offset); + + if (!nm_utils_strdup_reset(p_val, g_value_get_string(value))) + return; + goto out_notify; + } + default: + goto out_fail; + } + + return; + +out_notify: + /* If explicit-notify would be set, we would need to emit g_object_notify_by_pspec(). + * + * Currently we never set that, also because we still support glib 2.40. */ + nm_assert(!NM_FLAGS_HAS(pspec->flags, 1 << 30 /* G_PARAM_EXPLICIT_NOTIFY */)); + return; + +out_fail: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); +} + +/*****************************************************************************/ + GVariant * _nm_setting_property_to_dbus_fcn_direct(const NMSettInfoSetting * sett_info, guint property_idx,