intl/icu/source/common/uvectr64.cpp

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

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

mercurial