1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/intl/icu/source/common/uvectr64.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,209 @@ 1.4 +/* 1.5 +****************************************************************************** 1.6 +* Copyright (C) 1999-2010, International Business Machines Corporation and * 1.7 +* others. All Rights Reserved. * 1.8 +****************************************************************************** 1.9 +*/ 1.10 + 1.11 +#include "uvectr64.h" 1.12 +#include "cmemory.h" 1.13 +#include "putilimp.h" 1.14 + 1.15 +U_NAMESPACE_BEGIN 1.16 + 1.17 +#define DEFAULT_CAPACITY 8 1.18 + 1.19 +/* 1.20 + * Constants for hinting whether a key is an integer 1.21 + * or a pointer. If a hint bit is zero, then the associated 1.22 + * token is assumed to be an integer. This is needed for iSeries 1.23 + */ 1.24 + 1.25 +UOBJECT_DEFINE_RTTI_IMPLEMENTATION(UVector64) 1.26 + 1.27 +UVector64::UVector64(UErrorCode &status) : 1.28 + count(0), 1.29 + capacity(0), 1.30 + maxCapacity(0), 1.31 + elements(NULL) 1.32 +{ 1.33 + _init(DEFAULT_CAPACITY, status); 1.34 +} 1.35 + 1.36 +UVector64::UVector64(int32_t initialCapacity, UErrorCode &status) : 1.37 + count(0), 1.38 + capacity(0), 1.39 + maxCapacity(0), 1.40 + elements(0) 1.41 +{ 1.42 + _init(initialCapacity, status); 1.43 +} 1.44 + 1.45 + 1.46 + 1.47 +void UVector64::_init(int32_t initialCapacity, UErrorCode &status) { 1.48 + // Fix bogus initialCapacity values; avoid malloc(0) 1.49 + if (initialCapacity < 1) { 1.50 + initialCapacity = DEFAULT_CAPACITY; 1.51 + } 1.52 + if (maxCapacity>0 && maxCapacity<initialCapacity) { 1.53 + initialCapacity = maxCapacity; 1.54 + } 1.55 + if (initialCapacity > (int32_t)(INT32_MAX / sizeof(int64_t))) { 1.56 + initialCapacity = uprv_min(DEFAULT_CAPACITY, maxCapacity); 1.57 + } 1.58 + elements = (int64_t *)uprv_malloc(sizeof(int64_t)*initialCapacity); 1.59 + if (elements == 0) { 1.60 + status = U_MEMORY_ALLOCATION_ERROR; 1.61 + } else { 1.62 + capacity = initialCapacity; 1.63 + } 1.64 +} 1.65 + 1.66 +UVector64::~UVector64() { 1.67 + uprv_free(elements); 1.68 + elements = 0; 1.69 +} 1.70 + 1.71 +/** 1.72 + * Assign this object to another (make this a copy of 'other'). 1.73 + */ 1.74 +void UVector64::assign(const UVector64& other, UErrorCode &ec) { 1.75 + if (ensureCapacity(other.count, ec)) { 1.76 + setSize(other.count); 1.77 + for (int32_t i=0; i<other.count; ++i) { 1.78 + elements[i] = other.elements[i]; 1.79 + } 1.80 + } 1.81 +} 1.82 + 1.83 + 1.84 +UBool UVector64::operator==(const UVector64& other) { 1.85 + int32_t i; 1.86 + if (count != other.count) return FALSE; 1.87 + for (i=0; i<count; ++i) { 1.88 + if (elements[i] != other.elements[i]) { 1.89 + return FALSE; 1.90 + } 1.91 + } 1.92 + return TRUE; 1.93 +} 1.94 + 1.95 + 1.96 +void UVector64::setElementAt(int64_t elem, int32_t index) { 1.97 + if (0 <= index && index < count) { 1.98 + elements[index] = elem; 1.99 + } 1.100 + /* else index out of range */ 1.101 +} 1.102 + 1.103 +void UVector64::insertElementAt(int64_t elem, int32_t index, UErrorCode &status) { 1.104 + // must have 0 <= index <= count 1.105 + if (0 <= index && index <= count && ensureCapacity(count + 1, status)) { 1.106 + for (int32_t i=count; i>index; --i) { 1.107 + elements[i] = elements[i-1]; 1.108 + } 1.109 + elements[index] = elem; 1.110 + ++count; 1.111 + } 1.112 + /* else index out of range */ 1.113 +} 1.114 + 1.115 +void UVector64::removeAllElements(void) { 1.116 + count = 0; 1.117 +} 1.118 + 1.119 +UBool UVector64::expandCapacity(int32_t minimumCapacity, UErrorCode &status) { 1.120 + if (minimumCapacity < 0) { 1.121 + status = U_ILLEGAL_ARGUMENT_ERROR; 1.122 + return FALSE; 1.123 + } 1.124 + if (capacity >= minimumCapacity) { 1.125 + return TRUE; 1.126 + } 1.127 + if (maxCapacity>0 && minimumCapacity>maxCapacity) { 1.128 + status = U_BUFFER_OVERFLOW_ERROR; 1.129 + return FALSE; 1.130 + } 1.131 + if (capacity > (INT32_MAX - 1) / 2) { // integer overflow check 1.132 + status = U_ILLEGAL_ARGUMENT_ERROR; 1.133 + return FALSE; 1.134 + } 1.135 + int32_t newCap = capacity * 2; 1.136 + if (newCap < minimumCapacity) { 1.137 + newCap = minimumCapacity; 1.138 + } 1.139 + if (maxCapacity > 0 && newCap > maxCapacity) { 1.140 + newCap = maxCapacity; 1.141 + } 1.142 + if (newCap > (int32_t)(INT32_MAX / sizeof(int64_t))) { // integer overflow check 1.143 + // We keep the original memory contents on bad minimumCapacity/maxCapacity. 1.144 + status = U_ILLEGAL_ARGUMENT_ERROR; 1.145 + return FALSE; 1.146 + } 1.147 + int64_t* newElems = (int64_t *)uprv_realloc(elements, sizeof(int64_t)*newCap); 1.148 + if (newElems == NULL) { 1.149 + // We keep the original contents on the memory failure on realloc. 1.150 + status = U_MEMORY_ALLOCATION_ERROR; 1.151 + return FALSE; 1.152 + } 1.153 + elements = newElems; 1.154 + capacity = newCap; 1.155 + return TRUE; 1.156 +} 1.157 + 1.158 +void UVector64::setMaxCapacity(int32_t limit) { 1.159 + U_ASSERT(limit >= 0); 1.160 + if (limit < 0) { 1.161 + limit = 0; 1.162 + } 1.163 + if (limit > (int32_t)(INT32_MAX / sizeof(int64_t))) { // integer overflow check for realloc 1.164 + // Something is very wrong, don't realloc, leave capacity and maxCapacity unchanged 1.165 + return; 1.166 + } 1.167 + maxCapacity = limit; 1.168 + if (capacity <= maxCapacity || maxCapacity == 0) { 1.169 + // Current capacity is within the new limit. 1.170 + return; 1.171 + } 1.172 + 1.173 + // New maximum capacity is smaller than the current size. 1.174 + // Realloc the storage to the new, smaller size. 1.175 + int64_t* newElems = (int64_t *)uprv_realloc(elements, sizeof(int64_t)*maxCapacity); 1.176 + if (newElems == NULL) { 1.177 + // Realloc to smaller failed. 1.178 + // Just keep what we had. No need to call it a failure. 1.179 + return; 1.180 + } 1.181 + elements = newElems; 1.182 + capacity = maxCapacity; 1.183 + if (count > capacity) { 1.184 + count = capacity; 1.185 + } 1.186 +} 1.187 + 1.188 +/** 1.189 + * Change the size of this vector as follows: If newSize is smaller, 1.190 + * then truncate the array, possibly deleting held elements for i >= 1.191 + * newSize. If newSize is larger, grow the array, filling in new 1.192 + * slots with NULL. 1.193 + */ 1.194 +void UVector64::setSize(int32_t newSize) { 1.195 + int32_t i; 1.196 + if (newSize < 0) { 1.197 + return; 1.198 + } 1.199 + if (newSize > count) { 1.200 + UErrorCode ec = U_ZERO_ERROR; 1.201 + if (!ensureCapacity(newSize, ec)) { 1.202 + return; 1.203 + } 1.204 + for (i=count; i<newSize; ++i) { 1.205 + elements[i] = 0; 1.206 + } 1.207 + } 1.208 + count = newSize; 1.209 +} 1.210 + 1.211 +U_NAMESPACE_END 1.212 +