#include "ua_list.h" #include "ua_util.h" void UA_list_defaultFreer(void* payload){ if(payload){ UA_free(payload); } } UA_Int32 UA_list_initElement(UA_list_Element* element){ if(element==UA_NULL) return UA_ERROR; element->next=UA_NULL; element->prev=UA_NULL; element->father=UA_NULL; element->payload=UA_NULL; return UA_NO_ERROR; } UA_Int32 UA_list_init(UA_list_List* list){ if(list==UA_NULL) return UA_ERROR; list->first = UA_NULL; list->last = UA_NULL; list->size = 0; return UA_NO_ERROR; } UA_Int32 UA_list_addElementToFront(UA_list_List* list, UA_list_Element* element){ if(list==UA_NULL || element==UA_NULL) return UA_ERROR; UA_list_Element* second = UA_NULL; second = list->first; list->first = element; element->prev = UA_NULL; element->next = second; element->father = list; if(second){ second->prev=element; } list->size++; if(list->size==1){ list->last=element; } return UA_NO_ERROR; } UA_Int32 UA_list_addPayloadToFront(UA_list_List* list, void* const payload){ if(list==UA_NULL)return UA_ERROR; UA_list_Element* elem; UA_alloc((void**)&elem, sizeof(*elem)); UA_list_initElement(elem); elem->payload = payload; UA_list_addElementToFront(list, elem); return UA_NO_ERROR; } UA_Int32 UA_list_addElementToBack(UA_list_List* list, UA_list_Element* element){ if(list==UA_NULL || element == UA_NULL)return UA_ERROR; UA_list_Element* secondLast = UA_NULL; secondLast = list->last; list->last = element; element->prev = secondLast; element->next = UA_NULL; element->father = list; if(secondLast){ secondLast->next = element; } list->size++; if(list->size==1){ list->first=element; } return UA_NO_ERROR; } UA_Int32 UA_list_addPayloadToBack(UA_list_List* list, void* const payload){ if(list==UA_NULL)return UA_ERROR; UA_list_Element* elem; UA_alloc((void**)&elem, sizeof(*elem)); UA_list_initElement(elem); elem->payload = payload; UA_list_addElementToBack(list, elem); return UA_NO_ERROR; } UA_Int32 UA_list_removeFirst(UA_list_List* list, UA_list_PayloadVisitor visitor){ if(list==UA_NULL)return UA_ERROR; UA_list_Element* temp = UA_NULL; if(list->first){ temp = list->first->next; if(visitor){ (*visitor)(list->first->payload); } UA_free(list->first); list->first = temp; temp->prev = UA_NULL; list->size--; if(list->size == 1){ list->last = temp; }else if(list->size==0){ list->last = UA_NULL; } } return UA_NO_ERROR; } UA_Int32 UA_list_removeLast(UA_list_List* list, UA_list_PayloadVisitor visitor){ if(list==UA_NULL)return UA_ERROR; UA_list_Element* temp = UA_NULL; if(list->last){ temp = list->last->prev; if(visitor){ (*visitor)(list->last->payload); } UA_free(list->last); list->last = temp; temp->next = UA_NULL; list->size--; if(list->size == 1){ list->first = temp; list->first->next = UA_NULL; }else if(list->size==0){ list->first = UA_NULL; } } return UA_NO_ERROR; } UA_Int32 UA_list_removeElement(UA_list_Element* const elem, UA_list_PayloadVisitor visitor){ if(elem==UA_NULL)return UA_ERROR; if(elem==elem->father->first){ return UA_list_removeFirst(elem->father, visitor); }else if(elem==elem->father->last){ return UA_list_removeLast(elem->father, visitor); }else{ UA_list_Element* prev = elem->prev; UA_list_Element* next = elem->next; prev->next = next; next->prev = prev; if(visitor){ (*visitor)(elem->payload); } (elem->father)->size--; UA_free(elem); } return UA_NO_ERROR; } UA_Int32 UA_list_destroy(UA_list_List* list, UA_list_PayloadVisitor visitor){ if(list==UA_NULL)return UA_ERROR; UA_list_Element* current = UA_NULL; current=list->first; while(current){ UA_list_Element* next = current->next; if(visitor){ (*visitor)(current->payload); } UA_free(current); current = next; } UA_list_init(list); return UA_NO_ERROR; } UA_Int32 UA_list_iterateElement(UA_list_List* const list, UA_list_ElementVisitor visitor){ if(list==UA_NULL)return UA_ERROR; UA_list_Element* current = list->first; while(current){ if(visitor){ (*visitor)(current); } current=current->next; } return UA_NO_ERROR; } /*Int32 UA_list_iteratePayload(UA_list_list* const list, UA_payloadVisitor visitor){ void visitorTemp(UA_list_element* element){ if(visitor){ (*visitor)(element->payload); } } if(list==NULL)return UA_ERROR; UA_list_iterateElement(list, visitorTemp); return UA_NO_ERROR; }*/ /** ANSI C forbids function nesting - reworked ugly version **/ UA_Int32 UA_list_iteratePayload(UA_list_List* const list, UA_list_PayloadVisitor visitor){ if(list==UA_NULL)return UA_ERROR; UA_list_Element* current = list->first; while(current){ if(visitor){ (*visitor)(current->payload); } current=current->next; } return UA_NO_ERROR; } UA_list_Element* UA_list_find(UA_list_List* const list, UA_list_PayloadMatcher matcher){ if(list==UA_NULL)return UA_NULL; if(matcher){ UA_list_Element* current = list->first; while(current){ if(matcher && (*matcher)(current->payload)==TRUE){ return current; } current=current->next; } } /* nothing found */ return UA_NULL; } UA_list_Element* UA_list_search(UA_list_List* const list, UA_list_PayloadComparer compare, void* payload){ if(list==UA_NULL)return UA_NULL; if(compare){ UA_list_Element* current = list->first; while(current){ if(compare && (*compare)(current->payload, payload)==TRUE){ return current; } current=current->next; } } /* nothing found */ return UA_NULL; } UA_list_Element* UA_list_getFirst(UA_list_List* const list){ if(list==UA_NULL)return UA_NULL; return list->first; } UA_list_Element* UA_list_getLast(UA_list_List* const list){ if(list==UA_NULL)return UA_NULL; return list->last; }