/////////////////////////////////////////////////////////////////////////////// // Date: Sat Oct 13 20:28:10 CDT 2007 // Author: John Quigley // Revision: $Id$ // // 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 3 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, see . /////////////////////////////////////////////////////////////////////////////// #include #include "core/util.h" #include "core/core.h" #include "core/gc.h" ListNode* __List_getIndex(List *self, int index); Boolean *__List_removeNode(List *self, ListNode *node); List* List_new() { List *new = NULL; new = (List *)WGC_allocate(sizeof(List)); new->length = 0; new->iterating = Boolean_new(); new->list_head = NULL; new->list_tail = NULL; new->iter_node = NULL; return new; } void List_delete(List *object) { while(object->length > 0) { __List_removeNode(object, object->list_tail); } WGC_deallocate(object); } void List_resetIteration(List *self) { self->iterating = False; } void* List_iterate(List *self) { void *retval = NULL; if (!self->iterating) { self->iter_node = self->list_head; Boolean_setValue(self->iterating, True); } if (self->iter_node != NULL) { retval = self->iter_node->data; self->iter_node = self->iter_node->next_node; } return retval; } int List_getLength(List *self) { return self->length; } void *List_getIndex(List *self, int index) { void *retval = NULL; ListNode *node = NULL; if ((node = __List_getIndex(self, index)) != NULL) { retval = node->data; } return retval; } Boolean *List_append(List *self, void *data) { Boolean *retval = Boolean_new(); Boolean_setValue(retval, True); ListNode *new_node = (ListNode *)WGC_allocate(sizeof(ListNode)); new_node->data = data; new_node->next_node = NULL; new_node->prev_node = self->list_tail; /* empty list */ if (self->length == 0) { self->list_head = new_node; self->list_tail = new_node; } else { self->list_tail->next_node = new_node; self->list_tail = new_node; } self->length++; return retval; } void *List_remove(List *self, int index) { ListNode *removed = __List_getIndex(self, index); __List_removeNode(self, removed); return removed->data; } ListNode* __List_getIndex(List *self, int index) { void *retval = NULL; if (0 == index) { retval = self->list_head->data; } else if (index == (self->length - 1)) { retval = self->list_tail->data; } else if (index < self->length) { ListNode* at_node = self->list_head; for (int i = 0; i < index; i++) { at_node = at_node->next_node; } retval = at_node->data; } return retval; } Boolean *__List_removeNode(List *self, ListNode *node) { Boolean *retval = Boolean_new(); Boolean_setValue(retval, True); if (node == self->list_tail) { self->list_tail = node->prev_node; } else if(node == self->list_head) { self->list_head = node->next_node; } self->length--; if (node->prev_node != NULL) { node->prev_node->next_node = node->next_node; } if (node->next_node != NULL) { node->next_node->prev_node = node->prev_node; } WGC_deallocate(node); return retval; } // EOF