/* * handle-repo.c - mechanism to store and retrieve handles on a connection * (abstract interface) * * Copyright (C) 2007 Collabora Ltd. * Copyright (C) 2007 Nokia Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ /** * SECTION:handle-repo * @title: TpHandleRepoIface * @short_description: abstract interface for handle allocation * @see_also: TpDynamicHandleRepo, TpStaticHandleRepo * * Abstract interface of a repository for handles, supporting operations * which include checking for validity, lookup by * string value and lookup by numeric value. See #TpDynamicHandleRepo * and #TpStaticHandleRepo for concrete implementations. */ #include "config.h" #include #include #include G_DEFINE_INTERFACE (TpHandleRepoIface, tp_handle_repo_iface, G_TYPE_OBJECT); /** * tp_handle_is_valid: (skip) * @self: A handle repository implementation * @handle: A handle of the type stored in the repository @self * @error: Set to InvalidHandle if %FALSE is returned * * * * Returns: %TRUE if the handle is nonzero and is present in the repository, * else %FALSE */ gboolean tp_handle_is_valid (TpHandleRepoIface *self, TpHandle handle, GError **error) { return TP_HANDLE_REPO_IFACE_GET_CLASS (self)->handle_is_valid (self, handle, error); } /** * tp_handles_are_valid: (skip) * @self: A handle repository implementation * @handles: Array of TpHandle representing handles of the type stored in * the repository @self * @allow_zero: If %TRUE, zero is treated like a valid handle * @error: Set to InvalidHandle if %FALSE is returned * * * * Returns: %TRUE if the handle is present in the repository, else %FALSE */ gboolean tp_handles_are_valid (TpHandleRepoIface *self, const GArray *handles, gboolean allow_zero, GError **error) { return TP_HANDLE_REPO_IFACE_GET_CLASS (self)->handles_are_valid (self, handles, allow_zero, error); } /** * tp_handle_ref: (skip) * @self: not used * @handle: not used * * Do nothing. Since version 0.13.8, handles always last as long as * the connection; previously, this function provided refcounting for handles. * * Changed in 0.13.6: @handle is now returned; previously, * this function didn't return anything. * * Returns: the same @handle * Deprecated: This is no-op so can be safely removed. */ TpHandle tp_handle_ref (TpHandleRepoIface *self G_GNUC_UNUSED, TpHandle handle) { return handle; } /** * tp_handles_ref: (skip) * @self: not used * @handles: not used * * Do nothing. Since version 0.13.8, handles always last as long as * the connection; previously, this function provided refcounting for handles. * * Deprecated: This is no-op so can be safely removed. */ void tp_handles_ref (TpHandleRepoIface *self G_GNUC_UNUSED, const GArray *handles G_GNUC_UNUSED) { } /** * tp_handle_unref: (skip) * @self: A handle repository implementation * @handle: A handle of the type stored in the repository * * Do nothing. Since version 0.13.8, handles always last as long as * the connection; previously, this function provided refcounting for handles. * * Deprecated: This is no-op so can be safely removed. */ void tp_handle_unref (TpHandleRepoIface *self G_GNUC_UNUSED, TpHandle handle G_GNUC_UNUSED) { } /** * tp_handles_unref: (skip) * @self: not used * @handles: not used * * Do nothing. Since version 0.13.8, handles always last as long as * the connection; previously, this function provided refcounting for handles. * * Deprecated: This is no-op so can be safely removed. */ void tp_handles_unref (TpHandleRepoIface *self G_GNUC_UNUSED, const GArray *handles G_GNUC_UNUSED) { } /** * tp_handle_client_hold: (skip) * @self: not used * @client: not used * @handle: not used * @error: not set * * Do nothing. Since version 0.13.8, handles always last as long as * the connection; previously, this function provided refcounting for handles. * * Returns: %TRUE * Deprecated: This is no-op so can be safely removed. */ gboolean tp_handle_client_hold (TpHandleRepoIface *self G_GNUC_UNUSED, const gchar *client G_GNUC_UNUSED, TpHandle handle G_GNUC_UNUSED, GError **error G_GNUC_UNUSED) { return TRUE; } typedef gboolean (*HoldReleaseFunc) (TpHandleRepoIface *, const gchar *, TpHandle, GError **); /** * tp_handles_client_hold: (skip) * @self: ignored * @client: ignored * @handles: ignored * @error: ignored * * Do nothing. Since version 0.13.8, handles always last as long as * the connection; previously, this function provided refcounting for handles. * * Returns: %TRUE * Deprecated: This is no-op so can be safely removed. */ gboolean tp_handles_client_hold (TpHandleRepoIface *self G_GNUC_UNUSED, const gchar *client G_GNUC_UNUSED, const GArray *handles G_GNUC_UNUSED, GError **error G_GNUC_UNUSED) { return TRUE; } /** * tp_handle_client_release: (skip) * @self: ignored * @client: ignored * @handle: ignored * @error: ignored * * Do nothing. Since version 0.13.8, handles always last as long as * the connection; previously, this function provided refcounting for handles. * * Returns: %TRUE * Deprecated: This is no-op so can be safely removed. */ gboolean tp_handle_client_release (TpHandleRepoIface *self G_GNUC_UNUSED, const gchar *client G_GNUC_UNUSED, TpHandle handle G_GNUC_UNUSED, GError **error G_GNUC_UNUSED) { return TRUE; } /** * tp_handles_client_release: (skip) * @self: ignored * @client: ignored * @handles: ignored * @error: ignored * * Do nothing. Since version 0.13.8, handles always last as long as * the connection; previously, this function provided refcounting for handles. * * Returns: %TRUE * Deprecated: This is no-op so can be safely removed. */ gboolean tp_handles_client_release (TpHandleRepoIface *self G_GNUC_UNUSED, const gchar *client G_GNUC_UNUSED, const GArray *handles G_GNUC_UNUSED, GError **error G_GNUC_UNUSED) { return TRUE; } /** * tp_handle_inspect: (skip) * @self: A handle repository implementation * @handle: A handle of the type stored in the repository * * * * Returns: the string represented by the given handle, or NULL if the * handle is absent from the repository. The string is owned by the * handle repository and will remain valid as long as a reference to * the handle exists. */ const char * tp_handle_inspect (TpHandleRepoIface *self, TpHandle handle) { return TP_HANDLE_REPO_IFACE_GET_CLASS (self)->inspect_handle (self, handle); } /** * tp_handle_ensure: * @self: A handle repository implementation * @id: A string whose handle is required * @context: User data to be passed to the normalization callback * @error: Used to return an error if 0 is returned * * Return a handle for the given string, creating one if necessary. The string * is normalized, if possible. * * Returns: the handle corresponding to the given string, or 0 if it * is invalid. */ TpHandle tp_handle_ensure (TpHandleRepoIface *self, const gchar *id, gpointer context, GError **error) { return TP_HANDLE_REPO_IFACE_GET_CLASS (self)->ensure_handle (self, id, context, error); } /** * tp_handle_ensure_async: (skip) * @self: A handle repository implementation * @connection: the #TpBaseConnection using this handle repo * @id: A string whose handle is required * @context: User data to be passed to the normalization callback * @callback: a callback to call when the operation finishes * @user_data: data to pass to @callback * * Asyncronously normalize an identifier and create an handle for it. This could * involve a server round-trip. This should be used instead of * tp_handle_ensure() for user provided contact identifiers, but it is not * necessary for identifiers from the server. * * Since: 0.19.2 */ void tp_handle_ensure_async (TpHandleRepoIface *self, TpBaseConnection *connection, const gchar *id, gpointer context, GAsyncReadyCallback callback, gpointer user_data) { return TP_HANDLE_REPO_IFACE_GET_CLASS (self)->ensure_handle_async (self, connection, id, context, callback, user_data); } /** * tp_handle_ensure_finish: (skip) * @self: A handle repository implementation * @result: a #GAsyncResult * @error: a #GError to fill * * Finishes tp_handle_ensure_async() * * Returns: non-0 #TpHandle if the operation was successful, otherwise 0. * * Since: 0.19.2 */ TpHandle tp_handle_ensure_finish (TpHandleRepoIface *self, GAsyncResult *result, GError **error) { return TP_HANDLE_REPO_IFACE_GET_CLASS (self)->ensure_handle_finish (self, result, error); } /** * tp_handle_lookup: (skip) * @self: A handle repository implementation * @id: A string whose handle is required * @context: User data to be passed to the normalization callback * @error: Used to raise an error if the handle does not exist or is * invalid * * Return the handle for the given string. The string is normalized if * possible. If no handle already exists for the string, none is created. * * Returns: the handle corresponding to the given string, or 0 if it * does not exist or is invalid */ TpHandle tp_handle_lookup (TpHandleRepoIface *self, const gchar *id, gpointer context, GError **error) { return TP_HANDLE_REPO_IFACE_GET_CLASS (self)->lookup_handle (self, id, context, error); } /** * tp_handle_set_qdata: (skip) * @repo: A handle repository implementation * @handle: A handle to set data on * @key_id: Key id to associate data with * @data: data to associate with handle * @destroy: A #GDestroyNotify to call to destroy the data, * or NULL if not needed. * * Associates a blob of data with a given handle and a given key * * If @destroy is set, then the data is freed when the handle is freed. * * Since version 0.13.8, handles always last as long as the * connection, so @destroy will not be called until the connection * disconnects. * * Deprecated: Since 0.19.9. It is not recommended to use this function * because the associated data won't be freed until the connection disconnects. */ void tp_handle_set_qdata (TpHandleRepoIface *repo, TpHandle handle, GQuark key_id, gpointer data, GDestroyNotify destroy) { TP_HANDLE_REPO_IFACE_GET_CLASS (repo)->set_qdata (repo, handle, key_id, data, destroy); } /** * tp_handle_get_qdata: (skip) * @repo: A handle repository implementation * @handle: A handle to get data from * @key_id: Key id of data to fetch * * * * Returns: the data associated with a given key on a given handle; %NULL * if there is no associated data. * Deprecated: Since 0.19.9. It is not recommended to use this function * because the associated data won't be freed until the connection disconnects. */ gpointer tp_handle_get_qdata (TpHandleRepoIface *repo, TpHandle handle, GQuark key_id) { return TP_HANDLE_REPO_IFACE_GET_CLASS (repo)->get_qdata (repo, handle, key_id); } static void default_ensure_handle_async (TpHandleRepoIface *self, TpBaseConnection *connection, const gchar *id, gpointer context, GAsyncReadyCallback callback, gpointer user_data) { GSimpleAsyncResult *result; TpHandle handle; GError *error = NULL; result = g_simple_async_result_new (G_OBJECT (self), callback, user_data, default_ensure_handle_async); handle = tp_handle_ensure (self, id, context, &error); if (handle == 0) { g_simple_async_result_take_error (result, error); } else { g_simple_async_result_set_op_res_gpointer (result, GUINT_TO_POINTER (handle), NULL); } g_simple_async_result_complete_in_idle (result); g_object_unref (result); } static TpHandle default_ensure_handle_finish (TpHandleRepoIface *self, GAsyncResult *result, GError **error) { GSimpleAsyncResult *simple = (GSimpleAsyncResult *) result; g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (self), NULL), 0); if (g_simple_async_result_propagate_error (simple, error)) return 0; return GPOINTER_TO_UINT (g_simple_async_result_get_op_res_gpointer (simple)); } static void tp_handle_repo_iface_default_init (TpHandleRepoIfaceInterface *iface) { GParamSpec *param_spec; iface->ensure_handle_async = default_ensure_handle_async; iface->ensure_handle_finish = default_ensure_handle_finish; param_spec = g_param_spec_uint ("handle-type", "Handle type", "The TpHandleType held in this handle repository.", 0, G_MAXUINT32, 0, G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); g_object_interface_install_property (iface, param_spec); }