diff options
Diffstat (limited to 'contrib/libcdio/ds.c')
-rw-r--r-- | contrib/libcdio/ds.c | 249 |
1 files changed, 249 insertions, 0 deletions
diff --git a/contrib/libcdio/ds.c b/contrib/libcdio/ds.c new file mode 100644 index 000000000..381c0f00c --- /dev/null +++ b/contrib/libcdio/ds.c @@ -0,0 +1,249 @@ +/* + $Id: ds.c,v 1.3 2005/01/01 02:43:57 rockyb Exp $ + + Copyright (C) 2000 Herbert Valerio Riedel <hvr@gnu.org> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include <stdlib.h> +#include <string.h> + +#include <cdio/ds.h> +#include <cdio/util.h> +#include <cdio/types.h> +#include "cdio_assert.h" + +static const char _rcsid[] = "$Id: ds.c,v 1.3 2005/01/01 02:43:57 rockyb Exp $"; + +struct _CdioList +{ + unsigned length; + + CdioListNode *begin; + CdioListNode *end; +}; + +struct _CdioListNode +{ + CdioList *list; + + CdioListNode *next; + + void *data; +}; + +/* impl */ + +CdioList * +_cdio_list_new (void) +{ + CdioList *new_obj = _cdio_malloc (sizeof (CdioList)); + + return new_obj; +} + +void +_cdio_list_free (CdioList *list, int free_data) +{ + while (_cdio_list_length (list)) + _cdio_list_node_free (_cdio_list_begin (list), free_data); + + free (list); +} + +unsigned +_cdio_list_length (const CdioList *list) +{ + cdio_assert (list != NULL); + + return list->length; +} + +void +_cdio_list_prepend (CdioList *list, void *data) +{ + CdioListNode *new_node; + + cdio_assert (list != NULL); + + new_node = _cdio_malloc (sizeof (CdioListNode)); + + new_node->list = list; + new_node->next = list->begin; + new_node->data = data; + + list->begin = new_node; + if (list->length == 0) + list->end = new_node; + + list->length++; +} + +void +_cdio_list_append (CdioList *list, void *data) +{ + cdio_assert (list != NULL); + + if (list->length == 0) + { + _cdio_list_prepend (list, data); + } + else + { + CdioListNode *new_node = _cdio_malloc (sizeof (CdioListNode)); + + new_node->list = list; + new_node->next = NULL; + new_node->data = data; + + list->end->next = new_node; + list->end = new_node; + + list->length++; + } +} + +void +_cdio_list_foreach (CdioList *list, _cdio_list_iterfunc func, void *user_data) +{ + CdioListNode *node; + + cdio_assert (list != NULL); + cdio_assert (func != 0); + + for (node = _cdio_list_begin (list); + node != NULL; + node = _cdio_list_node_next (node)) + func (_cdio_list_node_data (node), user_data); +} + +CdioListNode * +_cdio_list_find (CdioList *list, _cdio_list_iterfunc cmp_func, void *user_data) +{ + CdioListNode *node; + + cdio_assert (list != NULL); + cdio_assert (cmp_func != 0); + + for (node = _cdio_list_begin (list); + node != NULL; + node = _cdio_list_node_next (node)) + if (cmp_func (_cdio_list_node_data (node), user_data)) + break; + + return node; +} + +CdioListNode * +_cdio_list_begin (const CdioList *list) +{ + cdio_assert (list != NULL); + + return list->begin; +} + +CdioListNode * +_cdio_list_end (CdioList *list) +{ + cdio_assert (list != NULL); + + return list->end; +} + +CdioListNode * +_cdio_list_node_next (CdioListNode *node) +{ + if (node) + return node->next; + + return NULL; +} + +void +_cdio_list_node_free (CdioListNode *node, int free_data) +{ + CdioList *list; + CdioListNode *prev_node; + + cdio_assert (node != NULL); + + list = node->list; + + cdio_assert (_cdio_list_length (list) > 0); + + if (free_data) + free (_cdio_list_node_data (node)); + + if (_cdio_list_length (list) == 1) + { + cdio_assert (list->begin == list->end); + + list->end = list->begin = NULL; + list->length = 0; + free (node); + return; + } + + cdio_assert (list->begin != list->end); + + if (list->begin == node) + { + list->begin = node->next; + free (node); + list->length--; + return; + } + + for (prev_node = list->begin; prev_node->next; prev_node = prev_node->next) + if (prev_node->next == node) + break; + + cdio_assert (prev_node->next != NULL); + + if (list->end == node) + list->end = prev_node; + + prev_node->next = node->next; + + list->length--; + + free (node); +} + +void * +_cdio_list_node_data (CdioListNode *node) +{ + if (node) + return node->data; + + return NULL; +} + +/* eof */ + + +/* + * Local variables: + * c-file-style: "gnu" + * tab-width: 8 + * indent-tabs-mode: nil + * End: + */ + |