From 97d1ed153c08211d1ab4b0d52053d03e65f02c92 Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Thu, 14 Nov 2013 16:12:17 +0000 Subject: [PATCH 20/26] Thread expected GVariant types through to mcd_storage_get_* We're going to need this soon, in order to advise plugins how best to unescape the value. The result is still a GValue, for now. --- src/mcd-account-addressing.c | 4 +-- src/mcd-account-manager-default.c | 4 +-- src/mcd-account-manager.c | 8 ++++-- src/mcd-account.c | 60 ++++++++++++++++++++++++++++++--------- src/mcd-account.h | 1 + src/mcd-storage.c | 31 +++++++++++++------- src/mcd-storage.h | 7 +++-- 7 files changed, 82 insertions(+), 33 deletions(-) diff --git a/src/mcd-account-addressing.c b/src/mcd-account-addressing.c index ec3d8f5..c9740c7 100644 --- a/src/mcd-account-addressing.c +++ b/src/mcd-account-addressing.c @@ -48,7 +48,7 @@ addressing_set_uri_scheme_association (TpSvcAccountInterfaceAddressing *iface, g_value_init (&value, G_TYPE_STRV); if (mcd_storage_get_attribute (storage, account, MC_ACCOUNTS_KEY_URI_SCHEMES, - &value, NULL)) + G_VARIANT_TYPE_STRING_ARRAY, &value, NULL)) { schemes = g_value_get_boxed (&value); old_association = tp_strv_contains ((const gchar * const *) schemes, @@ -109,7 +109,7 @@ addressing_get_uri_schemes (TpSvcDBusProperties *iface, g_value_init (value, G_TYPE_STRV); if (!mcd_storage_get_attribute (storage, account, MC_ACCOUNTS_KEY_URI_SCHEMES, - value, NULL)) + G_VARIANT_TYPE_STRING_ARRAY, value, NULL)) { g_value_set_boxed (value, NULL); } diff --git a/src/mcd-account-manager-default.c b/src/mcd-account-manager-default.c index e04f408..1ceb90b 100644 --- a/src/mcd-account-manager-default.c +++ b/src/mcd-account-manager-default.c @@ -666,7 +666,7 @@ am_default_load_keyfile (McdAccountManagerDefault *self, } else { - const gchar *type = mcd_storage_get_attribute_type (key); + const GVariantType *type = mcd_storage_get_attribute_type (key); GVariant *variant = NULL; if (type == NULL) @@ -678,7 +678,7 @@ am_default_load_keyfile (McdAccountManagerDefault *self, else { variant = mcd_keyfile_get_variant (keyfile, - account, key, G_VARIANT_TYPE (type), &error); + account, key, type, &error); } if (variant == NULL) diff --git a/src/mcd-account-manager.c b/src/mcd-account-manager.c index d97bafa..9f05afd 100644 --- a/src/mcd-account-manager.c +++ b/src/mcd-account-manager.c @@ -1207,7 +1207,9 @@ migrate_butterfly_haze_ready (McdManager *manager, /* Parameters; the only mandatory one is 'account' */ if (!mcd_account_get_parameter_of_known_type (ctx->account, - "account", G_TYPE_STRING, + "account", + G_VARIANT_TYPE_STRING, + G_TYPE_STRING, &v, NULL)) { _mcd_account_set_enabled (ctx->account, FALSE, TRUE, @@ -1221,7 +1223,9 @@ migrate_butterfly_haze_ready (McdManager *manager, /* If MC is storing the password, let's copy that too, so Empathy * can migrate it somewhere better. */ if (mcd_account_get_parameter_of_known_type (ctx->account, - "password", G_TYPE_STRING, + "password", + G_VARIANT_TYPE_STRING, + G_TYPE_STRING, &password_v, NULL)) { g_hash_table_insert (parameters, "password", &password_v); diff --git a/src/mcd-account.c b/src/mcd-account.c index 620487f..9d84732 100644 --- a/src/mcd-account.c +++ b/src/mcd-account.c @@ -382,7 +382,8 @@ _mcd_account_set_parameter (McdAccount *account, const gchar *name, mcd_storage_set_parameter (storage, account_name, name, value); } -static GType mc_param_type (const TpConnectionManagerParam *param); +static GType mc_param_type (const TpConnectionManagerParam *param, + const GVariantType **variant_type_out); /** * mcd_account_get_parameter: @@ -405,18 +406,22 @@ mcd_account_get_parameter (McdAccount *account, const gchar *name, McdAccountPrivate *priv = account->priv; const TpConnectionManagerParam *param; GType type; + const GVariantType *variant_type; + gboolean ret; param = mcd_manager_get_protocol_param (priv->manager, priv->protocol_name, name); - type = mc_param_type (param); + type = mc_param_type (param, &variant_type); - return mcd_account_get_parameter_of_known_type (account, name, - type, parameter, error); + ret = mcd_account_get_parameter_of_known_type (account, name, + variant_type, type, parameter, error); + return ret; } gboolean mcd_account_get_parameter_of_known_type (McdAccount *account, const gchar *name, + const GVariantType *variant_type, GType type, GValue *parameter, GError **error) @@ -427,7 +432,8 @@ mcd_account_get_parameter_of_known_type (McdAccount *account, g_value_init (&tmp, type); - if (mcd_storage_get_parameter (storage, account_name, name, &tmp, error)) + if (mcd_storage_get_parameter (storage, account_name, name, variant_type, + &tmp, error)) { if (parameter != NULL) { @@ -1090,7 +1096,8 @@ mcd_account_get_string_val (McdAccount *account, const gchar *key, g_value_init (value, G_TYPE_STRING); - if (!mcd_storage_get_attribute (priv->storage, name, key, value, NULL)) + if (!mcd_storage_get_attribute (priv->storage, name, key, + G_VARIANT_TYPE_STRING, value, NULL)) { g_value_set_static_string (value, NULL); } @@ -2375,10 +2382,13 @@ properties_iface_init (TpSvcDBusPropertiesClass *iface, gpointer iface_data) } static GType -mc_param_type (const TpConnectionManagerParam *param) +mc_param_type (const TpConnectionManagerParam *param, + const GVariantType **variant_type_out) { const gchar *dbus_signature; + *variant_type_out = NULL; + if (G_UNLIKELY (param == NULL)) return G_TYPE_INVALID; @@ -2390,37 +2400,49 @@ mc_param_type (const TpConnectionManagerParam *param) switch (dbus_signature[0]) { case DBUS_TYPE_STRING: + *variant_type_out = G_VARIANT_TYPE_STRING; return G_TYPE_STRING; case DBUS_TYPE_BYTE: + *variant_type_out = G_VARIANT_TYPE_BYTE; return G_TYPE_UCHAR; case DBUS_TYPE_INT16: case DBUS_TYPE_INT32: + *variant_type_out = G_VARIANT_TYPE_INT32; return G_TYPE_INT; case DBUS_TYPE_UINT16: case DBUS_TYPE_UINT32: + *variant_type_out = G_VARIANT_TYPE_UINT32; return G_TYPE_UINT; case DBUS_TYPE_BOOLEAN: + *variant_type_out = G_VARIANT_TYPE_BOOLEAN; return G_TYPE_BOOLEAN; case DBUS_TYPE_DOUBLE: + *variant_type_out = G_VARIANT_TYPE_DOUBLE; return G_TYPE_DOUBLE; case DBUS_TYPE_OBJECT_PATH: + *variant_type_out = G_VARIANT_TYPE_OBJECT_PATH; return DBUS_TYPE_G_OBJECT_PATH; case DBUS_TYPE_INT64: + *variant_type_out = G_VARIANT_TYPE_INT64; return G_TYPE_INT64; case DBUS_TYPE_UINT64: + *variant_type_out = G_VARIANT_TYPE_UINT64; return G_TYPE_UINT64; case DBUS_TYPE_ARRAY: if (dbus_signature[1] == DBUS_TYPE_STRING) + { + *variant_type_out = G_VARIANT_TYPE_STRING_ARRAY; return G_TYPE_STRV; + } /* other array types are not supported: * fall through the default case */ default: @@ -2497,11 +2519,13 @@ mcd_account_altered_by_plugin (McdAccount *account, const McdDBusProp *prop = NULL; GValue value = G_VALUE_INIT; GError *error = NULL; + const GVariantType *variant_type = NULL; DEBUG ("%s", name); if (tp_strdiff (name, "Parameters") && - !mcd_storage_init_value_for_attribute (&value, name)) + !mcd_storage_init_value_for_attribute (&value, name, + &variant_type)) { WARNING ("plugin wants to alter %s but I don't know what " "type that ought to be", name); @@ -2514,7 +2538,8 @@ mcd_account_altered_by_plugin (McdAccount *account, } else if (!mcd_storage_get_attribute (account->priv->storage, account->priv->unique_name, - name, &value, &error)) + name, variant_type, &value, + &error)) { WARNING ("cannot get new value of %s: %s", name, error->message); g_error_free (error); @@ -2703,6 +2728,7 @@ check_one_parameter_update (McdAccount *account, const TpConnectionManagerParam *param = tp_protocol_get_param (protocol, name); GType type; + const GVariantType *variant_type; if (param == NULL) { @@ -2712,15 +2738,18 @@ check_one_parameter_update (McdAccount *account, return FALSE; } - type = mc_param_type (param); + type = mc_param_type (param, &variant_type); if (G_VALUE_TYPE (new_value) != type) { /* FIXME: use D-Bus type names, not GType names. */ g_set_error (error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, - "parameter '%s' must be of type %s, not %s", + "parameter '%s' must be of type %s ('%.*s'), not %s", tp_connection_manager_param_get_name (param), - g_type_name (type), G_VALUE_TYPE_NAME (new_value)); + g_type_name (type), + (int) g_variant_type_get_string_length (variant_type), + g_variant_type_peek_string (variant_type), + G_VALUE_TYPE_NAME (new_value)); return FALSE; } @@ -3305,7 +3334,8 @@ mcd_account_setup (McdAccount *account) g_free (priv->auto_presence_message); if (mcd_storage_get_attribute (storage, name, - MC_ACCOUNTS_KEY_AUTOMATIC_PRESENCE, &value, + MC_ACCOUNTS_KEY_AUTOMATIC_PRESENCE, + G_VARIANT_TYPE ("(uss)"), &value, NULL)) { GValueArray *va = g_value_get_boxed (&value); @@ -3377,7 +3407,9 @@ mcd_account_setup (McdAccount *account) g_ptr_array_unref (priv->supersedes); if (mcd_storage_get_attribute (storage, name, - MC_ACCOUNTS_KEY_SUPERSEDES, &value, NULL)) + MC_ACCOUNTS_KEY_SUPERSEDES, + G_VARIANT_TYPE_OBJECT_PATH_ARRAY, + &value, NULL)) { priv->supersedes = g_value_dup_boxed (&value); } diff --git a/src/mcd-account.h b/src/mcd-account.h index edb8da0..6dce649 100644 --- a/src/mcd-account.h +++ b/src/mcd-account.h @@ -139,6 +139,7 @@ gboolean mcd_account_get_parameter (McdAccount *account, const gchar *name, gboolean mcd_account_get_parameter_of_known_type (McdAccount *account, const gchar *name, + const GVariantType *variant_type, GType type, GValue *parameter, GError **error); diff --git a/src/mcd-storage.c b/src/mcd-storage.c index 65ed69d..b09473d 100644 --- a/src/mcd-storage.c +++ b/src/mcd-storage.c @@ -264,7 +264,7 @@ static struct { { NULL, NULL } }; -const gchar * +const GVariantType * mcd_storage_get_attribute_type (const gchar *attribute) { guint i; @@ -272,7 +272,7 @@ mcd_storage_get_attribute_type (const gchar *attribute) for (i = 0; known_attributes[i].type != NULL; i++) { if (!tp_strdiff (attribute, known_attributes[i].name)) - return known_attributes[i].type; + return G_VARIANT_TYPE (known_attributes[i].type); } return NULL; @@ -280,14 +280,18 @@ mcd_storage_get_attribute_type (const gchar *attribute) gboolean mcd_storage_init_value_for_attribute (GValue *value, - const gchar *attribute) + const gchar *attribute, + const GVariantType **variant_type) { - const gchar *s = mcd_storage_get_attribute_type (attribute); + const GVariantType *s = mcd_storage_get_attribute_type (attribute); if (s == NULL) return FALSE; - switch (s[0]) + if (variant_type != NULL) + *variant_type = s; + + switch (g_variant_type_peek_string (s)[0]) { case 's': g_value_init (value, G_TYPE_STRING); @@ -304,7 +308,7 @@ mcd_storage_init_value_for_attribute (GValue *value, case 'a': { - switch (s[1]) + switch (g_variant_type_peek_string (s)[1]) { case 'o': g_value_init (value, TP_ARRAY_TYPE_OBJECT_PATH_LIST); @@ -319,7 +323,7 @@ mcd_storage_init_value_for_attribute (GValue *value, case '(': { - if (!tp_strdiff (s, "(uss)")) + if (g_variant_type_equal (s, G_VARIANT_TYPE ("(uss)"))) { g_value_init (value, TP_STRUCT_TYPE_SIMPLE_PRESENCE); return TRUE; @@ -401,7 +405,7 @@ set_value (const McpAccountManager *ma, GValue tmp = G_VALUE_INIT; GError *error = NULL; - if (!mcd_storage_init_value_for_attribute (&tmp, key)) + if (!mcd_storage_init_value_for_attribute (&tmp, key, NULL)) { g_warning ("Not sure what the type of '%s' is, assuming string", key); @@ -762,7 +766,8 @@ mcd_storage_dup_string (McdStorage *self, g_value_init (&tmp, G_TYPE_STRING); - if (!mcd_storage_get_attribute (self, account, attribute, &tmp, NULL)) + if (!mcd_storage_get_attribute (self, account, attribute, + G_VARIANT_TYPE_STRING, &tmp, NULL)) return NULL; ret = g_value_dup_string (&tmp); @@ -809,6 +814,7 @@ gboolean mcd_storage_get_attribute (McdStorage *self, const gchar *account, const gchar *attribute, + const GVariantType *type, GValue *value, GError **error) { @@ -853,6 +859,7 @@ gboolean mcd_storage_get_parameter (McdStorage *self, const gchar *account, const gchar *parameter, + const GVariantType *type, GValue *value, GError **error) { @@ -1345,7 +1352,8 @@ mcd_storage_get_boolean (McdStorage *self, g_value_init (&tmp, G_TYPE_BOOLEAN); - if (!mcd_storage_get_attribute (self, account, attribute, &tmp, NULL)) + if (!mcd_storage_get_attribute (self, account, attribute, + G_VARIANT_TYPE_BOOLEAN, &tmp, NULL)) return FALSE; return g_value_get_boolean (&tmp); @@ -1373,7 +1381,8 @@ mcd_storage_get_integer (McdStorage *self, g_value_init (&tmp, G_TYPE_INT); - if (!mcd_storage_get_attribute (self, account, attribute, &tmp, NULL)) + if (!mcd_storage_get_attribute (self, account, attribute, + G_VARIANT_TYPE_INT32, &tmp, NULL)) return FALSE; return g_value_get_int (&tmp); diff --git a/src/mcd-storage.h b/src/mcd-storage.h index 604af26..be0d0aa 100644 --- a/src/mcd-storage.h +++ b/src/mcd-storage.h @@ -104,12 +104,14 @@ gchar *mcd_storage_dup_string (McdStorage *storage, gboolean mcd_storage_get_attribute (McdStorage *storage, const gchar *account, const gchar *attribute, + const GVariantType *type, GValue *value, GError **error); gboolean mcd_storage_get_parameter (McdStorage *storage, const gchar *account, const gchar *parameter, + const GVariantType *type, GValue *value, GError **error); @@ -155,9 +157,10 @@ gboolean mcd_keyfile_unescape_value (const gchar *escaped, GValue *value, GError **error); -const gchar *mcd_storage_get_attribute_type (const gchar *attribute); +const GVariantType *mcd_storage_get_attribute_type (const gchar *attribute); gboolean mcd_storage_init_value_for_attribute (GValue *value, - const gchar *attribute); + const gchar *attribute, + const GVariantType **variant_type); G_END_DECLS -- 1.8.4.3