summaryrefslogtreecommitdiff
path: root/gck/gck-enumerator.c
diff options
context:
space:
mode:
Diffstat (limited to 'gck/gck-enumerator.c')
-rw-r--r--gck/gck-enumerator.c917
1 files changed, 0 insertions, 917 deletions
diff --git a/gck/gck-enumerator.c b/gck/gck-enumerator.c
deleted file mode 100644
index c57297e9..00000000
--- a/gck/gck-enumerator.c
+++ /dev/null
@@ -1,917 +0,0 @@
-/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
-/* gck-enumerator.c - the GObject PKCS#11 wrapper library
-
- Copyright (C) 2010, Stefan Walter
-
- The Gnome Keyring Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public License as
- published by the Free Software Foundation; either version 2 of the
- License, or (at your option) any later version.
-
- The Gnome Keyring 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with the Gnome Library; see the file COPYING.LIB. If not,
- write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA.
-
- Author: Stef Walter <nielsen@memberwebs.com>
-*/
-
-#include "config.h"
-
-#include "gck.h"
-#define DEBUG_FLAG GCK_DEBUG_ENUMERATOR
-#include "gck-debug.h"
-#include "gck-private.h"
-
-#include <string.h>
-
-/**
- * SECTION:gck-enumerator
- * @title: GckEnumerator
- * @short_description: Enumerates through PKCS\#11 objects.
- *
- * A GckEnumerator can be used to enumerate through PKCS\#11 objects. It will
- * automatically create sessions as necessary.
- *
- * Use gck_modules_enumerate_objects() or gck_modules_enumerate_uri() to create
- * an enumerator. To get the objects use gck_enumerator_next() or
- * gck_enumerator_next_async() functions.
- */
-
-enum {
- PROP_0,
- PROP_INTERACTION
-};
-
-/**
- * GckEnumerator:
- * @parent: derived from this.
- *
- * An object that allows enumerating of objects across modules, tokens.
- */
-
-typedef struct _GckEnumeratorState GckEnumeratorState;
-
-typedef gpointer (*GckEnumeratorFunc) (GckEnumeratorState *args, gboolean forward);
-
-struct _GckEnumeratorState {
- /* For the current call */
- gint want_objects;
-
- /* The state we're currently in */
- GckEnumeratorFunc handler;
-
- /* Input to enumerator */
- GList *modules;
- GckUriData *match;
- GckSessionOptions session_options;
- GTlsInteraction *interaction;
-
- /* state_slots */
- GList *slots;
-
- /* state_slot */
- GckSlot *slot;
- GckTokenInfo *token_info;
- CK_FUNCTION_LIST_PTR funcs;
-
- /* state_session */
- GckSession *session;
-
- /* state_results */
- GArray *objects;
-
- /* Output from enumerator */
- GList *results;
-};
-
-struct _GckEnumeratorPrivate {
- GMutex *mutex;
- GckEnumeratorState *the_state;
- GTlsInteraction *interaction;
-};
-
-G_DEFINE_TYPE (GckEnumerator, gck_enumerator, G_TYPE_OBJECT);
-
-static gpointer state_modules (GckEnumeratorState *args, gboolean forward);
-static gpointer state_slots (GckEnumeratorState *args, gboolean forward);
-static gpointer state_slot (GckEnumeratorState *args, gboolean forward);
-static gpointer state_session (GckEnumeratorState *args, gboolean forward);
-static gpointer state_authenticated (GckEnumeratorState *args, gboolean forward);
-static gpointer state_results (GckEnumeratorState *args, gboolean forward);
-
-/* ----------------------------------------------------------------------------
- * INTERNAL
- */
-
-static gpointer
-rewind_state (GckEnumeratorState *args, GckEnumeratorFunc handler)
-{
- g_assert (args);
- g_assert (handler);
- g_assert (args->handler);
-
- while (handler != args->handler) {
- args->handler = (args->handler) (args, FALSE);
- g_assert (args->handler);
- }
-
- return handler;
-}
-
-static void
-cleanup_state (GckEnumeratorState *args)
-{
- g_assert (args);
-
- /* Have each state cleanup */
- rewind_state (args, state_modules);
-
- /* state_slots */
- g_assert (!args->slots);
-
- /* state_slot */
- g_assert (!args->slot);
- g_assert (!args->token_info);
- g_assert (!args->funcs);
-
- /* state_session */
- g_assert (!args->session);
-
- /* state_results */
- if (args->objects)
- g_array_free (args->objects, TRUE);
- args->objects = NULL;
-
- /* Other cleanup */
- gck_list_unref_free (args->results);
- args->results = NULL;
-
- gck_list_unref_free (args->modules);
- args->modules = NULL;
-
- g_clear_object (&args->interaction);
-
- if (args->match) {
- if (args->match->attributes)
- _gck_attributes_unlock (args->match->attributes);
- gck_uri_data_free (args->match);
- args->match = NULL;
- }
-}
-
-static gpointer
-state_modules (GckEnumeratorState *args, gboolean forward)
-{
- GckModule *module;
-
- g_assert (args->slots == NULL);
-
- if (forward) {
-
- /* There are no more modules? */
- if (!args->modules) {
- _gck_debug ("no more modules, stopping enumerator");
- return NULL;
- }
-
- /* Pop off the current module */
- module = args->modules->data;
- g_assert (GCK_IS_MODULE (module));
- args->modules = g_list_delete_link (args->modules, args->modules);
-
- args->slots = gck_module_get_slots (module, TRUE);
-
- if (_gck_debugging) {
- GckModuleInfo *info = gck_module_get_info (module);
- _gck_debug ("enumerating into module: %s", info->library_description);
- gck_module_info_free (info);
- }
-
- g_object_unref (module);
- return state_slots;
- }
-
- /* Should never be asked to go backward from start state */
- g_assert_not_reached ();
-}
-
-static gpointer
-state_slots (GckEnumeratorState *args, gboolean forward)
-{
- GckSlot *slot;
- GckModule *module;
- GckTokenInfo *token_info;
- gboolean matched;
-
- g_assert (args->slot == NULL);
-
- /* slots to slot state */
- if (forward) {
-
- /* If there are no more slots go back to start state */
- if (!args->slots) {
- _gck_debug ("no more slots, want next module");
- return rewind_state (args, state_modules);
- }
-
- /* Pop the next slot off the stack */
- slot = args->slots->data;
- args->slots = g_list_delete_link (args->slots, args->slots);
-
- token_info = gck_slot_get_token_info (slot);
- if (!token_info) {
- g_message ("couldn't get token info while enumerating");
- g_object_unref (slot);
- return rewind_state (args, state_modules);
- }
-
- /* Do we have unrecognized matches? */
- if (args->match->any_unrecognized) {
- _gck_debug ("token uri had unrecognized, not matching any tokens");
- matched = FALSE;
-
- /* Are we trying to match the slot? */
- } else if (args->match->token_info) {
- /* No match? Go to next slot */
- matched = _gck_token_info_match (args->match->token_info, token_info);
-
- _gck_debug ("%s token: %s", matched ? "matched" : "did not match",
- token_info->label);
-
- } else {
- _gck_debug ("matching all tokens: %s", token_info->label);
- matched = TRUE;
- }
-
- if (!matched) {
- g_object_unref (slot);
- gck_token_info_free (token_info);
- return state_slots;
- }
-
- module = gck_slot_get_module (slot);
- args->funcs = gck_module_get_functions (module);
- g_assert (args->funcs);
- g_object_unref (module);
-
- /* We have a slot */
- args->slot = slot;
- args->token_info = token_info;
- return state_slot;
-
- /* slots state to modules state */
- } else {
-
- gck_list_unref_free (args->slots);
- args->slots = NULL;
- return state_modules;
- }
-}
-
-static gpointer
-state_slot (GckEnumeratorState *args, gboolean forward)
-{
- CK_SESSION_HANDLE session;
- CK_FLAGS flags;
- CK_RV rv;
-
- g_assert (args->slot);
- g_assert (args->funcs);
- g_assert (args->session == NULL);
-
- /* slot to session state */
- if (forward) {
- flags = CKF_SERIAL_SESSION;
- if ((args->session_options & GCK_SESSION_READ_WRITE) == GCK_SESSION_READ_WRITE)
- flags |= CKF_RW_SESSION;
-
- rv = (args->funcs->C_OpenSession) (gck_slot_get_handle (args->slot),
- flags, NULL, NULL, &session);
-
- if (rv != CKR_OK) {
- g_message ("couldn't open session on module while enumerating objects: %s",
- gck_message_from_rv (rv));
- return rewind_state (args, state_slots);
- }
-
- _gck_debug ("opened %s session", flags & CKF_RW_SESSION ? "read-write" : "read-only");
- args->session = gck_session_from_handle (args->slot, session, args->session_options);
- return state_session;
-
- /* slot to slots state */
- } else {
- g_object_unref (args->slot);
- args->slot = NULL;
- args->funcs = NULL;
-
- gck_token_info_free (args->token_info);
- args->token_info = NULL;
-
- return state_slots;
- }
-}
-
-static gpointer
-state_session (GckEnumeratorState *args, gboolean forward)
-{
- GTlsInteraction *interaction;
- CK_RV rv;
-
- g_assert (args->funcs);
- g_assert (args->session);
- g_assert (args->token_info);
-
- /* session to authenticated state */
- if (forward) {
-
- /* Don't want to authenticate? */
- if ((args->session_options & GCK_SESSION_LOGIN_USER) == 0) {
- _gck_debug ("no authentication necessary, skipping");
- return state_authenticated;
- }
-
- /* Compatibility, hook into GckModule signals if no interaction set */
- if (args->interaction)
- interaction = g_object_ref (args->interaction);
- else
- interaction = _gck_interaction_new (args->slot);
-
- rv = _gck_session_authenticate_token (args->funcs,
- gck_session_get_handle (args->session),
- args->slot, interaction, NULL);
-
- g_object_unref (interaction);
-
- if (rv != CKR_OK)
- g_message ("couldn't authenticate when enumerating: %s", gck_message_from_rv (rv));
-
- /* We try to proceed anyway with the enumeration */
- return state_authenticated;
-
- /* Session to slot state */
- } else {
- g_object_unref (args->session);
- args->session = NULL;
- return state_slot;
- }
-}
-
-static gpointer
-state_authenticated (GckEnumeratorState *args, gboolean forward)
-{
- CK_OBJECT_HANDLE objects[128];
- CK_SESSION_HANDLE session;
- CK_ATTRIBUTE_PTR attrs;
- CK_ULONG n_attrs, count;
- CK_RV rv;
-
- /* Just go back, no logout */
- if (!forward)
- return state_session;
-
- /* This is where we do the actual searching */
-
- g_assert (args->session);
- g_assert (args->want_objects);
- g_assert (args->funcs);
-
- if (args->match->attributes) {
- attrs = _gck_attributes_commit_out (args->match->attributes, &n_attrs);
- if (_gck_debugging) {
- gchar *string = _gck_attributes_format (args->match->attributes);
- _gck_debug ("finding objects matching: %s", string);
- g_free (string);
- }
- } else {
- attrs = NULL;
- n_attrs = 0;
- _gck_debug ("finding all objects");
- }
-
- session = gck_session_get_handle (args->session);
- g_return_val_if_fail (session, NULL);
-
- /* Get all the objects */
- rv = (args->funcs->C_FindObjectsInit) (session, attrs, n_attrs);
-
- if (rv == CKR_OK) {
- for(;;) {
- rv = (args->funcs->C_FindObjects) (session, objects, G_N_ELEMENTS (objects), &count);
- if (rv != CKR_OK || count == 0)
- break;
-
- if (!args->objects)
- args->objects = g_array_new (FALSE, TRUE, sizeof (CK_OBJECT_HANDLE));
- _gck_debug ("matched %lu objects", count);
- g_array_append_vals (args->objects, objects, count);
- }
-
- (args->funcs->C_FindObjectsFinal) (session);
- }
-
- _gck_debug ("finding objects completed with: %s", _gck_stringize_rv (rv));
- return state_results;
-}
-
-static GckObject*
-extract_result (GckEnumeratorState *args)
-{
- CK_OBJECT_HANDLE handle;
-
- if (!args->objects || !args->objects->len)
- return NULL;
-
- g_assert (args->session);
-
- handle = g_array_index (args->objects, CK_OBJECT_HANDLE, 0);
- g_array_remove_index_fast (args->objects, 0);
-
- return gck_object_from_handle (args->session, handle);
-}
-
-static gpointer
-state_results (GckEnumeratorState *args, gboolean forward)
-{
- GckObject *object;
- guint have;
-
- g_assert (args->session);
-
- /* No cleanup, just unwind */
- if (!forward)
- return state_authenticated;
-
- /* Create result objects from what we have */
- have = g_list_length (args->results);
-
- while (have < args->want_objects) {
-
- object = extract_result (args);
- if (!object) {
- _gck_debug ("wanted %d objects, have %d, looking for more",
- args->want_objects, have);
- return rewind_state (args, state_slots);
- }
-
- args->results = g_list_append (args->results, object);
- ++have;
- }
-
- _gck_debug ("wanted %d objects, returned %d objects",
- args->want_objects, have);
-
- /* We got all the results we wanted */
- return NULL;
-}
-
-/* ----------------------------------------------------------------------------
- * OBJECT
- */
-
-static void
-gck_enumerator_init (GckEnumerator *self)
-{
- self->pv = G_TYPE_INSTANCE_GET_PRIVATE (self, GCK_TYPE_ENUMERATOR, GckEnumeratorPrivate);
- self->pv->mutex = g_mutex_new ();
- self->pv->the_state = g_new0 (GckEnumeratorState, 1);
-}
-
-static void
-gck_enumerator_get_property (GObject *obj,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
-{
- GckEnumerator *self = GCK_ENUMERATOR (obj);
-
- switch (prop_id) {
- case PROP_INTERACTION:
- g_value_take_object (value, gck_enumerator_get_interaction (self));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
- break;
- }
-}
-
-static void
-gck_enumerator_set_property (GObject *obj,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- GckEnumerator *self = GCK_ENUMERATOR (obj);
-
- switch (prop_id) {
- case PROP_INTERACTION:
- gck_enumerator_set_interaction (self, g_value_get_object (value));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
- break;
- }
-}
-
-static void
-gck_enumerator_dispose (GObject *obj)
-{
- GckEnumerator *self = GCK_ENUMERATOR (obj);
-
- gck_enumerator_set_interaction (self, NULL);
-
- G_OBJECT_CLASS (gck_enumerator_parent_class)->dispose (obj);
-}
-
-static void
-gck_enumerator_finalize (GObject *obj)
-{
- GckEnumerator *self = GCK_ENUMERATOR (obj);
-
- g_assert (self->pv->interaction == NULL);
-
- g_assert (self->pv->the_state != NULL);
- cleanup_state (self->pv->the_state);
- g_free (self->pv->the_state);
-
- g_mutex_free (self->pv->mutex);
-
- G_OBJECT_CLASS (gck_enumerator_parent_class)->finalize (obj);
-}
-
-static void
-gck_enumerator_class_init (GckEnumeratorClass *klass)
-{
- GObjectClass *gobject_class = (GObjectClass*)klass;
-
- gobject_class->get_property = gck_enumerator_get_property;
- gobject_class->set_property = gck_enumerator_set_property;
- gobject_class->dispose = gck_enumerator_dispose;
- gobject_class->finalize = gck_enumerator_finalize;
-
- g_type_class_add_private (klass, sizeof (GckEnumeratorPrivate));
-
- /**
- * GckEnumerator:interaction:
- *
- * Interaction object used to ask the user for pins when opening
- * sessions. Used if the session_options of the enumerator have
- * %GCK_SESSION_LOGIN_USER
- */
- g_object_class_install_property (gobject_class, PROP_INTERACTION,
- g_param_spec_object ("interaction", "Interaction", "Interaction asking for pins",
- G_TYPE_TLS_INTERACTION, G_PARAM_READWRITE));
-}
-
-/* ----------------------------------------------------------------------------
- * PUBLIC
- */
-
-GckEnumerator*
-_gck_enumerator_new (GList *modules_or_slots,
- GckSessionOptions session_options,
- GckUriData *uri_data)
-{
- GckEnumerator *self;
- GckEnumeratorState *state;
-
- self = g_object_new (GCK_TYPE_ENUMERATOR, NULL);
- state = self->pv->the_state;
-
- state->session_options = session_options;
-
- if (modules_or_slots && GCK_IS_SLOT (modules_or_slots->data)) {
- state->slots = gck_list_ref_copy (modules_or_slots);
- state->modules = NULL;
- state->handler = state_slots;
- } else {
- state->modules = gck_list_ref_copy (modules_or_slots);
- state->slots = NULL;
- state->handler = state_modules;
- }
-
- state->match = uri_data;
- if (uri_data->attributes)
- _gck_attributes_lock (uri_data->attributes);
-
- if (_gck_debugging) {
- gchar *attrs, *uri;
- attrs = uri_data->attributes ? _gck_attributes_format (uri_data->attributes) : NULL;
- uri = uri_data ? gck_uri_build (uri_data, GCK_URI_FOR_TOKEN | GCK_URI_FOR_MODULE) : NULL;
- _gck_debug ("new enumerator: tokens = %s, objects = %s", uri, attrs);
- g_free (attrs);
- g_free (uri);
- }
-
- return self;
-}
-
-typedef struct _EnumerateNext {
- GckArguments base;
- GckEnumeratorState *state;
-} EnumerateNext;
-
-static CK_RV
-perform_enumerate_next (EnumerateNext *args)
-{
- GckEnumeratorFunc handler;
- GckEnumeratorState *state;
-
- g_assert (args->state);
- state = args->state;
-
- g_assert (state->handler);
-
- for (;;) {
- handler = (state->handler) (state, TRUE);
- if (!handler)
- break;
- state->handler = handler;
- }
-
- /* TODO: In some modes, errors */
- return CKR_OK;
-}
-
-static void
-free_enumerate_next (EnumerateNext *args)
-{
- /* Should have been assigned back to enumerator */
- g_assert (!args->state);
-
- g_free (args);
-}
-
-/**
- * gck_enumerator_get_interaction:
- * @self: the enumerator
- *
- * Get the interaction used when a pin is needed
- *
- * Returns: (transfer full) (allow-none): the interaction or %NULL
- */
-GTlsInteraction *
-gck_enumerator_get_interaction (GckEnumerator *self)
-{
- GTlsInteraction *result = NULL;
-
- g_return_val_if_fail (GCK_IS_ENUMERATOR (self), NULL);
-
- g_mutex_lock (self->pv->mutex);
-
- if (self->pv->interaction)
- result = g_object_ref (self->pv->interaction);
-
- g_mutex_unlock (self->pv->mutex);
-
- return result;
-}
-
-/**
- * gck_enumerator_set_interaction:
- * @self: the enumerator
- * @interaction: (allow-none): the interaction or %NULL
- *
- * Set the interaction used when a pin is needed
- */
-void
-gck_enumerator_set_interaction (GckEnumerator *self,
- GTlsInteraction *interaction)
-{
- GTlsInteraction *previous = NULL;
-
- g_return_if_fail (GCK_IS_ENUMERATOR (self));
- g_return_if_fail (interaction == NULL || G_IS_TLS_INTERACTION (interaction));
-
- g_mutex_lock (self->pv->mutex);
-
- if (interaction != self->pv->interaction) {
- previous = self->pv->interaction;
- self->pv->interaction = interaction;
- if (interaction)
- g_object_ref (interaction);
- }
-
- g_mutex_unlock (self->pv->mutex);
-
- g_clear_object (&previous);
- g_object_notify (G_OBJECT (self), "interaction");
-}
-
-static GckEnumeratorState *
-check_out_enumerator_state (GckEnumerator *self)
-{
- GckEnumeratorState *state = NULL;
-
- g_mutex_lock (self->pv->mutex);
-
- if (self->pv->the_state) {
- state = self->pv->the_state;
- self->pv->the_state = NULL;
-
- g_clear_object (&state->interaction);
- if (self->pv->interaction)
- state->interaction = g_object_ref (self->pv->interaction);
- }
-
- g_mutex_unlock (self->pv->mutex);
-
- if (state == NULL)
- g_warning ("this enumerator is already running a next operation");
-
- return state;
-}
-
-static void
-check_in_enumerator_state (GckEnumerator *self,
- GckEnumeratorState *state)
-{
- g_mutex_lock (self->pv->mutex);
-
- g_assert (self->pv->the_state == NULL);
- self->pv->the_state = state;
-
- g_mutex_unlock (self->pv->mutex);
-}
-
-/**
- * gck_enumerator_next:
- * @self: The enumerator
- * @cancellable: A #GCancellable or %NULL
- * @error: A location to store an error on failure
- *
- * Get the next object in the enumerator, or %NULL if there are no more objects.
- *
- * %NULL is also returned if the function fails. Use the @error to determine
- * whether a failure occurred or not.
- *
- * Returns: (transfer full) (allow-none): The next object, which must be released
- * using g_object_unref, or %NULL.
- */
-GckObject*
-gck_enumerator_next (GckEnumerator *self, GCancellable *cancellable, GError **error)
-{
- EnumerateNext args = { GCK_ARGUMENTS_INIT, NULL, };
- GckObject *result = NULL;
-
- g_return_val_if_fail (GCK_IS_ENUMERATOR (self), NULL);
- g_return_val_if_fail (!error || !*error, NULL);
-
- args.state = check_out_enumerator_state (self);
- g_return_val_if_fail (args.state != NULL, NULL);
-
- /* A result from a previous run? */
- result = extract_result (args.state);
- if (!result) {
- args.state->want_objects = 1;
-
- /* Run the operation and steal away the results */
- if (_gck_call_sync (NULL, perform_enumerate_next, NULL, &args, cancellable, error)) {
- if (args.state->results) {
- g_assert (g_list_length (args.state->results) == 1);
- result = g_object_ref (args.state->results->data);
- gck_list_unref_free (args.state->results);
- args.state->results = NULL;
- }
- }
-
- args.state->want_objects = 0;
- }
-
- /* Put the state back */
- check_in_enumerator_state (self, args.state);
-
- return result;
-}
-
-/**
- * gck_enumerator_next_n:
- * @self: An enumerator
- * @max_objects: The maximum amount of objects to enumerate
- * @cancellable: A #GCancellable or %NULL
- * @error: A location to store an error on failure
- *
- * Get the next set of objects from the enumerator. The maximum number of
- * objects can be specified with @max_objects. If -1 is specified, then all
- * the remaining objects will be returned.
- *
- * %NULL is also returned if the function fails. Use the @error to determine
- * whether a failure occurred or not.
- *
- * Returns: (transfer full) (element-type Gck.Object): A list of objects, which
- * should be freed using gck_list_unref_free().
- */
-GList*
-gck_enumerator_next_n (GckEnumerator *self, gint max_objects, GCancellable *cancellable,
- GError **error)
-{
- EnumerateNext args = { GCK_ARGUMENTS_INIT, NULL, };
- GList *results = NULL;
-
- g_return_val_if_fail (GCK_IS_ENUMERATOR (self), NULL);
- g_return_val_if_fail (max_objects == -1 || max_objects > 0, NULL);
- g_return_val_if_fail (!error || !*error, NULL);
-
- /* Remove the state and own it ourselves */
- args.state = check_out_enumerator_state (self);
- g_return_val_if_fail (args.state != NULL, NULL);
-
- args.state->want_objects = max_objects <= 0 ? G_MAXINT : max_objects;
-
- /* Run the operation and steal away the results */
- if (_gck_call_sync (NULL, perform_enumerate_next, NULL, &args, cancellable, error)) {
- results = args.state->results;
- args.state->results = NULL;
- }
-
- args.state->want_objects = 0;
-
- /* Put the state back */
- check_in_enumerator_state (self, args.state);
-
- return results;
-}
-
-/**
- * gck_enumerator_next_async:
- * @self: An enumerator
- * @max_objects: The maximum number of objects to get
- * @cancellable: A #GCancellable or %NULL
- * @callback: Called when the result is ready
- * @user_data: Data to pass to the callback
- *
- * Get the next set of objects from the enumerator. This operation completes
- * asynchronously.The maximum number of objects can be specified with
- * @max_objects. If -1 is specified, then all the remaining objects will be
- * enumerated.
- */
-void
-gck_enumerator_next_async (GckEnumerator *self, gint max_objects, GCancellable *cancellable,
- GAsyncReadyCallback callback, gpointer user_data)
-{
- GckEnumeratorState *state;
- EnumerateNext *args;
-
- g_return_if_fail (GCK_IS_ENUMERATOR (self));
- g_return_if_fail (max_objects == -1 || max_objects > 0);
-
- g_object_ref (self);
-
- /* Remove the state and own it ourselves */
- state = check_out_enumerator_state (self);
- g_return_if_fail (state != NULL);
-
- state->want_objects = max_objects <= 0 ? G_MAXINT : max_objects;
- args = _gck_call_async_prep (NULL, self, perform_enumerate_next, NULL,
- sizeof (*args), free_enumerate_next);
-
- args->state = state;
- _gck_call_async_ready_go (args, cancellable, callback, user_data);
- g_object_unref (self);
-}
-
-/**
- * gck_enumerator_next_finish:
- * @self: An enumerator
- * @result: The result passed to the callback
- * @error: A location to raise an error on failure.
- *
- * Complete an operation to enumerate next objects.
- *
- * %NULL is also returned if the function fails. Use the @error to determine
- * whether a failure occurred or not.
- *
- * Returns: (element-type Gck.Module) (transfer full): The list of objects, which
- * should be freed with gck_list_unref_free()
- */
-GList*
-gck_enumerator_next_finish (GckEnumerator *self, GAsyncResult *result, GError **error)
-{
- EnumerateNext *args;
- GckEnumeratorState *state;
- GList *results = NULL;
-
- g_object_ref (self);
-
- args = _gck_call_arguments (result, EnumerateNext);
- state = args->state;
- args->state = NULL;
- state->want_objects = 0;
-
- if (_gck_call_basic_finish (result, error)) {
- results = state->results;
- state->results = NULL;
- }
-
- /* Put the state back */
- check_in_enumerator_state (self, state);
-
- g_object_unref (self);
-
- return results;
-}