Azure IoT common library
Fork of azure_c_shared_utility by
Diff: singlylinkedlist.c
- Revision:
- 30:ce3813c5a692
- Parent:
- 21:b92006c5b9ff
diff -r e3ed192c35fb -r ce3813c5a692 singlylinkedlist.c --- a/singlylinkedlist.c Fri Jun 30 10:42:00 2017 -0700 +++ b/singlylinkedlist.c Fri Jul 14 16:38:40 2017 -0700 @@ -5,6 +5,7 @@ #include "azure_c_shared_utility/gballoc.h" #include "azure_c_shared_utility/singlylinkedlist.h" #include "azure_c_shared_utility/optimize_size.h" +#include "azure_c_shared_utility/xlogging.h" typedef struct LIST_ITEM_INSTANCE_TAG { @@ -59,6 +60,7 @@ if ((list == NULL) || (item == NULL)) { + LogError("Invalid argument (list=%p, item=%p)", list, item); result = NULL; } else @@ -105,6 +107,7 @@ if ((list == NULL) || (item == NULL)) { + LogError("Invalid argument (list=%p, item=%p)", list, item); result = __FAILURE__; } else @@ -156,7 +159,8 @@ if (list == NULL) { /* Codes_SRS_LIST_01_009: [If the list argument is NULL, singlylinkedlist_get_head_item shall return NULL.] */ - result = NULL; + LogError("Invalid argument (list=NULL)"); + result = NULL; } else { @@ -176,6 +180,7 @@ if (item_handle == NULL) { + LogError("Invalid argument (list is NULL)"); /* Codes_SRS_LIST_01_019: [If item_handle is NULL then singlylinkedlist_get_next_item shall return NULL.] */ result = NULL; } @@ -194,6 +199,7 @@ if (item_handle == NULL) { + LogError("Invalid argument (item_handle is NULL)"); /* Codes_SRS_LIST_01_021: [If item_handle is NULL, singlylinkedlist_item_get_value shall return NULL.] */ result = NULL; } @@ -213,6 +219,7 @@ if ((list == NULL) || (match_function == NULL)) { + LogError("Invalid argument (list=%p, match_function=%p)", list, match_function); /* Codes_SRS_LIST_01_012: [If the list or the match_function argument is NULL, singlylinkedlist_find shall return NULL.] */ result = NULL; } @@ -249,3 +256,103 @@ return result; } + +int singlylinkedlist_remove_if(SINGLYLINKEDLIST_HANDLE list, LIST_CONDITION_FUNCTION condition_function, const void* match_context) +{ + int result; + /* Codes_SRS_LIST_09_001: [ If the list or the condition_function argument is NULL, singlylinkedlist_remove_if shall return non-zero value. ] */ + if ((list == NULL) || + (condition_function == NULL)) + { + LogError("Invalid argument (list=%p, condition_function=%p)", list, condition_function); + result = __FAILURE__; + } + else + { + LIST_INSTANCE* list_instance = (LIST_INSTANCE*)list; + LIST_ITEM_INSTANCE* current_item = list_instance->head; + LIST_ITEM_INSTANCE* next_item = NULL; + LIST_ITEM_INSTANCE* previous_item = NULL; + + /* Codes_SRS_LIST_09_002: [ singlylinkedlist_remove_if shall iterate through all items in a list and remove all that satisfies a certain condition function. ] */ + while (current_item != NULL) + { + bool continue_processing = false; + + next_item = (LIST_ITEM_INSTANCE*)current_item->next; + + /* Codes_SRS_LIST_09_003: [ singlylinkedlist_remove_if shall determine whether an item satisfies the condition criteria by invoking the condition function for that item. ] */ + /* Codes_SRS_LIST_09_004: [ If the condition function returns true, singlylinkedlist_find shall consider that item as to be removed. ] */ + if (condition_function(current_item->item, match_context, &continue_processing) == true) + { + if (previous_item != NULL) + { + previous_item->next = next_item; + } + else + { + list_instance->head = next_item; + } + + free(current_item); + } + /* Codes_SRS_LIST_09_005: [ If the condition function returns false, singlylinkedlist_find shall consider that item as not to be removed. ] */ + else + { + previous_item = current_item; + } + + /* Codes_SRS_LIST_09_006: [ If the condition function returns continue_processing as false, singlylinkedlist_remove_if shall stop iterating through the list and return. ] */ + if (continue_processing == false) + { + break; + } + + current_item = next_item; + } + + /* Codes_SRS_LIST_09_007: [ If no errors occur, singlylinkedlist_remove_if shall return zero. ] */ + result = 0; + } + + return result; +} + +int singlylinkedlist_foreach(SINGLYLINKEDLIST_HANDLE list, LIST_ACTION_FUNCTION action_function, const void* action_context) +{ + int result; + + /* Codes_SRS_LIST_09_008: [ If the list or the action_function argument is NULL, singlylinkedlist_foreach shall return non-zero value. ] */ + if ((list == NULL) || + (action_function == NULL)) + { + LogError("Invalid argument (list=%p, action_function=%p)", list, action_function); + result = __FAILURE__; + } + else + { + LIST_INSTANCE* list_instance = (LIST_INSTANCE*)list; + LIST_ITEM_INSTANCE* list_item = list_instance->head; + + while (list_item != NULL) + { + bool continue_processing = false; + + /* Codes_SRS_LIST_09_009: [ singlylinkedlist_foreach shall iterate through all items in a list and invoke action_function for each one of them. ] */ + action_function(list_item->item, action_context, &continue_processing); + + /* Codes_SRS_LIST_09_010: [ If the condition function returns continue_processing as false, singlylinkedlist_foreach shall stop iterating through the list and return. ] */ + if (continue_processing == false) + { + break; + } + + list_item = (LIST_ITEM_INSTANCE*)list_item->next; + } + + /* Codes_SRS_LIST_09_011: [ If no errors occur, singlylinkedlist_foreach shall return zero. ] */ + result = 0; + } + + return result; +} \ No newline at end of file