/** * Copyright (c) 2021 Dominic Msters * * This software is released under the MIT License. * https://opensource.org/licenses/MIT */ #include "list.h" list_t * listCreate() { list_t *list = malloc(sizeof(list_t)); if(list == NULL) return NULL; list->start = NULL; list->end = NULL; list->size = 0; return list; } listentry_t * listAdd(list_t *list, void *data) { //Create the list entry listentry_t *entry = malloc(sizeof(listentry_t)); if(entry == NULL) return NULL; entry->data = data; entry->next = NULL; entry->prev = NULL; //Add it to the list listAddEntry(list, entry); //Return the entry return entry; } void listAddEntry(list_t *list, listentry_t *entry) { //Is this the first / only thing in the list? if(list->start == NULL) { list->start = entry; list->end = entry; } else { //Make the end's next be this entry, and this entry's prev the end, then //make this the new end entry->prev = list->end; list->end->next = entry; list->end = entry; } list->size++; } void listRemove(list_t *list, void *data) { uint32_t i = 0; listentry_t *previous = list->start; while(previous != NULL) { if(previous->data == data) { listRemoveEntry(list, previous, false); break; } i++; previous = previous->next; } } void listRemoveEntry(list_t *list, listentry_t *entry, bool freeData) { //Update next and prev if(entry->prev != NULL) entry->prev->next = entry->next; if(entry->next != NULL) entry->next->prev = entry->prev; //Was this at the end? if(list->start == entry) list->start = entry->next; if(list->end == entry) list->end = entry->prev; if(freeData) free(entry->data); free(entry); list->size--; } listentry_t * listGetByIndex(list_t *list, uint32_t index) { if(index >= list->size) return NULL; // TODO: We can probably make this more efficient by deciding which way we // should loop from based on the list size. uint32_t i = 0; listentry_t *previous = list->start; while(previous != NULL) { if(i == index) return previous; i++; previous = previous->next; } return NULL; } uint32_t listGetIndex(list_t *list, void* data) { uint32_t i = 0; listentry_t *previous = list->start; while(previous != NULL) { if(previous->data == data) return i; i++; previous = previous->next; } return -1; } uint32_t listGetEntryIndex(list_t *list, listentry_t *entry) { uint32_t i = 0; listentry_t *previous = list->start; while(previous != NULL) { if(previous == entry) return i; i++; previous = previous->next; } return -1; } void listDispose(list_t *list, bool freeData) { //Free all of the entries listentry_t *next = list->start; listentry_t *current; while(next != NULL) { current = next; next = current->next; if(freeData) free(current->data); free(current); } free(list); }