/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/*
* Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
*
* 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.
*
* 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, see .
*
* Authors: Christopher James Lahey
*/
#include
#include "e-list.h"
#include "e-list-iterator.h"
G_DEFINE_TYPE (EList, e_list, G_TYPE_OBJECT)
static void
list_dispose (GObject *object)
{
EList *list = E_LIST (object);
if (list->free)
g_list_foreach (list->list, (GFunc) list->free, list->closure);
g_list_free (list->list);
list->list = NULL;
/* Chain up to parent's dispose() method. */
G_OBJECT_CLASS (e_list_parent_class)->dispose (object);
}
static void
e_list_class_init (EListClass *class)
{
GObjectClass *object_class;
object_class = G_OBJECT_CLASS (class);
object_class->dispose = list_dispose;
}
/**
* e_list_init:
*/
static void
e_list_init (EList *list)
{
}
/**
* e_list_new:
* @copy: (scope call): the copy func
* @free: (scope call): the free func
* @closure: user data
*
* Returns: (transfer full): The new #EList.
**/
EList *
e_list_new (EListCopyFunc copy,
EListFreeFunc free,
gpointer closure)
{
EList *list = g_object_new (E_TYPE_LIST, NULL);
e_list_construct (list, copy, free, closure);
return list;
}
/**
* e_list_construct:
* @list: The #EList.
* @copy: (scope call): the copy func
* @free: (scope call): the free func
* @closure: user data
*
**/
void
e_list_construct (EList *list,
EListCopyFunc copy,
EListFreeFunc free,
gpointer closure)
{
list->copy = copy;
list->free = free;
list->closure = closure;
}
/**
* e_list_duplicate:
* @list: The #EList object.
*
* Returns: (transfer full): The duplicated #EList.
**/
EList *
e_list_duplicate (EList *list)
{
EList *dupe = g_object_new (E_TYPE_LIST, NULL);
dupe->copy = list->copy;
dupe->free = list->free;
dupe->closure = list->closure;
dupe->list = g_list_copy (list->list);
if (dupe->copy) {
GList *listlist;
for (listlist = dupe->list; listlist; listlist = listlist->next) {
listlist->data = dupe->copy (listlist->data, dupe->closure);
}
}
return dupe;
}
/**
* e_list_get_iterator:
* @list: The #EList object.
*
* Returns: (transfer none): the #EIterator.
**/
EIterator *
e_list_get_iterator (EList *list)
{
EIterator *iterator = NULL;
g_return_val_if_fail (list != NULL, NULL);
iterator = e_list_iterator_new (list);
if (iterator)
list->iterators = g_list_append (list->iterators, iterator);
return iterator;
}
gint
e_list_length (EList *list)
{
return g_list_length (list->list);
}
void
e_list_append (EList *list,
gconstpointer data)
{
e_list_invalidate_iterators (list, NULL);
if (list->copy)
list->list = g_list_append (
list->list, list->copy (data, list->closure));
else
list->list = g_list_append (list->list, (gpointer) data);
}
void
e_list_remove (EList *list,
gconstpointer data)
{
GList *link;
link = g_list_find (list->list, data);
if (link)
e_list_remove_link (list, link);
}
void
e_list_invalidate_iterators (EList *list,
EIterator *skip)
{
GList *iterators = list->iterators;
for (; iterators; iterators = iterators->next) {
if (iterators->data != skip) {
e_iterator_invalidate (E_ITERATOR (iterators->data));
}
}
}
/* FIXME: This doesn't work properly if the iterator is the first
* iterator in the list. Well, the iterator doesn't continue on after
* the next time next is called, at least. */
/**
* e_list_remove_link: (skip)
* @list:
* @link:
*/
void
e_list_remove_link (EList *list,
GList *link)
{
GList *iterators = list->iterators;
for (; iterators; iterators = iterators->next) {
if (((EListIterator *) iterators->data)->iterator == link) {
e_iterator_prev (iterators->data);
}
}
if (list->free)
list->free (link->data, list->closure);
list->list = g_list_remove_link (list->list, link);
g_list_free_1 (link);
}
void
e_list_remove_iterator (EList *list,
EIterator *iterator)
{
list->iterators = g_list_remove (list->iterators, iterator);
}