Imported Upstream version 58.1
[platform/upstream/icu.git] / source / common / ulist.c
index 6b5013b..7f7fdd9 100644 (file)
@@ -1,6 +1,8 @@
+// Copyright (C) 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 ******************************************************************************
-*   Copyright (C) 2009-2014, International Business Machines
+*   Copyright (C) 2009-2016, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 ******************************************************************************
 */
@@ -63,18 +65,45 @@ static void ulist_addFirstItem(UList *list, UListNode *newItem) {
     newItem->previous = NULL;
     list->head = newItem;
     list->tail = newItem;
+}
+
+static void ulist_removeItem(UList *list, UListNode *p) {
+    if (p->previous == NULL) {
+        // p is the list head.
+        list->head = p->next;
+    } else {
+        p->previous->next = p->next;
+    }
+    if (p->next == NULL) {
+        // p is the list tail.
+        list->tail = p->previous;
+    } else {
+        p->next->previous = p->previous;
+    }
+    list->curr = NULL;
     list->currentIndex = 0;
+    --list->size;
+    if (p->forceDelete) {
+        uprv_free(p->data);
+    }
+    uprv_free(p);
 }
 
 U_CAPI void U_EXPORT2 ulist_addItemEndList(UList *list, const void *data, UBool forceDelete, UErrorCode *status) {
     UListNode *newItem = NULL;
     
     if (U_FAILURE(*status) || list == NULL || data == NULL) {
+        if (forceDelete) {
+            uprv_free((void *)data);
+        }
         return;
     }
     
     newItem = (UListNode *)uprv_malloc(sizeof(UListNode));
     if (newItem == NULL) {
+        if (forceDelete) {
+            uprv_free((void *)data);
+        }
         *status = U_MEMORY_ALLOCATION_ERROR;
         return;
     }
@@ -97,11 +126,17 @@ U_CAPI void U_EXPORT2 ulist_addItemBeginList(UList *list, const void *data, UBoo
     UListNode *newItem = NULL;
     
     if (U_FAILURE(*status) || list == NULL || data == NULL) {
+        if (forceDelete) {
+            uprv_free((void *)data);
+        }
         return;
     }
     
     newItem = (UListNode *)uprv_malloc(sizeof(UListNode));
     if (newItem == NULL) {
+        if (forceDelete) {
+            uprv_free((void *)data);
+        }
         *status = U_MEMORY_ALLOCATION_ERROR;
         return;
     }
@@ -122,25 +157,31 @@ U_CAPI void U_EXPORT2 ulist_addItemBeginList(UList *list, const void *data, UBoo
 }
 
 U_CAPI UBool U_EXPORT2 ulist_containsString(const UList *list, const char *data, int32_t length) {
-    UBool result = FALSE;
-    const UListNode *pointer = NULL;
-    
-    if (list != NULL && list->size != 0) {
-        pointer = list->head;
-        
-        while (pointer != NULL) {
+    if (list != NULL) {
+        const UListNode *pointer;
+        for (pointer = list->head; pointer != NULL; pointer = pointer->next) {
             if (length == uprv_strlen(pointer->data)) {
                 if (uprv_memcmp(data, pointer->data, length) == 0) {
-                    result = TRUE;
-                    break;
+                    return TRUE;
                 }
             }
-            
-            pointer = pointer->next;
         }
     }
-    
-    return result;
+    return FALSE;
+}
+
+U_CAPI UBool U_EXPORT2 ulist_removeString(UList *list, const char *data) {
+    if (list != NULL) {
+        UListNode *pointer;
+        for (pointer = list->head; pointer != NULL; pointer = pointer->next) {
+            if (uprv_strcmp(data, pointer->data) == 0) {
+                ulist_removeItem(list, pointer);
+                // Remove only the first occurrence, like Java LinkedList.remove(Object).
+                return TRUE;
+            }
+        }
+    }
+    return FALSE;
 }
 
 U_CAPI void *U_EXPORT2 ulist_getNext(UList *list) {