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