Coverage Report

Created: 2025-10-24 06:54

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/icu/icu4c/source/common/uvectr64.cpp
Line
Count
Source
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
64.3k
#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
64.3k
    count(0),
28
64.3k
    capacity(0),
29
64.3k
    maxCapacity(0),
30
64.3k
    elements(nullptr)
31
64.3k
{
32
64.3k
    _init(DEFAULT_CAPACITY, status);
33
64.3k
}
34
35
UVector64::UVector64(int32_t initialCapacity, UErrorCode &status) :
36
0
    count(0),
37
0
    capacity(0),
38
0
    maxCapacity(0),
39
0
    elements(nullptr)
40
0
{
41
0
    _init(initialCapacity, status);
42
0
}
43
44
45
46
64.3k
void UVector64::_init(int32_t initialCapacity, UErrorCode &status) {
47
    // Fix bogus initialCapacity values; avoid malloc(0)
48
64.3k
    if (initialCapacity < 1) {
49
0
        initialCapacity = DEFAULT_CAPACITY;
50
0
    }
51
64.3k
    if (maxCapacity>0 && maxCapacity<initialCapacity) {
52
0
        initialCapacity = maxCapacity;
53
0
    }
54
64.3k
    if (initialCapacity > static_cast<int32_t>(INT32_MAX / sizeof(int64_t))) {
55
0
        initialCapacity = uprv_min(DEFAULT_CAPACITY, maxCapacity);
56
0
    }
57
64.3k
    elements = static_cast<int64_t*>(uprv_malloc(sizeof(int64_t) * initialCapacity));
58
64.3k
    if (elements == nullptr) {
59
0
        status = U_MEMORY_ALLOCATION_ERROR;
60
64.3k
    } else {
61
64.3k
        capacity = initialCapacity;
62
64.3k
    }
63
64.3k
}
64
65
64.3k
UVector64::~UVector64() {
66
64.3k
    uprv_free(elements);
67
64.3k
    elements = nullptr;
68
64.3k
}
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
86.0M
void UVector64::setElementAt(int64_t elem, int32_t index) {
96
86.0M
    if (0 <= index && index < count) {
97
86.0M
        elements[index] = elem;
98
86.0M
    }
99
    /* else index out of range */
100
86.0M
}
101
102
1.52M
void UVector64::insertElementAt(int64_t elem, int32_t index, UErrorCode &status) {
103
    // must have 0 <= index <= count
104
1.52M
    if (0 <= index && index <= count && ensureCapacity(count + 1, status)) {
105
56.7M
        for (int32_t i=count; i>index; --i) {
106
55.2M
            elements[i] = elements[i-1];
107
55.2M
        }
108
1.52M
        elements[index] = elem;
109
1.52M
        ++count;
110
1.52M
    }
111
    /* else index out of range */
112
1.52M
}
113
114
19.2M
void UVector64::removeAllElements() {
115
19.2M
    count = 0;
116
19.2M
}
117
118
89.1k
UBool UVector64::expandCapacity(int32_t minimumCapacity, UErrorCode &status) {
119
89.1k
    if (U_FAILURE(status)) {
120
1
        return false;
121
1
    }
122
89.1k
    if (minimumCapacity < 0) {
123
0
        status = U_ILLEGAL_ARGUMENT_ERROR;
124
0
        return false;
125
0
    }
126
89.1k
    if (capacity >= minimumCapacity) {
127
0
        return true;
128
0
    }
129
89.1k
    if (maxCapacity>0 && minimumCapacity>maxCapacity) {
130
76
        status = U_BUFFER_OVERFLOW_ERROR;
131
76
        return false;
132
76
    }
133
89.0k
    if (capacity > (INT32_MAX - 1) / 2) {  // integer overflow check
134
0
        status = U_ILLEGAL_ARGUMENT_ERROR;
135
0
        return false;
136
0
    }
137
89.0k
    int32_t newCap = capacity * 2;
138
89.0k
    if (newCap < minimumCapacity) {
139
517
        newCap = minimumCapacity;
140
517
    }
141
89.0k
    if (maxCapacity > 0 && newCap > maxCapacity) {
142
99
        newCap = maxCapacity;
143
99
    }
144
89.0k
    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
0
        status = U_ILLEGAL_ARGUMENT_ERROR;
147
0
        return false;
148
0
    }
149
89.0k
    int64_t* newElems = static_cast<int64_t*>(uprv_realloc(elements, sizeof(int64_t) * newCap));
150
89.0k
    if (newElems == nullptr) {
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
89.0k
    elements = newElems;
156
89.0k
    capacity = newCap;
157
89.0k
    return true;
158
89.0k
}
159
160
14.6k
void UVector64::setMaxCapacity(int32_t limit) {
161
14.6k
    U_ASSERT(limit >= 0);
162
14.6k
    if (limit < 0) {
163
0
        limit = 0;
164
0
    }
165
14.6k
    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
0
        return;
168
0
    }
169
14.6k
    maxCapacity = limit;
170
14.6k
    if (capacity <= maxCapacity || maxCapacity == 0) {
171
        // Current capacity is within the new limit.
172
14.6k
        return;
173
14.6k
    }
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 = static_cast<int64_t*>(uprv_realloc(elements, sizeof(int64_t) * maxCapacity));
178
0
    if (newElems == nullptr) {
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 nullptr.
195
 */
196
2.06M
void UVector64::setSize(int32_t newSize) {
197
2.06M
    int32_t i;
198
2.06M
    if (newSize < 0) {
199
0
        return;
200
0
    }
201
2.06M
    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
2.06M
    count = newSize;
211
2.06M
}
212
213
U_NAMESPACE_END
214