tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

uvectr64.cpp (5982B)


      1 // © 2016 and later: Unicode, Inc. and others.
      2 // License & terms of use: http://www.unicode.org/copyright.html
      3 /*
      4 ******************************************************************************
      5 * Copyright (C) 1999-2015, International Business Machines Corporation and
      6 * others. All Rights Reserved.
      7 ******************************************************************************
      8 */
      9 
     10 #include "uvectr64.h"
     11 #include "cmemory.h"
     12 #include "putilimp.h"
     13 
     14 U_NAMESPACE_BEGIN
     15 
     16 #define DEFAULT_CAPACITY 8
     17 
     18 /*
     19 * Constants for hinting whether a key is an integer
     20 * or a pointer.  If a hint bit is zero, then the associated
     21 * token is assumed to be an integer. This is needed for iSeries
     22 */
     23 
     24 UOBJECT_DEFINE_RTTI_IMPLEMENTATION(UVector64)
     25 
     26 UVector64::UVector64(UErrorCode &status) :
     27    count(0),
     28    capacity(0),
     29    maxCapacity(0),
     30    elements(nullptr)
     31 {
     32    _init(DEFAULT_CAPACITY, status);
     33 }
     34 
     35 UVector64::UVector64(int32_t initialCapacity, UErrorCode &status) :
     36    count(0),
     37    capacity(0),
     38    maxCapacity(0),
     39    elements(nullptr)
     40 {
     41    _init(initialCapacity, status);
     42 }
     43 
     44 
     45 
     46 void UVector64::_init(int32_t initialCapacity, UErrorCode &status) {
     47    // Fix bogus initialCapacity values; avoid malloc(0)
     48    if (initialCapacity < 1) {
     49        initialCapacity = DEFAULT_CAPACITY;
     50    }
     51    if (maxCapacity>0 && maxCapacity<initialCapacity) {
     52        initialCapacity = maxCapacity;
     53    }
     54    if (initialCapacity > static_cast<int32_t>(INT32_MAX / sizeof(int64_t))) {
     55        initialCapacity = uprv_min(DEFAULT_CAPACITY, maxCapacity);
     56    }
     57    elements = static_cast<int64_t*>(uprv_malloc(sizeof(int64_t) * initialCapacity));
     58    if (elements == nullptr) {
     59        status = U_MEMORY_ALLOCATION_ERROR;
     60    } else {
     61        capacity = initialCapacity;
     62    }
     63 }
     64 
     65 UVector64::~UVector64() {
     66    uprv_free(elements);
     67    elements = nullptr;
     68 }
     69 
     70 /**
     71 * Assign this object to another (make this a copy of 'other').
     72 */
     73 void UVector64::assign(const UVector64& other, UErrorCode &ec) {
     74    if (ensureCapacity(other.count, ec)) {
     75        setSize(other.count);
     76        for (int32_t i=0; i<other.count; ++i) {
     77            elements[i] = other.elements[i];
     78        }
     79    }
     80 }
     81 
     82 
     83 bool UVector64::operator==(const UVector64& other) {
     84    int32_t i;
     85    if (count != other.count) return false;
     86    for (i=0; i<count; ++i) {
     87        if (elements[i] != other.elements[i]) {
     88            return false;
     89        }
     90    }
     91    return true;
     92 }
     93 
     94 
     95 void UVector64::setElementAt(int64_t elem, int32_t index) {
     96    if (0 <= index && index < count) {
     97        elements[index] = elem;
     98    }
     99    /* else index out of range */
    100 }
    101 
    102 void UVector64::insertElementAt(int64_t elem, int32_t index, UErrorCode &status) {
    103    // must have 0 <= index <= count
    104    if (0 <= index && index <= count && ensureCapacity(count + 1, status)) {
    105        for (int32_t i=count; i>index; --i) {
    106            elements[i] = elements[i-1];
    107        }
    108        elements[index] = elem;
    109        ++count;
    110    }
    111    /* else index out of range */
    112 }
    113 
    114 void UVector64::removeAllElements() {
    115    count = 0;
    116 }
    117 
    118 UBool UVector64::expandCapacity(int32_t minimumCapacity, UErrorCode &status) {
    119    if (U_FAILURE(status)) {
    120        return false;
    121    }
    122    if (minimumCapacity < 0) {
    123        status = U_ILLEGAL_ARGUMENT_ERROR;
    124        return false;
    125    }
    126    if (capacity >= minimumCapacity) {
    127        return true;
    128    }
    129    if (maxCapacity>0 && minimumCapacity>maxCapacity) {
    130        status = U_BUFFER_OVERFLOW_ERROR;
    131        return false;
    132    }
    133    if (capacity > (INT32_MAX - 1) / 2) {  // integer overflow check
    134        status = U_ILLEGAL_ARGUMENT_ERROR;
    135        return false;
    136    }
    137    int32_t newCap = capacity * 2;
    138    if (newCap < minimumCapacity) {
    139        newCap = minimumCapacity;
    140    }
    141    if (maxCapacity > 0 && newCap > maxCapacity) {
    142        newCap = maxCapacity;
    143    }
    144    if (newCap > static_cast<int32_t>(INT32_MAX / sizeof(int64_t))) { // integer overflow check
    145        // We keep the original memory contents on bad minimumCapacity/maxCapacity.
    146        status = U_ILLEGAL_ARGUMENT_ERROR;
    147        return false;
    148    }
    149    int64_t* newElems = static_cast<int64_t*>(uprv_realloc(elements, sizeof(int64_t) * newCap));
    150    if (newElems == nullptr) {
    151        // We keep the original contents on the memory failure on realloc.
    152        status = U_MEMORY_ALLOCATION_ERROR;
    153        return false;
    154    }
    155    elements = newElems;
    156    capacity = newCap;
    157    return true;
    158 }
    159 
    160 void UVector64::setMaxCapacity(int32_t limit) {
    161    U_ASSERT(limit >= 0);
    162    if (limit < 0) {
    163        limit = 0;
    164    }
    165    if (limit > static_cast<int32_t>(INT32_MAX / sizeof(int64_t))) { // integer overflow check for realloc
    166        //  Something is very wrong, don't realloc, leave capacity and maxCapacity unchanged
    167        return;
    168    }
    169    maxCapacity = limit;
    170    if (capacity <= maxCapacity || maxCapacity == 0) {
    171        // Current capacity is within the new limit.
    172        return;
    173    }
    174    
    175    // New maximum capacity is smaller than the current size.
    176    // Realloc the storage to the new, smaller size.
    177    int64_t* newElems = static_cast<int64_t*>(uprv_realloc(elements, sizeof(int64_t) * maxCapacity));
    178    if (newElems == nullptr) {
    179        // Realloc to smaller failed.
    180        //   Just keep what we had.  No need to call it a failure.
    181        return;
    182    }
    183    elements = newElems;
    184    capacity = maxCapacity;
    185    if (count > capacity) {
    186        count = capacity;
    187    }
    188 }
    189 
    190 /**
    191 * Change the size of this vector as follows: If newSize is smaller,
    192 * then truncate the array, possibly deleting held elements for i >=
    193 * newSize.  If newSize is larger, grow the array, filling in new
    194 * slots with nullptr.
    195 */
    196 void UVector64::setSize(int32_t newSize) {
    197    int32_t i;
    198    if (newSize < 0) {
    199        return;
    200    }
    201    if (newSize > count) {
    202        UErrorCode ec = U_ZERO_ERROR;
    203        if (!ensureCapacity(newSize, ec)) {
    204            return;
    205        }
    206        for (i=count; i<newSize; ++i) {
    207            elements[i] = 0;
    208        }
    209    } 
    210    count = newSize;
    211 }
    212 
    213 U_NAMESPACE_END