11cb0ef41Sopenharmony_ci// © 2016 and later: Unicode, Inc. and others. 21cb0ef41Sopenharmony_ci// License & terms of use: http://www.unicode.org/copyright.html 31cb0ef41Sopenharmony_ci/* 41cb0ef41Sopenharmony_ci****************************************************************************** 51cb0ef41Sopenharmony_ci* Copyright (C) 1999-2015, International Business Machines Corporation and 61cb0ef41Sopenharmony_ci* others. All Rights Reserved. 71cb0ef41Sopenharmony_ci****************************************************************************** 81cb0ef41Sopenharmony_ci*/ 91cb0ef41Sopenharmony_ci 101cb0ef41Sopenharmony_ci#include "uvectr64.h" 111cb0ef41Sopenharmony_ci#include "cmemory.h" 121cb0ef41Sopenharmony_ci#include "putilimp.h" 131cb0ef41Sopenharmony_ci 141cb0ef41Sopenharmony_ciU_NAMESPACE_BEGIN 151cb0ef41Sopenharmony_ci 161cb0ef41Sopenharmony_ci#define DEFAULT_CAPACITY 8 171cb0ef41Sopenharmony_ci 181cb0ef41Sopenharmony_ci/* 191cb0ef41Sopenharmony_ci * Constants for hinting whether a key is an integer 201cb0ef41Sopenharmony_ci * or a pointer. If a hint bit is zero, then the associated 211cb0ef41Sopenharmony_ci * token is assumed to be an integer. This is needed for iSeries 221cb0ef41Sopenharmony_ci */ 231cb0ef41Sopenharmony_ci 241cb0ef41Sopenharmony_ciUOBJECT_DEFINE_RTTI_IMPLEMENTATION(UVector64) 251cb0ef41Sopenharmony_ci 261cb0ef41Sopenharmony_ciUVector64::UVector64(UErrorCode &status) : 271cb0ef41Sopenharmony_ci count(0), 281cb0ef41Sopenharmony_ci capacity(0), 291cb0ef41Sopenharmony_ci maxCapacity(0), 301cb0ef41Sopenharmony_ci elements(nullptr) 311cb0ef41Sopenharmony_ci{ 321cb0ef41Sopenharmony_ci _init(DEFAULT_CAPACITY, status); 331cb0ef41Sopenharmony_ci} 341cb0ef41Sopenharmony_ci 351cb0ef41Sopenharmony_ciUVector64::UVector64(int32_t initialCapacity, UErrorCode &status) : 361cb0ef41Sopenharmony_ci count(0), 371cb0ef41Sopenharmony_ci capacity(0), 381cb0ef41Sopenharmony_ci maxCapacity(0), 391cb0ef41Sopenharmony_ci elements(0) 401cb0ef41Sopenharmony_ci{ 411cb0ef41Sopenharmony_ci _init(initialCapacity, status); 421cb0ef41Sopenharmony_ci} 431cb0ef41Sopenharmony_ci 441cb0ef41Sopenharmony_ci 451cb0ef41Sopenharmony_ci 461cb0ef41Sopenharmony_civoid UVector64::_init(int32_t initialCapacity, UErrorCode &status) { 471cb0ef41Sopenharmony_ci // Fix bogus initialCapacity values; avoid malloc(0) 481cb0ef41Sopenharmony_ci if (initialCapacity < 1) { 491cb0ef41Sopenharmony_ci initialCapacity = DEFAULT_CAPACITY; 501cb0ef41Sopenharmony_ci } 511cb0ef41Sopenharmony_ci if (maxCapacity>0 && maxCapacity<initialCapacity) { 521cb0ef41Sopenharmony_ci initialCapacity = maxCapacity; 531cb0ef41Sopenharmony_ci } 541cb0ef41Sopenharmony_ci if (initialCapacity > (int32_t)(INT32_MAX / sizeof(int64_t))) { 551cb0ef41Sopenharmony_ci initialCapacity = uprv_min(DEFAULT_CAPACITY, maxCapacity); 561cb0ef41Sopenharmony_ci } 571cb0ef41Sopenharmony_ci elements = (int64_t *)uprv_malloc(sizeof(int64_t)*initialCapacity); 581cb0ef41Sopenharmony_ci if (elements == 0) { 591cb0ef41Sopenharmony_ci status = U_MEMORY_ALLOCATION_ERROR; 601cb0ef41Sopenharmony_ci } else { 611cb0ef41Sopenharmony_ci capacity = initialCapacity; 621cb0ef41Sopenharmony_ci } 631cb0ef41Sopenharmony_ci} 641cb0ef41Sopenharmony_ci 651cb0ef41Sopenharmony_ciUVector64::~UVector64() { 661cb0ef41Sopenharmony_ci uprv_free(elements); 671cb0ef41Sopenharmony_ci elements = 0; 681cb0ef41Sopenharmony_ci} 691cb0ef41Sopenharmony_ci 701cb0ef41Sopenharmony_ci/** 711cb0ef41Sopenharmony_ci * Assign this object to another (make this a copy of 'other'). 721cb0ef41Sopenharmony_ci */ 731cb0ef41Sopenharmony_civoid UVector64::assign(const UVector64& other, UErrorCode &ec) { 741cb0ef41Sopenharmony_ci if (ensureCapacity(other.count, ec)) { 751cb0ef41Sopenharmony_ci setSize(other.count); 761cb0ef41Sopenharmony_ci for (int32_t i=0; i<other.count; ++i) { 771cb0ef41Sopenharmony_ci elements[i] = other.elements[i]; 781cb0ef41Sopenharmony_ci } 791cb0ef41Sopenharmony_ci } 801cb0ef41Sopenharmony_ci} 811cb0ef41Sopenharmony_ci 821cb0ef41Sopenharmony_ci 831cb0ef41Sopenharmony_cibool UVector64::operator==(const UVector64& other) { 841cb0ef41Sopenharmony_ci int32_t i; 851cb0ef41Sopenharmony_ci if (count != other.count) return false; 861cb0ef41Sopenharmony_ci for (i=0; i<count; ++i) { 871cb0ef41Sopenharmony_ci if (elements[i] != other.elements[i]) { 881cb0ef41Sopenharmony_ci return false; 891cb0ef41Sopenharmony_ci } 901cb0ef41Sopenharmony_ci } 911cb0ef41Sopenharmony_ci return true; 921cb0ef41Sopenharmony_ci} 931cb0ef41Sopenharmony_ci 941cb0ef41Sopenharmony_ci 951cb0ef41Sopenharmony_civoid UVector64::setElementAt(int64_t elem, int32_t index) { 961cb0ef41Sopenharmony_ci if (0 <= index && index < count) { 971cb0ef41Sopenharmony_ci elements[index] = elem; 981cb0ef41Sopenharmony_ci } 991cb0ef41Sopenharmony_ci /* else index out of range */ 1001cb0ef41Sopenharmony_ci} 1011cb0ef41Sopenharmony_ci 1021cb0ef41Sopenharmony_civoid UVector64::insertElementAt(int64_t elem, int32_t index, UErrorCode &status) { 1031cb0ef41Sopenharmony_ci // must have 0 <= index <= count 1041cb0ef41Sopenharmony_ci if (0 <= index && index <= count && ensureCapacity(count + 1, status)) { 1051cb0ef41Sopenharmony_ci for (int32_t i=count; i>index; --i) { 1061cb0ef41Sopenharmony_ci elements[i] = elements[i-1]; 1071cb0ef41Sopenharmony_ci } 1081cb0ef41Sopenharmony_ci elements[index] = elem; 1091cb0ef41Sopenharmony_ci ++count; 1101cb0ef41Sopenharmony_ci } 1111cb0ef41Sopenharmony_ci /* else index out of range */ 1121cb0ef41Sopenharmony_ci} 1131cb0ef41Sopenharmony_ci 1141cb0ef41Sopenharmony_civoid UVector64::removeAllElements() { 1151cb0ef41Sopenharmony_ci count = 0; 1161cb0ef41Sopenharmony_ci} 1171cb0ef41Sopenharmony_ci 1181cb0ef41Sopenharmony_ciUBool UVector64::expandCapacity(int32_t minimumCapacity, UErrorCode &status) { 1191cb0ef41Sopenharmony_ci if (U_FAILURE(status)) { 1201cb0ef41Sopenharmony_ci return false; 1211cb0ef41Sopenharmony_ci } 1221cb0ef41Sopenharmony_ci if (minimumCapacity < 0) { 1231cb0ef41Sopenharmony_ci status = U_ILLEGAL_ARGUMENT_ERROR; 1241cb0ef41Sopenharmony_ci return false; 1251cb0ef41Sopenharmony_ci } 1261cb0ef41Sopenharmony_ci if (capacity >= minimumCapacity) { 1271cb0ef41Sopenharmony_ci return true; 1281cb0ef41Sopenharmony_ci } 1291cb0ef41Sopenharmony_ci if (maxCapacity>0 && minimumCapacity>maxCapacity) { 1301cb0ef41Sopenharmony_ci status = U_BUFFER_OVERFLOW_ERROR; 1311cb0ef41Sopenharmony_ci return false; 1321cb0ef41Sopenharmony_ci } 1331cb0ef41Sopenharmony_ci if (capacity > (INT32_MAX - 1) / 2) { // integer overflow check 1341cb0ef41Sopenharmony_ci status = U_ILLEGAL_ARGUMENT_ERROR; 1351cb0ef41Sopenharmony_ci return false; 1361cb0ef41Sopenharmony_ci } 1371cb0ef41Sopenharmony_ci int32_t newCap = capacity * 2; 1381cb0ef41Sopenharmony_ci if (newCap < minimumCapacity) { 1391cb0ef41Sopenharmony_ci newCap = minimumCapacity; 1401cb0ef41Sopenharmony_ci } 1411cb0ef41Sopenharmony_ci if (maxCapacity > 0 && newCap > maxCapacity) { 1421cb0ef41Sopenharmony_ci newCap = maxCapacity; 1431cb0ef41Sopenharmony_ci } 1441cb0ef41Sopenharmony_ci if (newCap > (int32_t)(INT32_MAX / sizeof(int64_t))) { // integer overflow check 1451cb0ef41Sopenharmony_ci // We keep the original memory contents on bad minimumCapacity/maxCapacity. 1461cb0ef41Sopenharmony_ci status = U_ILLEGAL_ARGUMENT_ERROR; 1471cb0ef41Sopenharmony_ci return false; 1481cb0ef41Sopenharmony_ci } 1491cb0ef41Sopenharmony_ci int64_t* newElems = (int64_t *)uprv_realloc(elements, sizeof(int64_t)*newCap); 1501cb0ef41Sopenharmony_ci if (newElems == nullptr) { 1511cb0ef41Sopenharmony_ci // We keep the original contents on the memory failure on realloc. 1521cb0ef41Sopenharmony_ci status = U_MEMORY_ALLOCATION_ERROR; 1531cb0ef41Sopenharmony_ci return false; 1541cb0ef41Sopenharmony_ci } 1551cb0ef41Sopenharmony_ci elements = newElems; 1561cb0ef41Sopenharmony_ci capacity = newCap; 1571cb0ef41Sopenharmony_ci return true; 1581cb0ef41Sopenharmony_ci} 1591cb0ef41Sopenharmony_ci 1601cb0ef41Sopenharmony_civoid UVector64::setMaxCapacity(int32_t limit) { 1611cb0ef41Sopenharmony_ci U_ASSERT(limit >= 0); 1621cb0ef41Sopenharmony_ci if (limit < 0) { 1631cb0ef41Sopenharmony_ci limit = 0; 1641cb0ef41Sopenharmony_ci } 1651cb0ef41Sopenharmony_ci if (limit > (int32_t)(INT32_MAX / sizeof(int64_t))) { // integer overflow check for realloc 1661cb0ef41Sopenharmony_ci // Something is very wrong, don't realloc, leave capacity and maxCapacity unchanged 1671cb0ef41Sopenharmony_ci return; 1681cb0ef41Sopenharmony_ci } 1691cb0ef41Sopenharmony_ci maxCapacity = limit; 1701cb0ef41Sopenharmony_ci if (capacity <= maxCapacity || maxCapacity == 0) { 1711cb0ef41Sopenharmony_ci // Current capacity is within the new limit. 1721cb0ef41Sopenharmony_ci return; 1731cb0ef41Sopenharmony_ci } 1741cb0ef41Sopenharmony_ci 1751cb0ef41Sopenharmony_ci // New maximum capacity is smaller than the current size. 1761cb0ef41Sopenharmony_ci // Realloc the storage to the new, smaller size. 1771cb0ef41Sopenharmony_ci int64_t* newElems = (int64_t *)uprv_realloc(elements, sizeof(int64_t)*maxCapacity); 1781cb0ef41Sopenharmony_ci if (newElems == nullptr) { 1791cb0ef41Sopenharmony_ci // Realloc to smaller failed. 1801cb0ef41Sopenharmony_ci // Just keep what we had. No need to call it a failure. 1811cb0ef41Sopenharmony_ci return; 1821cb0ef41Sopenharmony_ci } 1831cb0ef41Sopenharmony_ci elements = newElems; 1841cb0ef41Sopenharmony_ci capacity = maxCapacity; 1851cb0ef41Sopenharmony_ci if (count > capacity) { 1861cb0ef41Sopenharmony_ci count = capacity; 1871cb0ef41Sopenharmony_ci } 1881cb0ef41Sopenharmony_ci} 1891cb0ef41Sopenharmony_ci 1901cb0ef41Sopenharmony_ci/** 1911cb0ef41Sopenharmony_ci * Change the size of this vector as follows: If newSize is smaller, 1921cb0ef41Sopenharmony_ci * then truncate the array, possibly deleting held elements for i >= 1931cb0ef41Sopenharmony_ci * newSize. If newSize is larger, grow the array, filling in new 1941cb0ef41Sopenharmony_ci * slots with nullptr. 1951cb0ef41Sopenharmony_ci */ 1961cb0ef41Sopenharmony_civoid UVector64::setSize(int32_t newSize) { 1971cb0ef41Sopenharmony_ci int32_t i; 1981cb0ef41Sopenharmony_ci if (newSize < 0) { 1991cb0ef41Sopenharmony_ci return; 2001cb0ef41Sopenharmony_ci } 2011cb0ef41Sopenharmony_ci if (newSize > count) { 2021cb0ef41Sopenharmony_ci UErrorCode ec = U_ZERO_ERROR; 2031cb0ef41Sopenharmony_ci if (!ensureCapacity(newSize, ec)) { 2041cb0ef41Sopenharmony_ci return; 2051cb0ef41Sopenharmony_ci } 2061cb0ef41Sopenharmony_ci for (i=count; i<newSize; ++i) { 2071cb0ef41Sopenharmony_ci elements[i] = 0; 2081cb0ef41Sopenharmony_ci } 2091cb0ef41Sopenharmony_ci } 2101cb0ef41Sopenharmony_ci count = newSize; 2111cb0ef41Sopenharmony_ci} 2121cb0ef41Sopenharmony_ci 2131cb0ef41Sopenharmony_ciU_NAMESPACE_END 2141cb0ef41Sopenharmony_ci 215