diff -r 000000000000 -r 6474c204b198 intl/icu/source/common/uvectr32.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/intl/icu/source/common/uvectr32.cpp Wed Dec 31 06:09:35 2014 +0100 @@ -0,0 +1,330 @@ +/* +****************************************************************************** +* Copyright (C) 1999-2010, International Business Machines Corporation and * +* others. All Rights Reserved. * +****************************************************************************** +* Date Name Description +* 10/22/99 alan Creation. +********************************************************************** +*/ + +#include "uvectr32.h" +#include "cmemory.h" +#include "putilimp.h" + +U_NAMESPACE_BEGIN + +#define DEFAULT_CAPACITY 8 + +/* + * Constants for hinting whether a key is an integer + * or a pointer. If a hint bit is zero, then the associated + * token is assumed to be an integer. This is needed for iSeries + */ + +UOBJECT_DEFINE_RTTI_IMPLEMENTATION(UVector32) + +UVector32::UVector32(UErrorCode &status) : + count(0), + capacity(0), + maxCapacity(0), + elements(NULL) +{ + _init(DEFAULT_CAPACITY, status); +} + +UVector32::UVector32(int32_t initialCapacity, UErrorCode &status) : + count(0), + capacity(0), + maxCapacity(0), + elements(0) +{ + _init(initialCapacity, status); +} + + + +void UVector32::_init(int32_t initialCapacity, UErrorCode &status) { + // Fix bogus initialCapacity values; avoid malloc(0) + if (initialCapacity < 1) { + initialCapacity = DEFAULT_CAPACITY; + } + if (maxCapacity>0 && maxCapacity (int32_t)(INT32_MAX / sizeof(int32_t))) { + initialCapacity = uprv_min(DEFAULT_CAPACITY, maxCapacity); + } + elements = (int32_t *)uprv_malloc(sizeof(int32_t)*initialCapacity); + if (elements == 0) { + status = U_MEMORY_ALLOCATION_ERROR; + } else { + capacity = initialCapacity; + } +} + +UVector32::~UVector32() { + uprv_free(elements); + elements = 0; +} + +/** + * Assign this object to another (make this a copy of 'other'). + */ +void UVector32::assign(const UVector32& other, UErrorCode &ec) { + if (ensureCapacity(other.count, ec)) { + setSize(other.count); + for (int32_t i=0; iindex; --i) { + elements[i] = elements[i-1]; + } + elements[index] = elem; + ++count; + } + /* else index out of range */ +} + +UBool UVector32::containsAll(const UVector32& other) const { + for (int32_t i=0; i= 0) { + return FALSE; + } + } + return TRUE; +} + +UBool UVector32::removeAll(const UVector32& other) { + UBool changed = FALSE; + for (int32_t i=0; i= 0) { + removeElementAt(j); + changed = TRUE; + } + } + return changed; +} + +UBool UVector32::retainAll(const UVector32& other) { + UBool changed = FALSE; + for (int32_t j=size()-1; j>=0; --j) { + int32_t i = other.indexOf(elements[j]); + if (i < 0) { + removeElementAt(j); + changed = TRUE; + } + } + return changed; +} + +void UVector32::removeElementAt(int32_t index) { + if (index >= 0) { + for (int32_t i=index; icount != other.count) { + return FALSE; + } + for (i=0; i= minimumCapacity) { + return TRUE; + } + if (maxCapacity>0 && minimumCapacity>maxCapacity) { + status = U_BUFFER_OVERFLOW_ERROR; + return FALSE; + } + if (capacity > (INT32_MAX - 1) / 2) { // integer overflow check + status = U_ILLEGAL_ARGUMENT_ERROR; + return FALSE; + } + int32_t newCap = capacity * 2; + if (newCap < minimumCapacity) { + newCap = minimumCapacity; + } + if (maxCapacity > 0 && newCap > maxCapacity) { + newCap = maxCapacity; + } + if (newCap > (int32_t)(INT32_MAX / sizeof(int32_t))) { // integer overflow check + // We keep the original memory contents on bad minimumCapacity/maxCapacity. + status = U_ILLEGAL_ARGUMENT_ERROR; + return FALSE; + } + 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); + if (limit < 0) { + limit = 0; + } + if (limit > (int32_t)(INT32_MAX / sizeof(int32_t))) { // integer overflow check for realloc + // Something is very wrong, don't realloc, leave capacity and maxCapacity unchanged + return; + } + maxCapacity = limit; + 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; + } +} + +/** + * Change the size of this vector as follows: If newSize is smaller, + * then truncate the array, possibly deleting held elements for i >= + * newSize. If newSize is larger, grow the array, filling in new + * slots with NULL. + */ +void UVector32::setSize(int32_t newSize) { + int32_t i; + if (newSize < 0) { + return; + } + if (newSize > count) { + UErrorCode ec = U_ZERO_ERROR; + if (!ensureCapacity(newSize, ec)) { + return; + } + for (i=count; i 0) { + if (elements[probe] > tok) { + max = probe; + } else { + // assert(c <= 0); + min = probe + 1; + } + } + if (ensureCapacity(count + 1, ec)) { + for (int32_t i=count; i>min; --i) { + elements[i] = elements[i-1]; + } + elements[min] = tok; + ++count; + } +} + + + + + +U_NAMESPACE_END +