Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/crypto/krb5/src/ccapi/common/cci_array_internal.c
39536 views
1
/* ccapi/common/cci_array_internal.c */
2
/*
3
* Copyright 2006, 2007 Massachusetts Institute of Technology.
4
* All Rights Reserved.
5
*
6
* Export of this software from the United States of America may
7
* require a specific license from the United States Government.
8
* It is the responsibility of any person or organization contemplating
9
* export to obtain such a license before exporting.
10
*
11
* WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
12
* distribute this software and its documentation for any purpose and
13
* without fee is hereby granted, provided that the above copyright
14
* notice appear in all copies and that both that copyright notice and
15
* this permission notice appear in supporting documentation, and that
16
* the name of M.I.T. not be used in advertising or publicity pertaining
17
* to distribution of the software without specific, written prior
18
* permission. Furthermore if you modify this software you must label
19
* your software as modified software and not distribute it in such a
20
* fashion that it might be confused with the original M.I.T. software.
21
* M.I.T. makes no representations about the suitability of
22
* this software for any purpose. It is provided "as is" without express
23
* or implied warranty.
24
*/
25
26
#include "cci_common.h"
27
#include "cci_array_internal.h"
28
29
#ifdef WIN32
30
#include "k5-platform.h"
31
#endif
32
33
/* ------------------------------------------------------------------------ */
34
35
struct cci_array_d {
36
cci_array_object_t *objects;
37
cc_uint64 count;
38
cc_uint64 max_count;
39
40
cci_array_object_release_t object_release;
41
};
42
43
struct cci_array_d cci_array_initializer = { NULL, 0, 0, NULL };
44
45
#define CCI_ARRAY_COUNT_INCREMENT 16
46
47
/* ------------------------------------------------------------------------ */
48
49
static cc_int32 cci_array_resize (cci_array_t io_array,
50
cc_uint64 in_new_count)
51
{
52
cc_int32 err = ccNoError;
53
cc_uint64 new_max_count = 0;
54
55
if (!io_array) { err = cci_check_error (ccErrBadParam); }
56
57
if (!err) {
58
cc_uint64 old_max_count = io_array->max_count;
59
new_max_count = io_array->max_count;
60
61
if (in_new_count > old_max_count) {
62
/* Expand the array */
63
while (in_new_count > new_max_count) {
64
new_max_count += CCI_ARRAY_COUNT_INCREMENT;
65
}
66
67
} else if ((in_new_count + CCI_ARRAY_COUNT_INCREMENT) < old_max_count) {
68
/* Shrink the array, but never drop below CC_ARRAY_COUNT_INCREMENT */
69
while ((in_new_count + CCI_ARRAY_COUNT_INCREMENT) < new_max_count &&
70
(new_max_count > CCI_ARRAY_COUNT_INCREMENT)) {
71
new_max_count -= CCI_ARRAY_COUNT_INCREMENT;
72
}
73
}
74
}
75
76
if (!err && io_array->max_count != new_max_count) {
77
cci_array_object_t *objects = io_array->objects;
78
79
if (!objects) {
80
objects = malloc (new_max_count * sizeof (*objects));
81
} else {
82
objects = realloc (objects, new_max_count * sizeof (*objects));
83
}
84
if (!objects) { err = cci_check_error (ccErrNoMem); }
85
86
if (!err) {
87
io_array->objects = objects;
88
io_array->max_count = new_max_count;
89
}
90
}
91
92
return cci_check_error (err);
93
}
94
95
#ifdef TARGET_OS_MAC
96
#pragma mark -
97
#endif
98
99
/* ------------------------------------------------------------------------ */
100
101
cc_int32 cci_array_new (cci_array_t *out_array,
102
cci_array_object_release_t in_array_object_release)
103
{
104
cc_int32 err = ccNoError;
105
cci_array_t array = NULL;
106
107
if (!out_array) { err = cci_check_error (ccErrBadParam); }
108
109
if (!err) {
110
array = malloc (sizeof (*array));
111
if (array) {
112
*array = cci_array_initializer;
113
array->object_release = in_array_object_release;
114
} else {
115
err = cci_check_error (ccErrNoMem);
116
}
117
}
118
119
if (!err) {
120
*out_array = array;
121
array = NULL;
122
}
123
124
cci_array_release (array);
125
126
return cci_check_error (err);
127
}
128
129
/* ------------------------------------------------------------------------ */
130
131
cc_int32 cci_array_release (cci_array_t io_array)
132
{
133
cc_int32 err = ccNoError;
134
135
if (!err && io_array) {
136
cc_uint64 i;
137
138
if (io_array->object_release) {
139
for (i = 0; i < io_array->count; i++) {
140
io_array->object_release (io_array->objects[i]);
141
}
142
}
143
free (io_array->objects);
144
free (io_array);
145
}
146
147
return err;
148
}
149
150
/* ------------------------------------------------------------------------ */
151
152
cc_uint64 cci_array_count (cci_array_t in_array)
153
{
154
return in_array ? in_array->count : 0;
155
}
156
157
/* ------------------------------------------------------------------------ */
158
159
cci_array_object_t cci_array_object_at_index (cci_array_t io_array,
160
cc_uint64 in_position)
161
{
162
if (io_array && in_position < io_array->count) {
163
return io_array->objects[in_position];
164
} else {
165
if (!io_array) {
166
cci_debug_printf ("%s() got NULL array", __FUNCTION__);
167
} else {
168
cci_debug_printf ("%s() got bad index %lld (count = %lld)", __FUNCTION__,
169
in_position, io_array->count);
170
}
171
return NULL;
172
}
173
}
174
175
#ifdef TARGET_OS_MAC
176
#pragma mark -
177
#endif
178
179
/* ------------------------------------------------------------------------ */
180
181
cc_int32 cci_array_insert (cci_array_t io_array,
182
cci_array_object_t in_object,
183
cc_uint64 in_position)
184
{
185
cc_int32 err = ccNoError;
186
187
if (!io_array ) { err = cci_check_error (ccErrBadParam); }
188
if (!in_object) { err = cci_check_error (ccErrBadParam); }
189
190
if (!err) {
191
/* Don't try to insert past the end and don't overflow the array */
192
if (in_position > io_array->count || io_array->count == UINT64_MAX) {
193
err = cci_check_error (ccErrBadParam);
194
}
195
}
196
197
if (!err) {
198
err = cci_array_resize (io_array, io_array->count + 1);
199
}
200
201
if (!err) {
202
cc_uint64 move_count = io_array->count - in_position;
203
204
if (move_count > 0) {
205
memmove (&io_array->objects[in_position + 1], &io_array->objects[in_position],
206
move_count * sizeof (*io_array->objects));
207
}
208
209
io_array->objects[in_position] = in_object;
210
io_array->count++;
211
}
212
213
return cci_check_error (err);
214
}
215
216
/* ------------------------------------------------------------------------ */
217
218
cc_int32 cci_array_remove (cci_array_t io_array,
219
cc_uint64 in_position)
220
{
221
cc_int32 err = ccNoError;
222
223
if (!io_array) { err = cci_check_error (ccErrBadParam); }
224
225
if (!err && in_position >= io_array->count) {
226
err = cci_check_error (ccErrBadParam);
227
}
228
229
if (!err) {
230
cc_uint64 move_count = io_array->count - in_position - 1;
231
cci_array_object_t object = io_array->objects[in_position];
232
233
if (move_count > 0) {
234
memmove (&io_array->objects[in_position], &io_array->objects[in_position + 1],
235
move_count * sizeof (*io_array->objects));
236
}
237
io_array->count--;
238
239
if (io_array->object_release) { io_array->object_release (object); }
240
241
cci_array_resize (io_array, io_array->count);
242
}
243
244
return cci_check_error (err);
245
}
246
247
/* ------------------------------------------------------------------------ */
248
249
cc_int32 cci_array_move (cci_array_t io_array,
250
cc_uint64 in_position,
251
cc_uint64 in_new_position,
252
cc_uint64 *out_real_new_position)
253
{
254
cc_int32 err = ccNoError;
255
256
if (!io_array ) { err = cci_check_error (ccErrBadParam); }
257
if (!out_real_new_position) { err = cci_check_error (ccErrBadParam); }
258
259
if (!err && in_position >= io_array->count) {
260
err = cci_check_error (ccErrBadParam);
261
}
262
263
if (!err && in_new_position > io_array->count) {
264
err = cci_check_error (ccErrBadParam);
265
}
266
if (!err) {
267
cc_uint64 move_from = 0;
268
cc_uint64 move_to = 0;
269
cc_uint64 move_count = 0;
270
cc_uint64 real_new_position = 0;
271
272
if (in_position < in_new_position) {
273
/* shift right, making an empty space so the
274
* actual new position is one less in_new_position */
275
move_from = in_position + 1;
276
move_to = in_position;
277
move_count = in_new_position - in_position - 1;
278
real_new_position = in_new_position - 1;
279
280
} else if (in_position > in_new_position) {
281
/* shift left */
282
move_from = in_new_position;
283
move_to = in_new_position + 1;
284
move_count = in_position - in_new_position;
285
real_new_position = in_new_position;
286
287
} else {
288
real_new_position = in_new_position;
289
}
290
291
if (move_count > 0) {
292
cci_array_object_t object = io_array->objects[in_position];
293
294
memmove (&io_array->objects[move_to], &io_array->objects[move_from],
295
move_count * sizeof (*io_array->objects));
296
io_array->objects[real_new_position] = object;
297
}
298
299
*out_real_new_position = real_new_position;
300
}
301
302
return cci_check_error (err);
303
}
304
305
/* ------------------------------------------------------------------------ */
306
307
cc_int32 cci_array_push_front (cci_array_t io_array,
308
cc_uint64 in_position)
309
{
310
cc_uint64 real_new_position = 0;
311
return cci_array_move (io_array, in_position, 0, &real_new_position);
312
}
313
314