From 7fb76e3ea7b41dc799e20fb351d264faacada2f7 Mon Sep 17 00:00:00 2001 From: Xavier Claessens Date: Tue, 29 May 2012 13:25:13 +0200 Subject: [PATCH] TpDynamicHandleRepo: Support async normalization function Override TpHandleRepoIface::ensure_handle_async() and use an user provided async normalization function. https://bugs.freedesktop.org/show_bug.cgi?id=50341 --- docs/reference/telepathy-glib-sections.txt | 3 + telepathy-glib/handle-repo-dynamic.c | 113 ++++++++++++++++++++++++++++ telepathy-glib/handle-repo-dynamic.h | 15 ++++ 3 files changed, 131 insertions(+) diff --git a/docs/reference/telepathy-glib-sections.txt b/docs/reference/telepathy-glib-sections.txt index f8d7790..da5c28c 100644 --- a/docs/reference/telepathy-glib-sections.txt +++ b/docs/reference/telepathy-glib-sections.txt @@ -294,7 +294,10 @@ TpDynamicHandleRepo TpDynamicHandleRepoClass tp_dynamic_handle_repo_lookup_exact tp_dynamic_handle_repo_new +tp_dynamic_handle_repo_set_normalize_async TpDynamicHandleRepoNormalizeFunc +TpDynamicHandleRepoNormalizeAsync +TpDynamicHandleRepoNormalizeFinish TP_DYNAMIC_HANDLE_REPO TP_IS_DYNAMIC_HANDLE_REPO diff --git a/telepathy-glib/handle-repo-dynamic.c b/telepathy-glib/handle-repo-dynamic.c index 9bd6513..983d6c0 100644 --- a/telepathy-glib/handle-repo-dynamic.c +++ b/telepathy-glib/handle-repo-dynamic.c @@ -75,6 +75,33 @@ */ /** + * TpDynamicHandleRepoNormalizeAsync: + * @repo: The repository on which tp_handle_ensure_async() was called + * @connection: the #TpBaseConnection using this handle repo + * @id: The name to be normalized + * @context: Arbitrary context passed to tp_handle_ensure_async() + * @callback: a callback to call when the operation finishes + * @user_data: data to pass to @callback + * + * Signature of a function to asynchronously normalize an identifier. See + * tp_dynamic_handle_repo_set_normalize_async(). + * + * Since: 0.UNRELEASED + */ + +/** + * TpDynamicHandleRepoNormalizeFinish: + * @repo: The repository on which tp_handle_ensure_async() was called + * @result: a #GAsyncResult + * @error: a #GError to fill + * + * Signature of a function to finish the operation started with + * #TpDynamicHandleRepoNormalizeAsync. + * + * Since: 0.UNRELEASED + */ + +/** * tp_dynamic_handle_repo_new: * @handle_type: The handle type * @normalize_func: The function to be used to normalize and validate handles, @@ -160,6 +187,10 @@ struct _TpDynamicHandleRepo { gpointer normalization_data; /* Destructor for extra data */ GDestroyNotify free_normalization_data; + + /* Async normalization function */ + TpDynamicHandleRepoNormalizeAsync normalize_async; + TpDynamicHandleRepoNormalizeFinish normalize_finish; }; static void dynamic_repo_iface_init (gpointer g_iface, @@ -522,6 +553,63 @@ dynamic_ensure_handle (TpHandleRepoIface *irepo, } static void +normalize_cb (GObject *source, + GAsyncResult *result, + gpointer user_data) +{ + TpDynamicHandleRepo *self = (TpDynamicHandleRepo *) source; + TpHandleRepoIface *repo = (TpHandleRepoIface *) self; + GSimpleAsyncResult *my_result = user_data; + gchar *normal_id; + GError *error = NULL; + + normal_id = self->normalize_finish (repo, result, &error); + if (normal_id == NULL) + { + g_simple_async_result_take_error (my_result, error); + } + else + { + TpHandle handle; + + handle = ensure_handle_take_normalized_id (self, normal_id); + g_simple_async_result_set_op_res_gpointer (my_result, + GUINT_TO_POINTER (handle), NULL); + } + + g_simple_async_result_complete (my_result); + g_object_unref (my_result); +} + +static void +dynamic_ensure_handle_async (TpHandleRepoIface *repo, + TpBaseConnection *connection, + const gchar *id, + gpointer context, + GAsyncReadyCallback callback, + gpointer user_data) +{ + TpDynamicHandleRepo *self = TP_DYNAMIC_HANDLE_REPO (repo); + GSimpleAsyncResult *result; + + if (self->normalize_async == NULL) + { + /* Fallback to default implementation */ + _tp_handle_repo_default_ensure_handle_async (repo, connection, id, + context, callback, user_data); + return; + } + + if (context == NULL) + context = self->default_normalize_context; + + result = g_simple_async_result_new (G_OBJECT (repo), callback, user_data, + dynamic_ensure_handle_async); + + self->normalize_async (repo, connection, id, context, normalize_cb, result); +} + +static void dynamic_set_qdata (TpHandleRepoIface *repo, TpHandle handle, GQuark key_id, gpointer data, GDestroyNotify destroy) { @@ -560,6 +648,7 @@ dynamic_repo_iface_init (gpointer g_iface, klass->inspect_handle = dynamic_inspect_handle; klass->lookup_handle = dynamic_lookup_handle; klass->ensure_handle = dynamic_ensure_handle; + klass->ensure_handle_async = dynamic_ensure_handle_async; klass->set_qdata = dynamic_set_qdata; klass->get_qdata = dynamic_get_qdata; } @@ -612,3 +701,27 @@ _tp_dynamic_handle_repo_set_normalization_data (TpHandleRepoIface *irepo, self->normalization_data = data; self->free_normalization_data = destroy; } + +/** + * tp_dynamic_handle_repo_set_normalize_async: + * @self: A #TpDynamicHandleRepo + * @normalize_async: a #TpDynamicHandleRepoNormalizeAsync + * @normalize_finish: a #TpDynamicHandleRepoNormalizeFinish + * + * Set an asynchronous normalization function. This is to be used if handle + * normalization requires a server round-trip. See tp_handle_ensure_async(). + * + * Since: 0.UNRELEASED + */ +void +tp_dynamic_handle_repo_set_normalize_async (TpDynamicHandleRepo *self, + TpDynamicHandleRepoNormalizeAsync normalize_async, + TpDynamicHandleRepoNormalizeFinish normalize_finish) +{ + g_return_if_fail (TP_IS_DYNAMIC_HANDLE_REPO (self)); + g_return_if_fail (normalize_async != NULL); + g_return_if_fail (normalize_finish != NULL); + + self->normalize_async = normalize_async; + self->normalize_finish = normalize_finish; +} diff --git a/telepathy-glib/handle-repo-dynamic.h b/telepathy-glib/handle-repo-dynamic.h index bfd4341..c2125e2 100644 --- a/telepathy-glib/handle-repo-dynamic.h +++ b/telepathy-glib/handle-repo-dynamic.h @@ -33,6 +33,16 @@ typedef struct _TpDynamicHandleRepoClass TpDynamicHandleRepoClass; typedef gchar *(*TpDynamicHandleRepoNormalizeFunc)(TpHandleRepoIface *repo, const gchar *id, gpointer context, GError **error); +typedef void (*TpDynamicHandleRepoNormalizeAsync) (TpHandleRepoIface *repo, + TpBaseConnection *connection, + const gchar *id, + gpointer context, + GAsyncReadyCallback callback, + gpointer user_data); +typedef gchar * (*TpDynamicHandleRepoNormalizeFinish) (TpHandleRepoIface *repo, + GAsyncResult *result, + GError **error); + GType tp_dynamic_handle_repo_get_type (void); #define TP_TYPE_DYNAMIC_HANDLE_REPO \ @@ -72,6 +82,11 @@ tp_dynamic_handle_repo_new (TpHandleType handle_type, NULL); } +_TP_AVAILABLE_IN_UNRELEASED +void tp_dynamic_handle_repo_set_normalize_async (TpDynamicHandleRepo *self, + TpDynamicHandleRepoNormalizeAsync normalize_async, + TpDynamicHandleRepoNormalizeFinish normalize_finish); + G_END_DECLS #endif -- 1.7.9.5