libnm: add type enum for handling gprop differences in to_dbus_fcn

For GBytes, GEnum, GFlags and others, we need special converters from the
default GObject properties to GVariant.

Previously, those were implemented by providing a special
gprop_to_dbus_fcn hook. But gprop_to_dbus_fcn should move
from NMSettInfoPropertType to NMSettInfoProperty, because it's
usually a per-property meta data, and not a per-property-type meta data.
The difference is whether the meta data can be shared between different
properties (of the same "type).

In these cases, this extra information is indeed part of the type.
We want to have a generic NM_SETT_INFO_PROPERT_TYPE_GPROP() property
(using _nm_setting_property_to_dbus_fcn_gprop()), but then we would like
to distinguish between special cases. So this was fine.

However, I find the approach of providing a gprop_to_dbus_fcn in this
case cumbersome. It makes it harder to understand what happens. Instead,
introduce a new "gprop_type" for the different types that
_nm_setting_property_to_dbus_fcn_gprop() can handle.

This new "gprop_type" is extra data of the property type, so
introduce a new field "typdata_to_dbus".

(cherry picked from commit ac090edd87)
This commit is contained in:
Thomas Haller 2021-06-18 09:43:20 +02:00
parent d2e0a8cc0e
commit 3dfd563601
No known key found for this signature in database
GPG key ID: 29C2366E4DFC5728
3 changed files with 60 additions and 32 deletions

View file

@ -156,25 +156,6 @@ _nm_sett_info_property_find_in_array(const NMSettInfoProperty *properties,
return NULL;
}
static GVariant *
_gprop_to_dbus_fcn_bytes(const GValue *val)
{
nm_assert(G_VALUE_HOLDS(val, G_TYPE_BYTES));
return nm_utils_gbytes_to_variant_ay(g_value_get_boxed(val));
}
static GVariant *
_gprop_to_dbus_fcn_enum(const GValue *val)
{
return g_variant_new_int32(g_value_get_enum(val));
}
static GVariant *
_gprop_to_dbus_fcn_flags(const GValue *val)
{
return g_variant_new_uint32(g_value_get_flags(val));
}
gboolean
_nm_properties_override_assert(const NMSettInfoProperty *prop_info)
{
@ -395,17 +376,17 @@ _nm_setting_class_commit_full(NMSettingClass * setting_class,
else if (vtype == G_TYPE_STRV)
p->property_type = NM_SETT_INFO_PROPERT_TYPE_GPROP(G_VARIANT_TYPE_STRING_ARRAY);
else if (vtype == G_TYPE_BYTES) {
p->property_type =
NM_SETT_INFO_PROPERT_TYPE_GPROP(G_VARIANT_TYPE_BYTESTRING,
.gprop_to_dbus_fcn = _gprop_to_dbus_fcn_bytes);
p->property_type = NM_SETT_INFO_PROPERT_TYPE_GPROP(
G_VARIANT_TYPE_BYTESTRING,
.typdata_to_dbus.gprop_type = NM_SETTING_PROPERTY_TO_DBUS_FCN_GPROP_TYPE_BYTES);
} else if (g_type_is_a(vtype, G_TYPE_ENUM)) {
p->property_type =
NM_SETT_INFO_PROPERT_TYPE_GPROP(G_VARIANT_TYPE_INT32,
.gprop_to_dbus_fcn = _gprop_to_dbus_fcn_enum);
p->property_type = NM_SETT_INFO_PROPERT_TYPE_GPROP(
G_VARIANT_TYPE_INT32,
.typdata_to_dbus.gprop_type = NM_SETTING_PROPERTY_TO_DBUS_FCN_GPROP_TYPE_ENUM);
} else if (g_type_is_a(vtype, G_TYPE_FLAGS)) {
p->property_type =
NM_SETT_INFO_PROPERT_TYPE_GPROP(G_VARIANT_TYPE_UINT32,
.gprop_to_dbus_fcn = _gprop_to_dbus_fcn_flags);
p->property_type = NM_SETT_INFO_PROPERT_TYPE_GPROP(
G_VARIANT_TYPE_UINT32,
.typdata_to_dbus.gprop_type = NM_SETTING_PROPERTY_TO_DBUS_FCN_GPROP_TYPE_FLAGS);
} else
nm_assert_not_reached();
@ -573,10 +554,22 @@ _nm_setting_property_to_dbus_fcn_gprop(const NMSettInfoSetting * s
if (g_param_value_defaults(property->param_spec, &prop_value))
return NULL;
if (property->property_type->gprop_to_dbus_fcn)
return property->property_type->gprop_to_dbus_fcn(&prop_value);
switch (property->property_type->typdata_to_dbus.gprop_type) {
case NM_SETTING_PROPERTY_TO_DBUS_FCN_GPROP_TYPE_DEFAULT:
if (property->property_type->gprop_to_dbus_fcn)
return property->property_type->gprop_to_dbus_fcn(&prop_value);
return g_dbus_gvalue_to_gvariant(&prop_value, property->property_type->dbus_type);
return g_dbus_gvalue_to_gvariant(&prop_value, property->property_type->dbus_type);
case NM_SETTING_PROPERTY_TO_DBUS_FCN_GPROP_TYPE_BYTES:
nm_assert(G_VALUE_HOLDS(&prop_value, G_TYPE_BYTES));
return nm_utils_gbytes_to_variant_ay(g_value_get_boxed(&prop_value));
case NM_SETTING_PROPERTY_TO_DBUS_FCN_GPROP_TYPE_ENUM:
return g_variant_new_int32(g_value_get_enum(&prop_value));
case NM_SETTING_PROPERTY_TO_DBUS_FCN_GPROP_TYPE_FLAGS:
return g_variant_new_uint32(g_value_get_flags(&prop_value));
}
return nm_assert_unreachable_val(NULL);
}
static GVariant *

View file

@ -4373,6 +4373,23 @@ test_setting_metadata(void)
* properties must not have a param_spec and no gprop_to_dbus_fcn. */
g_assert(!sip->param_spec);
g_assert(!sip->property_type->gprop_to_dbus_fcn);
} else if (sip->property_type->to_dbus_fcn == _nm_setting_property_to_dbus_fcn_gprop) {
g_assert(sip->param_spec);
switch (sip->property_type->typdata_to_dbus.gprop_type) {
case NM_SETTING_PROPERTY_TO_DBUS_FCN_GPROP_TYPE_BYTES:
g_assert(sip->param_spec->value_type == G_TYPE_BYTES);
goto check_done;
case NM_SETTING_PROPERTY_TO_DBUS_FCN_GPROP_TYPE_ENUM:
g_assert(g_type_is_a (sip->param_spec->value_type, G_TYPE_ENUM));
goto check_done;
case NM_SETTING_PROPERTY_TO_DBUS_FCN_GPROP_TYPE_FLAGS:
g_assert(g_type_is_a (sip->param_spec->value_type, G_TYPE_FLAGS));
goto check_done;
case NM_SETTING_PROPERTY_TO_DBUS_FCN_GPROP_TYPE_DEFAULT:
goto check_done;
}
g_assert_not_reached();
check_done:;
}
g_assert(!sip->property_type->from_dbus_fcn
@ -4493,7 +4510,11 @@ test_setting_metadata(void)
|| pt->from_dbus_fcn != pt_2->from_dbus_fcn
|| pt->missing_from_dbus_fcn != pt_2->missing_from_dbus_fcn
|| pt->gprop_to_dbus_fcn != pt_2->gprop_to_dbus_fcn
|| pt->gprop_from_dbus_fcn != pt_2->gprop_from_dbus_fcn)
|| pt->gprop_from_dbus_fcn != pt_2->gprop_from_dbus_fcn
|| memcmp(&pt->typdata_to_dbus,
&pt_2->typdata_to_dbus,
sizeof(pt->typdata_to_dbus))
!= 0)
continue;
if ((pt == &nm_sett_info_propert_type_plain_i

View file

@ -671,6 +671,13 @@ typedef void (*NMSettInfoPropGPropFromDBusFcn)(GVariant *from, GValue *to);
const NMSettInfoSetting *nmtst_sett_info_settings(void);
typedef enum _nm_packed {
NM_SETTING_PROPERTY_TO_DBUS_FCN_GPROP_TYPE_DEFAULT = 0,
NM_SETTING_PROPERTY_TO_DBUS_FCN_GPROP_TYPE_BYTES,
NM_SETTING_PROPERTY_TO_DBUS_FCN_GPROP_TYPE_ENUM,
NM_SETTING_PROPERTY_TO_DBUS_FCN_GPROP_TYPE_FLAGS,
} NMSettingPropertyToDBusFcnGPropType;
typedef struct {
const GVariantType *dbus_type;
@ -682,6 +689,13 @@ typedef struct {
* on the GValue value of the GObject property. */
NMSettInfoPropGPropToDBusFcn gprop_to_dbus_fcn;
NMSettInfoPropGPropFromDBusFcn gprop_from_dbus_fcn;
struct {
union {
NMSettingPropertyToDBusFcnGPropType gprop_type;
};
} typdata_to_dbus;
} NMSettInfoPropertType;
struct _NMSettInfoProperty {