Coverage Report

Created: 2023-02-22 06:51

/src/icu/source/common/uvectr64.cpp
Line
Count
Source (jump to first uncovered line)
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
0
#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(NULL)
31
0
{
32
0
    _init(DEFAULT_CAPACITY, status);
33
0
}
34
35
UVector64::UVector64(int32_t initialCapacity, UErrorCode &status) :
36
    count(0),
37
    capacity(0),
38
    maxCapacity(0),
39
    elements(0)
40
0
{
41
0
    _init(initialCapacity, status);
42
0
}
43
44
45
46
0
void UVector64::_init(int32_t initialCapacity, UErrorCode &status) {
47
    // Fix bogus initialCapacity values; avoid malloc(0)
48
0
    if (initialCapacity < 1) {
49
0
        initialCapacity = DEFAULT_CAPACITY;
50
0
    }
51
0
    if (maxCapacity>0 && maxCapacity<initialCapacity) {
52
0
        initialCapacity = maxCapacity;
53
0
    }
54
0
    if (initialCapacity > (int32_t)(INT32_MAX / sizeof(int64_t))) {
55
0
        initialCapacity = uprv_min(DEFAULT_CAPACITY, maxCapacity);
56
0
    }
57
0
    elements = (int64_t *)uprv_malloc(sizeof(int64_t)*initialCapacity);
58
0
    if (elements == 0) {
59
0
        status = U_MEMORY_ALLOCATION_ERROR;
60
0
    } else {
61
0
        capacity = initialCapacity;
62
0
    }
63
0
}
64
65
0
UVector64::~UVector64() {
66
0
    uprv_free(elements);
67
0
    elements = 0;
68
0
}
69
70
/**
71
 * Assign this object to another (make this a copy of 'other').
72
 */
73
0
void UVector64::assign(const UVector64& other, UErrorCode &ec) {
74
0
    if (ensureCapacity(other.count, ec)) {
75
0
        setSize(other.count);
76
0
        for (int32_t i=0; i<other.count; ++i) {
77
0
            elements[i] = other.elements[i];
78
0
        }
79
0
    }
80
0
}
81
82
83
0
bool UVector64::operator==(const UVector64& other) {
84
0
    int32_t i;
85
0
    if (count != other.count) return FALSE;
86
0
    for (i=0; i<count; ++i) {
87
0
        if (elements[i] != other.elements[i]) {
88
0
            return FALSE;
89
0
        }
90
0
    }
91
0
    return TRUE;
92
0
}
93
94
95
0
void UVector64::setElementAt(int64_t elem, int32_t index) {
96
0
    if (0 <= index && index < count) {
97
0
        elements[index] = elem;
98
0
    }
99
    /* else index out of range */
100
0
}
101
102
0
void UVector64::insertElementAt(int64_t elem, int32_t index, UErrorCode &status) {
103
    // must have 0 <= index <= count
104
0
    if (0 <= index && index <= count && ensureCapacity(count + 1, status)) {
105
0
        for (int32_t i=count; i>index; --i) {
106
0
            elements[i] = elements[i-1];
107
0
        }
108
0
        elements[index] = elem;
109
0
        ++count;
110
0
    }
111
    /* else index out of range */
112
0
}
113
114
0
void UVector64::removeAllElements(void) {
115
0
    count = 0;
116
0
}
117
118
0
UBool UVector64::expandCapacity(int32_t minimumCapacity, UErrorCode &status) {
119
0
    if (U_FAILURE(status)) {
120
0
        return FALSE;
121
0
    }
122
0
    if (minimumCapacity < 0) {
123
0
        status = U_ILLEGAL_ARGUMENT_ERROR;
124
0
        return FALSE;
125
0
    }
126
0
    if (capacity >= minimumCapacity) {
127
0
        return TRUE;
128
0
    }
129
0
    if (maxCapacity>0 && minimumCapacity>maxCapacity) {
130
0
        status = U_BUFFER_OVERFLOW_ERROR;
131
0
        return FALSE;
132
0
    }
133
0
    if (capacity > (INT32_MAX - 1) / 2) {  // integer overflow check
134
0
        status = U_ILLEGAL_ARGUMENT_ERROR;
135
0
        return FALSE;
136
0
    }
137
0
    int32_t newCap = capacity * 2;
138
0
    if (newCap < minimumCapacity) {
139
0
        newCap = minimumCapacity;
140
0
    }
141
0
    if (maxCapacity > 0 && newCap > maxCapacity) {
142
0
        newCap = maxCapacity;
143
0
    }
144
0
    if (newCap > (int32_t)(INT32_MAX / sizeof(int64_t))) {  // integer overflow check
145
        // We keep the original memory contents on bad minimumCapacity/maxCapacity.
146
0
        status = U_ILLEGAL_ARGUMENT_ERROR;
147
0
        return FALSE;
148
0
    }
149
0
    int64_t* newElems = (int64_t *)uprv_realloc(elements, sizeof(int64_t)*newCap);
150
0
    if (newElems == NULL) {
151
        // We keep the original contents on the memory failure on realloc.
152
0
        status = U_MEMORY_ALLOCATION_ERROR;
153
0
        return FALSE;
154
0
    }
155
0
    elements = newElems;
156
0
    capacity = newCap;
157
0
    return TRUE;
158
0
}
159
160
0
void UVector64::setMaxCapacity(int32_t limit) {
161
0
    U_ASSERT(limit >= 0);
162
0
    if (limit < 0) {
163
0
        limit = 0;
164
0
    }
165
0
    if (limit > (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
0
        return;
168
0
    }
169
0
    maxCapacity = limit;
170
0
    if (capacity <= maxCapacity || maxCapacity == 0) {
171
        // Current capacity is within the new limit.
172
0
        return;
173
0
    }
174
    
175
    // New maximum capacity is smaller than the current size.
176
    // Realloc the storage to the new, smaller size.
177
0
    int64_t* newElems = (int64_t *)uprv_realloc(elements, sizeof(int64_t)*maxCapacity);
178
0
    if (newElems == NULL) {
179
        // Realloc to smaller failed.
180
        //   Just keep what we had.  No need to call it a failure.
181
0
        return;
182
0
    }
183
0
    elements = newElems;
184
0
    capacity = maxCapacity;
185
0
    if (count > capacity) {
186
0
        count = capacity;
187
0
    }
188
0
}
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 NULL.
195
 */
196
0
void UVector64::setSize(int32_t newSize) {
197
0
    int32_t i;
198
0
    if (newSize < 0) {
199
0
        return;
200
0
    }
201
0
    if (newSize > count) {
202
0
        UErrorCode ec = U_ZERO_ERROR;
203
0
        if (!ensureCapacity(newSize, ec)) {
204
0
            return;
205
0
        }
206
0
        for (i=count; i<newSize; ++i) {
207
0
            elements[i] = 0;
208
0
        }
209
0
    } 
210
0
    count = newSize;
211
0
}
212
213
U_NAMESPACE_END
214