/* 2004.02.01 first released source code for IOMP */ /* * Copyright (C) 2000-2002 the xine project * * This file is part of xine, a unix video player. * * xine 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. * * xine 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 * * $Id: list.c,v 1.2 2003/11/25 04:26:12 georgedon Exp $ * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include "xineutils.h" /* * create a new, empty list */ xine_list_t *xine_list_new (void) { xine_list_t *list; list = (xine_list_t *) xine_xmalloc(sizeof(xine_list_t)); list->first=NULL; list->last =NULL; list->cur =NULL; return list; } /* * dispose a list (and only the list, contents have to be managed separately) * TODO: this is easy to fix by using "content destructors" */ void xine_list_free(xine_list_t *l) { xine_node_t *node; if (!l) { fprintf(stderr, "%s(): No list.\n", __XINE_FUNCTION__); return; } if(!l->first) { return; } node = l->first; while(node) { xine_node_t *n = node; /* TODO: support for content destructors */ node = n->next; free(n); } l->first = l->cur = l->last = NULL; /* FIXME: free(l) instead */ } void *xine_list_first_content (xine_list_t *l) { l->cur = l->first; if (l->first) return l->first->content; else return NULL; } void *xine_list_next_content (xine_list_t *l) { if (l->cur) { if (l->cur->next) { l->cur = l->cur->next; return l->cur->content; } else return NULL; } else { fprintf(stderr,"%s() WARNING: passed end of list\n", __XINE_FUNCTION__); return NULL; } } int xine_list_is_empty (xine_list_t *l) { if (l == NULL){ fprintf(stderr, "%s(): list is NULL\n", __XINE_FUNCTION__); return -1; } return (l->first != NULL); } void *xine_list_last_content (xine_list_t *l) { if (l->last) { l->cur = l->last; return l->last->content; } else { fprintf(stderr, "xine_list: wanted last of empty list\n"); return NULL; } } void *xine_list_prev_content (xine_list_t *l) { if (l->cur) { if (l->cur->prev) { l->cur = l->cur->prev; return l->cur->content; } else return NULL; } else { fprintf(stderr, "xine_list: passed begin of list\n"); return NULL; } } void xine_list_append_priority_content (xine_list_t *l, void *content, int priority) { xine_node_t *node; node = (xine_node_t *) xine_xmalloc(sizeof(xine_node_t)); node->content = content; node->priority = priority; if (l->first) { xine_node_t *cur; cur = l->first; while(1) { if( priority >= cur->priority ) { node->next = cur; node->prev = cur->prev; if( node->prev ) node->prev->next = node; else l->first = node; cur->prev = node; l->cur = node; break; } if( !cur->next ) { node->next = NULL; node->prev = cur; cur->next = node; l->cur = node; l->last = node; break; } cur = cur->next; } } else { l->first = l->last = l->cur = node; node->prev = node->next = NULL; } } void xine_list_append_content (xine_list_t *l, void *content) { xine_node_t *node; node = (xine_node_t *) xine_xmalloc(sizeof(xine_node_t)); node->content = content; if (l->last) { node->next = NULL; node->prev = l->last; l->last->next = node; l->last = node; l->cur = node; } else { l->first = l->last = l->cur = node; node->prev = node->next = NULL; } } void xine_list_insert_content (xine_list_t *l, void *content) { xine_node_t *nodecur, *nodenext, *nodenew; if(l->cur->next) { nodenew = (xine_node_t *) xine_xmalloc(sizeof(xine_node_t)); nodenew->content = content; nodecur = l->cur; nodenext = l->cur->next; nodecur->next = nodenew; nodenext->prev = nodenew; nodenew->prev = nodecur; nodenew->next = nodenext; l->cur = nodenew; } else { /* current is last, append to the list */ xine_list_append_content(l, content); } } void xine_list_delete_current (xine_list_t *l) { xine_node_t *node_cur; node_cur = l->cur; if(node_cur->prev) { node_cur->prev->next = node_cur->next; } else { /* First entry */ l->first = node_cur->next; } if(node_cur->next) { node_cur->next->prev = node_cur->prev; l->cur = node_cur->next; } else { /* last entry in the list */ l->last = node_cur->prev; l->cur = node_cur->prev; } /* TODO: support content destructors */ free(node_cur); }