summaryrefslogtreecommitdiff
path: root/libnm-core/nm-setting.c
diff options
context:
space:
mode:
Diffstat (limited to 'libnm-core/nm-setting.c')
-rw-r--r--libnm-core/nm-setting.c218
1 files changed, 117 insertions, 101 deletions
diff --git a/libnm-core/nm-setting.c b/libnm-core/nm-setting.c
index 460dafac7d..ba606d5a47 100644
--- a/libnm-core/nm-setting.c
+++ b/libnm-core/nm-setting.c
@@ -22,6 +22,7 @@
#include <string.h>
#include <glib/gi18n.h>
+#include <gio/gio.h>
#include "nm-setting.h"
#include "nm-setting-private.h"
@@ -104,7 +105,6 @@ _ensure_registered (void)
#if !GLIB_CHECK_VERSION (2, 35, 0)
g_type_init ();
#endif
- _nm_value_transforms_register ();
registered_settings = g_hash_table_new (g_str_hash, g_str_equal);
registered_settings_by_type = g_hash_table_new (_nm_gtype_hash, _nm_gtype_equal);
}
@@ -272,31 +272,81 @@ _nm_setting_compare_priority (gconstpointer a, gconstpointer b)
/*************************************************************/
+static const GVariantType *
+variant_type_for_gtype (GType type)
+{
+ if (type == G_TYPE_BOOLEAN)
+ return G_VARIANT_TYPE_BOOLEAN;
+ else if (type == G_TYPE_UCHAR)
+ return G_VARIANT_TYPE_BYTE;
+ else if (type == G_TYPE_INT)
+ return G_VARIANT_TYPE_INT32;
+ else if (type == G_TYPE_UINT)
+ return G_VARIANT_TYPE_UINT32;
+ else if (type == G_TYPE_STRING)
+ return G_VARIANT_TYPE_STRING;
+ else if (type == G_TYPE_DOUBLE)
+ return G_VARIANT_TYPE_DOUBLE;
+ else
+ g_assert_not_reached ();
+}
+
+static GVariant *
+get_property_for_dbus (NMSetting *setting, GParamSpec *prop_spec, gboolean ignore_default)
+{
+ GValue prop_value = { 0, };
+ GVariant *dbus_value;
+
+ g_value_init (&prop_value, prop_spec->value_type);
+ g_object_get_property (G_OBJECT (setting), prop_spec->name, &prop_value);
+
+ if (ignore_default && g_param_value_defaults (prop_spec, &prop_value)) {
+ g_value_unset (&prop_value);
+ return NULL;
+ }
+
+ if (NM_IS_PARAM_SPEC_DBUS (prop_spec))
+ dbus_value = _nm_param_spec_dbus_value_to_dbus (NM_PARAM_SPEC_DBUS (prop_spec), &prop_value);
+ else
+ dbus_value = g_dbus_gvalue_to_gvariant (&prop_value, variant_type_for_gtype (prop_value.g_type));
+
+ g_value_unset (&prop_value);
+ return dbus_value;
+}
+
static void
-destroy_gvalue (gpointer data)
+set_property_from_dbus (NMSetting *setting, GParamSpec *prop_spec, GVariant *dbus_value)
{
- GValue *value = (GValue *) data;
+ GValue prop_value = { 0, };
+
+ g_value_init (&prop_value, prop_spec->value_type);
+ if (NM_IS_PARAM_SPEC_DBUS (prop_spec)) {
+ _nm_param_spec_dbus_value_from_dbus (NM_PARAM_SPEC_DBUS (prop_spec),
+ dbus_value, &prop_value);
+ } else
+ g_dbus_gvariant_to_gvalue (dbus_value, &prop_value);
- g_value_unset (value);
- g_slice_free (GValue, value);
+ g_object_set_property (G_OBJECT (setting), prop_spec->name, &prop_value);
+ g_value_unset (&prop_value);
}
/**
- * nm_setting_to_hash:
+ * nm_setting_to_variant:
* @setting: the #NMSetting
* @flags: hash flags, e.g. %NM_SETTING_HASH_FLAG_ALL
*
- * Converts the #NMSetting into a #GHashTable mapping each setting property
- * name to a GValue describing that property, suitable for marshalling over
- * D-Bus or serializing. The mapping is string to GValue.
+ * Converts the #NMSetting into a #GVariant of type #NM_VARIANT_TYPE_SETTING
+ * (`a{sv}`), mapping each setting property name to a value describing that
+ * property, suitable for marshalling over D-Bus or serializing.
*
- * Returns: (transfer full) (element-type utf8 GObject.Value): a new #GHashTable
- * describing the setting's properties
+ * Returns: (transfer none): a new floating #GVariant describing the setting's
+ * properties
**/
-GHashTable *
-nm_setting_to_hash (NMSetting *setting, NMSettingHashFlags flags)
+GVariant *
+nm_setting_to_variant (NMSetting *setting, NMSettingHashFlags flags)
{
- GHashTable *hash;
+ GVariantBuilder builder;
+ GVariant *dbus_value, *ret;
GParamSpec **property_specs;
guint n_property_specs;
guint i;
@@ -310,12 +360,10 @@ nm_setting_to_hash (NMSetting *setting, NMSettingHashFlags flags)
return NULL;
}
- hash = g_hash_table_new_full (g_str_hash, g_str_equal,
- (GDestroyNotify) g_free, destroy_gvalue);
+ g_variant_builder_init (&builder, NM_VARIANT_TYPE_SETTING);
for (i = 0; i < n_property_specs; i++) {
GParamSpec *prop_spec = property_specs[i];
- GValue *value;
/* Don't serialize properties that can't be deserialized */
if ( !(prop_spec->flags & G_PARAM_WRITABLE)
@@ -325,60 +373,46 @@ nm_setting_to_hash (NMSetting *setting, NMSettingHashFlags flags)
if ( (flags & NM_SETTING_HASH_FLAG_NO_SECRETS)
&& (prop_spec->flags & NM_SETTING_PARAM_SECRET))
continue;
+
if ( (flags & NM_SETTING_HASH_FLAG_ONLY_SECRETS)
&& !(prop_spec->flags & NM_SETTING_PARAM_SECRET))
continue;
- value = g_slice_new0 (GValue);
- g_value_init (value, prop_spec->value_type);
- g_object_get_property (G_OBJECT (setting), prop_spec->name, value);
-
- /* Don't serialize values with default values */
- if (g_param_value_defaults (prop_spec, value)) {
- destroy_gvalue (value);
- continue;
- }
-
- if (NM_IS_PARAM_SPEC_DBUS (prop_spec)) {
- GValue *dbus_value = g_slice_new0 (GValue);
-
- _nm_param_spec_dbus_value_to_dbus (NM_PARAM_SPEC_DBUS (prop_spec),
- value, dbus_value);
- destroy_gvalue (value);
- value = dbus_value;
- }
-
- g_hash_table_insert (hash, g_strdup (prop_spec->name), value);
+ dbus_value = get_property_for_dbus (setting, prop_spec, TRUE);
+ if (dbus_value)
+ g_variant_builder_add (&builder, "{sv}", prop_spec->name, dbus_value);
}
g_free (property_specs);
+ ret = g_variant_builder_end (&builder);
+
/* Don't return empty hashes, except for base types */
- if (g_hash_table_size (hash) < 1 && !_nm_setting_is_base_type (setting)) {
- g_hash_table_destroy (hash);
- hash = NULL;
+ if (g_variant_n_children (ret) < 1 && !_nm_setting_is_base_type (setting)) {
+ g_variant_unref (ret);
+ ret = NULL;
}
- return hash;
+ return ret;
}
/**
- * nm_setting_new_from_hash:
+ * nm_setting_new_from_variant:
* @setting_type: the #NMSetting type which the hash contains properties for
- * @hash: (element-type utf8 GObject.Value): the #GHashTable containing a
- * string to GValue mapping of properties that apply to the setting
+ * @variant: the #GVariant containing an %NM_VARIANT_TYPE_SETTING dictionary mapping
+ * property names to values
*
* Creates a new #NMSetting object and populates that object with the properties
- * contained in the hash table, using each hash key as the property to set,
- * and each hash value as the value to set that property to. Setting properties
- * are strongly typed, thus the GValue type of the hash value must be correct.
- * See the documentation on each #NMSetting object subclass for the correct
- * property names and value types.
+ * contained in the vardict, using each key as the property to set, and each
+ * value as the value to set that property to. Setting properties are strongly
+ * typed, thus the #GVariantType of the dict value must be correct. See the
+ * documentation on each #NMSetting object subclass for the correct property
+ * names and value types.
*
* Returns: a new #NMSetting object populated with the properties from the
* hash table, or %NULL on failure
**/
NMSetting *
-nm_setting_new_from_hash (GType setting_type, GHashTable *hash)
+nm_setting_new_from_variant (GType setting_type, GVariant *variant)
{
NMSetting *setting;
GObjectClass *class;
@@ -387,7 +421,7 @@ nm_setting_new_from_hash (GType setting_type, GHashTable *hash)
int i;
g_return_val_if_fail (G_TYPE_IS_INSTANTIATABLE (setting_type), NULL);
- g_return_val_if_fail (hash != NULL, NULL);
+ g_return_val_if_fail (g_variant_is_of_type (variant, NM_VARIANT_TYPE_SETTING), NULL);
class = g_type_class_ref (setting_type);
property_specs = g_object_class_list_properties (class, &n_property_specs);
@@ -403,26 +437,18 @@ nm_setting_new_from_hash (GType setting_type, GHashTable *hash)
for (i = 0; i < n_property_specs; i++) {
GParamSpec *prop_spec = property_specs[i];
- GValue *value;
+ GVariant *value;
if ( !(prop_spec->flags & G_PARAM_WRITABLE)
|| (prop_spec->flags & G_PARAM_CONSTRUCT_ONLY))
continue;
- value = g_hash_table_lookup (hash, prop_spec->name);
+ value = g_variant_lookup_value (variant, prop_spec->name, NULL);
if (!value)
continue;
- if (NM_IS_PARAM_SPEC_DBUS (prop_spec)) {
- GValue prop_value = { 0, };
-
- g_value_init (&prop_value, prop_spec->value_type);
- _nm_param_spec_dbus_value_from_dbus (NM_PARAM_SPEC_DBUS (prop_spec),
- value, &prop_value);
- g_object_set_property (G_OBJECT (setting), prop_spec->name, &prop_value);
- g_value_unset (&prop_value);
- } else
- g_object_set_property (G_OBJECT (setting), prop_spec->name, value);
+ set_property_from_dbus (setting, prop_spec, value);
+ g_variant_unref (value);
}
return setting;
@@ -977,10 +1003,9 @@ nm_setting_need_secrets (NMSetting *setting)
}
static int
-update_one_secret (NMSetting *setting, const char *key, GValue *value, GError **error)
+update_one_secret (NMSetting *setting, const char *key, GVariant *value, GError **error)
{
GParamSpec *prop_spec;
- GValue transformed_value = G_VALUE_INIT;
prop_spec = g_object_class_find_property (G_OBJECT_GET_CLASS (setting), key);
if (!prop_spec) {
@@ -995,76 +1020,67 @@ update_one_secret (NMSetting *setting, const char *key, GValue *value, GError **
if (!(prop_spec->flags & NM_SETTING_PARAM_SECRET))
return NM_SETTING_UPDATE_SECRET_SUCCESS_UNCHANGED;
- if (g_value_type_compatible (G_VALUE_TYPE (value), G_PARAM_SPEC_VALUE_TYPE (prop_spec))) {
- if (G_VALUE_HOLDS_STRING (value) && G_IS_PARAM_SPEC_STRING (prop_spec)) {
- /* String is expected to be a common case. Handle it specially and check whether
- * the value is already set. Otherwise, we just reset the property and
- * assume the value got modified. */
- char *v;
-
- g_object_get (G_OBJECT (setting), prop_spec->name, &v, NULL);
- if (g_strcmp0 (v, g_value_get_string (value)) == 0) {
- g_free (v);
- return NM_SETTING_UPDATE_SECRET_SUCCESS_UNCHANGED;
- }
+ if ( g_variant_is_of_type (value, G_VARIANT_TYPE_STRING)
+ && G_IS_PARAM_SPEC_STRING (prop_spec)) {
+ /* String is expected to be a common case. Handle it specially and check
+ * whether the value is already set. Otherwise, we just reset the
+ * property and assume the value got modified.
+ */
+ char *v;
+
+ g_object_get (G_OBJECT (setting), prop_spec->name, &v, NULL);
+ if (g_strcmp0 (v, g_variant_get_string (value, NULL)) == 0) {
g_free (v);
+ return NM_SETTING_UPDATE_SECRET_SUCCESS_UNCHANGED;
}
- g_object_set_property (G_OBJECT (setting), prop_spec->name, value);
- return NM_SETTING_UPDATE_SECRET_SUCCESS_MODIFIED;
+ g_free (v);
}
- if (g_value_transform (value, &transformed_value)) {
- g_object_set_property (G_OBJECT (setting), prop_spec->name, &transformed_value);
- g_value_unset (&transformed_value);
- return NM_SETTING_UPDATE_SECRET_SUCCESS_MODIFIED;
- }
- g_set_error (error,
- NM_SETTING_ERROR,
- NM_SETTING_ERROR_PROPERTY_TYPE_MISMATCH,
- "%s", key);
- return NM_SETTING_UPDATE_SECRET_ERROR;
+
+ set_property_from_dbus (setting, prop_spec, value);
+ return NM_SETTING_UPDATE_SECRET_SUCCESS_MODIFIED;
}
/**
* nm_setting_update_secrets:
* @setting: the #NMSetting
- * @secrets: (element-type utf8 GObject.Value): a #GHashTable mapping
- * string to #GValue of setting property names and secrets
+ * @secrets: a vardict mapping property names to secrets
* @error: location to store error, or %NULL
*
- * Update the setting's secrets, given a hash table of secrets intended for that
+ * Update the setting's secrets, given a vardict of secrets intended for that
* setting (deserialized from D-Bus for example).
*
* Returns: %TRUE if the secrets were successfully updated, %FALSE on failure to
* update one or more of the secrets.
**/
gboolean
-nm_setting_update_secrets (NMSetting *setting, GHashTable *secrets, GError **error)
+nm_setting_update_secrets (NMSetting *setting, GVariant *secrets, GError **error)
{
return _nm_setting_update_secrets (setting, secrets, error) != NM_SETTING_UPDATE_SECRET_ERROR;
}
NMSettingUpdateSecretResult
-_nm_setting_update_secrets (NMSetting *setting, GHashTable *secrets, GError **error)
+_nm_setting_update_secrets (NMSetting *setting, GVariant *secrets, GError **error)
{
- GHashTableIter iter;
- gpointer key, data;
+ GVariantIter iter;
+ const char *secret_key;
+ GVariant *secret_value;
GError *tmp_error = NULL;
NMSettingUpdateSecretResult result = NM_SETTING_UPDATE_SECRET_SUCCESS_UNCHANGED;
g_return_val_if_fail (NM_IS_SETTING (setting), NM_SETTING_UPDATE_SECRET_ERROR);
- g_return_val_if_fail (secrets != NULL, NM_SETTING_UPDATE_SECRET_ERROR);
+ g_return_val_if_fail (g_variant_is_of_type (secrets, NM_VARIANT_TYPE_SETTING), NM_SETTING_UPDATE_SECRET_ERROR);
if (error)
g_return_val_if_fail (*error == NULL, NM_SETTING_UPDATE_SECRET_ERROR);
- g_hash_table_iter_init (&iter, secrets);
- while (g_hash_table_iter_next (&iter, &key, &data)) {
+ g_variant_iter_init (&iter, secrets);
+ while (g_variant_iter_next (&iter, "{&sv}", &secret_key, &secret_value)) {
int success;
- const char *secret_key = (const char *) key;
- GValue *secret_value = (GValue *) data;
success = NM_SETTING_GET_CLASS (setting)->update_one_secret (setting, secret_key, secret_value, &tmp_error);
g_assert (!((success == NM_SETTING_UPDATE_SECRET_ERROR) ^ (!!tmp_error)));
+ g_variant_unref (secret_value);
+
if (success == NM_SETTING_UPDATE_SECRET_ERROR) {
g_propagate_error (error, tmp_error);
return NM_SETTING_UPDATE_SECRET_ERROR;