1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/intl/icu/source/common/ulist.c Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,236 @@ 1.4 +/* 1.5 +****************************************************************************** 1.6 +* Copyright (C) 2009-2012, International Business Machines 1.7 +* Corporation and others. All Rights Reserved. 1.8 +****************************************************************************** 1.9 +*/ 1.10 + 1.11 +#include "ulist.h" 1.12 +#include "cmemory.h" 1.13 +#include "cstring.h" 1.14 +#include "uenumimp.h" 1.15 + 1.16 +typedef struct UListNode UListNode; 1.17 +struct UListNode { 1.18 + void *data; 1.19 + 1.20 + UListNode *next; 1.21 + UListNode *previous; 1.22 + 1.23 + /* When data is created with uprv_malloc, needs to be freed during deleteList function. */ 1.24 + UBool forceDelete; 1.25 +}; 1.26 + 1.27 +struct UList { 1.28 + UListNode *curr; 1.29 + UListNode *head; 1.30 + UListNode *tail; 1.31 + 1.32 + int32_t size; 1.33 + int32_t currentIndex; 1.34 +}; 1.35 + 1.36 +static void ulist_addFirstItem(UList *list, UListNode *newItem); 1.37 + 1.38 +U_CAPI UList *U_EXPORT2 ulist_createEmptyList(UErrorCode *status) { 1.39 + UList *newList = NULL; 1.40 + 1.41 + if (U_FAILURE(*status)) { 1.42 + return NULL; 1.43 + } 1.44 + 1.45 + newList = (UList *)uprv_malloc(sizeof(UList)); 1.46 + if (newList == NULL) { 1.47 + *status = U_MEMORY_ALLOCATION_ERROR; 1.48 + return NULL; 1.49 + } 1.50 + 1.51 + newList->curr = NULL; 1.52 + newList->head = NULL; 1.53 + newList->tail = NULL; 1.54 + newList->size = 0; 1.55 + newList->currentIndex = -1; 1.56 + 1.57 + return newList; 1.58 +} 1.59 + 1.60 +/* 1.61 + * Function called by addItemEndList or addItemBeginList when the first item is added to the list. 1.62 + * This function properly sets the pointers for the first item added. 1.63 + */ 1.64 +static void ulist_addFirstItem(UList *list, UListNode *newItem) { 1.65 + newItem->next = NULL; 1.66 + newItem->previous = NULL; 1.67 + list->head = newItem; 1.68 + list->tail = newItem; 1.69 + list->currentIndex = 0; 1.70 +} 1.71 + 1.72 +U_CAPI void U_EXPORT2 ulist_addItemEndList(UList *list, const void *data, UBool forceDelete, UErrorCode *status) { 1.73 + UListNode *newItem = NULL; 1.74 + 1.75 + if (U_FAILURE(*status) || list == NULL || data == NULL) { 1.76 + return; 1.77 + } 1.78 + 1.79 + newItem = (UListNode *)uprv_malloc(sizeof(UListNode)); 1.80 + if (newItem == NULL) { 1.81 + *status = U_MEMORY_ALLOCATION_ERROR; 1.82 + return; 1.83 + } 1.84 + newItem->data = (void *)(data); 1.85 + newItem->forceDelete = forceDelete; 1.86 + 1.87 + if (list->size == 0) { 1.88 + ulist_addFirstItem(list, newItem); 1.89 + } else { 1.90 + newItem->next = NULL; 1.91 + newItem->previous = list->tail; 1.92 + list->tail->next = newItem; 1.93 + list->tail = newItem; 1.94 + } 1.95 + 1.96 + list->size++; 1.97 +} 1.98 + 1.99 +U_CAPI void U_EXPORT2 ulist_addItemBeginList(UList *list, const void *data, UBool forceDelete, UErrorCode *status) { 1.100 + UListNode *newItem = NULL; 1.101 + 1.102 + if (U_FAILURE(*status) || list == NULL || data == NULL) { 1.103 + return; 1.104 + } 1.105 + 1.106 + newItem = (UListNode *)uprv_malloc(sizeof(UListNode)); 1.107 + if (newItem == NULL) { 1.108 + *status = U_MEMORY_ALLOCATION_ERROR; 1.109 + return; 1.110 + } 1.111 + newItem->data = (void *)(data); 1.112 + newItem->forceDelete = forceDelete; 1.113 + 1.114 + if (list->size == 0) { 1.115 + ulist_addFirstItem(list, newItem); 1.116 + } else { 1.117 + newItem->previous = NULL; 1.118 + newItem->next = list->head; 1.119 + list->head->previous = newItem; 1.120 + list->head = newItem; 1.121 + list->currentIndex++; 1.122 + } 1.123 + 1.124 + list->size++; 1.125 +} 1.126 + 1.127 +U_CAPI UBool U_EXPORT2 ulist_containsString(const UList *list, const char *data, int32_t length) { 1.128 + UBool result = FALSE; 1.129 + const UListNode *pointer = NULL; 1.130 + 1.131 + if (list != NULL && list->size != 0) { 1.132 + pointer = list->head; 1.133 + 1.134 + while (pointer != NULL) { 1.135 + if (length == uprv_strlen(pointer->data)) { 1.136 + if (uprv_memcmp(data, pointer->data, length) == 0) { 1.137 + result = TRUE; 1.138 + break; 1.139 + } 1.140 + } 1.141 + 1.142 + pointer = pointer->next; 1.143 + } 1.144 + } 1.145 + 1.146 + return result; 1.147 +} 1.148 + 1.149 +U_CAPI void *U_EXPORT2 ulist_getNext(UList *list) { 1.150 + UListNode *curr = NULL; 1.151 + 1.152 + if (list == NULL || list->curr == NULL) { 1.153 + return NULL; 1.154 + } 1.155 + 1.156 + curr = list->curr; 1.157 + list->curr = curr->next; 1.158 + list->currentIndex++; 1.159 + 1.160 + return curr->data; 1.161 +} 1.162 + 1.163 +U_CAPI int32_t U_EXPORT2 ulist_getListSize(const UList *list) { 1.164 + if (list != NULL) { 1.165 + return list->size; 1.166 + } 1.167 + 1.168 + return -1; 1.169 +} 1.170 + 1.171 +U_CAPI void U_EXPORT2 ulist_resetList(UList *list) { 1.172 + if (list != NULL) { 1.173 + list->curr = list->head; 1.174 + list->currentIndex = 0; 1.175 + } 1.176 +} 1.177 + 1.178 +U_CAPI void U_EXPORT2 ulist_deleteList(UList *list) { 1.179 + UListNode *listHead = NULL; 1.180 + UListNode *listPointer = NULL; 1.181 + 1.182 + if (list != NULL) { 1.183 + listHead = list->head; 1.184 + listPointer = listHead; 1.185 + while (listHead != NULL) { 1.186 + listPointer = listHead->next; 1.187 + 1.188 + if (listHead->forceDelete) { 1.189 + uprv_free(listHead->data); 1.190 + } 1.191 + 1.192 + uprv_free(listHead); 1.193 + listHead = listPointer; 1.194 + } 1.195 + uprv_free(list); 1.196 + list = NULL; 1.197 + } 1.198 +} 1.199 + 1.200 +U_CAPI void U_EXPORT2 ulist_close_keyword_values_iterator(UEnumeration *en) { 1.201 + if (en != NULL) { 1.202 + ulist_deleteList((UList *)(en->context)); 1.203 + uprv_free(en); 1.204 + } 1.205 +} 1.206 + 1.207 +U_CAPI int32_t U_EXPORT2 ulist_count_keyword_values(UEnumeration *en, UErrorCode *status) { 1.208 + if (U_FAILURE(*status)) { 1.209 + return -1; 1.210 + } 1.211 + 1.212 + return ulist_getListSize((UList *)(en->context)); 1.213 +} 1.214 + 1.215 +U_CAPI const char * U_EXPORT2 ulist_next_keyword_value(UEnumeration *en, int32_t *resultLength, UErrorCode *status) { 1.216 + const char *s; 1.217 + if (U_FAILURE(*status)) { 1.218 + return NULL; 1.219 + } 1.220 + 1.221 + s = (const char *)ulist_getNext((UList *)(en->context)); 1.222 + if (s != NULL && resultLength != NULL) { 1.223 + *resultLength = uprv_strlen(s); 1.224 + } 1.225 + return s; 1.226 +} 1.227 + 1.228 +U_CAPI void U_EXPORT2 ulist_reset_keyword_values_iterator(UEnumeration *en, UErrorCode *status) { 1.229 + if (U_FAILURE(*status)) { 1.230 + return ; 1.231 + } 1.232 + 1.233 + ulist_resetList((UList *)(en->context)); 1.234 +} 1.235 + 1.236 +U_CAPI UList * U_EXPORT2 ulist_getListFromEnum(UEnumeration *en) { 1.237 + return (UList *)(en->context); 1.238 +} 1.239 +