]> git.saurik.com Git - apple/icu.git/blobdiff - icuSources/common/uvectr32.cpp
ICU-400.37.tar.gz
[apple/icu.git] / icuSources / common / uvectr32.cpp
index e0dd4cbb325e92a959457da8aa828cbd785d6fec..2ccb90635256bce5fc745d1afa639c36e63f1957 100644 (file)
@@ -1,6 +1,6 @@
 /*
 ******************************************************************************
-* Copyright (C) 1999-2003, International Business Machines Corporation and   *
+* Copyright (C) 1999-2008, International Business Machines Corporation and   *
 * others. All Rights Reserved.                                               *
 ******************************************************************************
 *   Date        Name        Description
@@ -26,6 +26,7 @@ UOBJECT_DEFINE_RTTI_IMPLEMENTATION(UVector32)
 UVector32::UVector32(UErrorCode &status) :
     count(0),
     capacity(0),
+    maxCapacity(0),
     elements(NULL)
 {
     _init(DEFUALT_CAPACITY, status);
@@ -34,6 +35,7 @@ UVector32::UVector32(UErrorCode &status) :
 UVector32::UVector32(int32_t initialCapacity, UErrorCode &status) :
     count(0),
     capacity(0),
+    maxCapacity(0),
     elements(0)
 {
     _init(initialCapacity, status);
@@ -46,6 +48,9 @@ void UVector32::_init(int32_t initialCapacity, UErrorCode &status) {
     if (initialCapacity < 1) {
         initialCapacity = DEFUALT_CAPACITY;
     }
+    if (maxCapacity>0 && maxCapacity<initialCapacity) {
+        initialCapacity = maxCapacity;
+    }
     elements = (int32_t *)uprv_malloc(sizeof(int32_t)*initialCapacity);
     if (elements == 0) {
         status = U_MEMORY_ALLOCATION_ERROR;
@@ -189,21 +194,52 @@ int32_t UVector32::indexOf(int32_t key, int32_t startIndex) const {
 UBool UVector32::expandCapacity(int32_t minimumCapacity, UErrorCode &status) {
     if (capacity >= minimumCapacity) {
         return TRUE;
-    } else {
-        int32_t newCap = capacity * 2;
-        if (newCap < minimumCapacity) {
-            newCap = minimumCapacity;
-        }
-        int32_t* newElems = (int32_t *)uprv_malloc(sizeof(int32_t)*newCap);
-        if (newElems == 0) {
-            status = U_MEMORY_ALLOCATION_ERROR;
-            return FALSE;
-        }
-        uprv_memcpy(newElems, elements, sizeof(elements[0]) * count);
-        uprv_free(elements);
-        elements = newElems;
-        capacity = newCap;
-        return TRUE;
+    }
+    if (maxCapacity>0 && minimumCapacity>maxCapacity) {
+        status = U_BUFFER_OVERFLOW_ERROR;
+        return FALSE;
+    }
+    int32_t newCap = capacity * 2;
+    if (newCap < minimumCapacity) {
+        newCap = minimumCapacity;
+    }
+    if (maxCapacity > 0 && newCap > maxCapacity) {
+        newCap = maxCapacity;
+    }
+    int32_t* newElems = (int32_t *)uprv_realloc(elements, sizeof(int32_t)*newCap);
+    if (newElems == NULL) {
+        // We keep the original contents on the memory failure on realloc.
+        status = U_MEMORY_ALLOCATION_ERROR;
+        return FALSE;
+    }
+    elements = newElems;
+    capacity = newCap;
+    return TRUE;
+}
+
+void UVector32::setMaxCapacity(int32_t limit) {
+    U_ASSERT(limit >= 0);
+    maxCapacity = limit;
+    if (maxCapacity < 0) {
+        maxCapacity = 0;
+    }
+    if (capacity <= maxCapacity || maxCapacity == 0) {
+        // Current capacity is within the new limit.
+        return;
+    }
+    
+    // New maximum capacity is smaller than the current size.
+    // Realloc the storage to the new, smaller size.
+    int32_t* newElems = (int32_t *)uprv_realloc(elements, sizeof(int32_t)*maxCapacity);
+    if (newElems == NULL) {
+        // Realloc to smaller failed.
+        //   Just keep what we had.  No need to call it a failure.
+        return;
+    }
+    elements = newElems;
+    capacity = maxCapacity;
+    if (count > capacity) {
+        count = capacity;
     }
 }