libnm-util: convert nm_setting_new_from_hash() to GHashTableIter

This commit is contained in:
Dan Williams
2013-03-26 17:50:09 -05:00
parent a8d33c7e2c
commit 6c7c2b874d
2 changed files with 58 additions and 44 deletions

View File

@@ -152,39 +152,6 @@ nm_setting_to_hash (NMSetting *setting, NMSettingHashFlags flags)
return hash;
}
typedef struct {
GObjectClass *class;
guint n_params;
GParameter *params;
} NMSettingFromHashInfo;
static void
one_property_cb (gpointer key, gpointer val, gpointer user_data)
{
const char *prop_name = (char *) key;
GValue *src_value = (GValue *) val;
NMSettingFromHashInfo *info = (NMSettingFromHashInfo *) user_data;
GValue *dst_value = &info->params[info->n_params].value;
GParamSpec *param_spec;
param_spec = g_object_class_find_property (info->class, prop_name);
if (!param_spec || !(param_spec->flags & NM_SETTING_PARAM_SERIALIZE)) {
/* Oh, we're so nice and only warn, maybe it should be a fatal error? */
g_warning ("Ignoring invalid property '%s'", prop_name);
return;
}
g_value_init (dst_value, G_VALUE_TYPE (src_value));
if (g_value_transform (src_value, dst_value)) {
info->params[info->n_params].name = prop_name;
info->n_params++;
} else {
g_warning ("Ignoring property '%s' with invalid type (%s)",
prop_name, G_VALUE_TYPE_NAME (src_value));
g_value_unset (dst_value);
}
}
/**
* nm_setting_new_from_hash:
* @setting_type: the #NMSetting type which the hash contains properties for
@@ -204,28 +171,53 @@ one_property_cb (gpointer key, gpointer val, gpointer user_data)
NMSetting *
nm_setting_new_from_hash (GType setting_type, GHashTable *hash)
{
GHashTableIter iter;
NMSetting *setting;
NMSettingFromHashInfo info;
const char *prop_name;
GValue *src_value;
GObjectClass *class;
guint n_params = 0;
GParameter *params;
int i;
g_return_val_if_fail (G_TYPE_IS_INSTANTIATABLE (setting_type), NULL);
g_return_val_if_fail (hash != NULL, NULL);
info.class = g_type_class_ref (setting_type);
info.n_params = 0;
info.params = g_new0 (GParameter, g_hash_table_size (hash));
/* g_type_class_ref() ensures the setting class is created if it hasn't
* already been used.
*/
class = g_type_class_ref (setting_type);
params = g_new0 (GParameter, g_hash_table_size (hash));
g_hash_table_foreach (hash, one_property_cb, &info);
g_hash_table_iter_init (&iter, hash);
while (g_hash_table_iter_next (&iter, (gpointer) &prop_name, (gpointer) &src_value)) {
GValue *dst_value = &params[n_params].value;
GParamSpec *param_spec;
setting = (NMSetting *) g_object_newv (setting_type, info.n_params, info.params);
param_spec = g_object_class_find_property (class, prop_name);
if (!param_spec || !(param_spec->flags & NM_SETTING_PARAM_SERIALIZE)) {
/* Oh, we're so nice and only warn, maybe it should be a fatal error? */
g_warning ("Ignoring invalid property '%s'", prop_name);
continue;
}
for (i = 0; i < info.n_params; i++) {
GValue *v = &info.params[i].value;
g_value_unset (v);
g_value_init (dst_value, G_VALUE_TYPE (src_value));
if (g_value_transform (src_value, dst_value))
params[n_params++].name = prop_name;
else {
g_warning ("Ignoring property '%s' with invalid type (%s)",
prop_name, G_VALUE_TYPE_NAME (src_value));
g_value_unset (dst_value);
}
}
g_free (info.params);
g_type_class_unref (info.class);
setting = (NMSetting *) g_object_newv (setting_type, n_params, params);
for (i = 0; i < n_params; i++)
g_value_unset (&params[i].value);
g_free (params);
g_type_class_unref (class);
return setting;
}

View File

@@ -584,6 +584,26 @@ test_connection_to_hash_setting_name (void)
g_object_unref (connection);
}
static void
test_setting_new_from_hash (void)
{
NMSettingWirelessSecurity *s_wsec;
GHashTable *hash;
s_wsec = make_test_wsec_setting ("setting-to-hash-all");
hash = nm_setting_to_hash (NM_SETTING (s_wsec), NM_SETTING_HASH_FLAG_ALL);
g_object_unref (s_wsec);
s_wsec = (NMSettingWirelessSecurity *) nm_setting_new_from_hash (NM_TYPE_SETTING_WIRELESS_SECURITY, hash);
g_hash_table_destroy (hash);
g_assert (s_wsec);
g_assert_cmpstr (nm_setting_wireless_security_get_key_mgmt (s_wsec), ==, "wpa-psk");
g_assert_cmpstr (nm_setting_wireless_security_get_leap_username (s_wsec), ==, "foobarbaz");
g_assert_cmpstr (nm_setting_wireless_security_get_psk (s_wsec), ==, "random psk");
g_object_unref (s_wsec);
}
static void
check_permission (NMSettingConnection *s_con,
guint32 idx,
@@ -1476,6 +1496,8 @@ int main (int argc, char **argv)
test_setting_compare_vpn_secrets (NM_SETTING_SECRET_FLAG_NONE, NM_SETTING_COMPARE_FLAG_EXACT, FALSE);
test_connection_to_hash_setting_name ();
test_setting_new_from_hash ();
test_setting_connection_permissions_helpers ();
test_setting_connection_permissions_property ();