Coverage Report

Created: 2026-05-16 07:29

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/fluent-bit/lib/cfl/src/cfl_array.c
Line
Count
Source
1
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
3
/*  CFL
4
 *  ===
5
 *  Copyright (C) 2022-2024 The CFL Authors
6
 *
7
 *  Licensed under the Apache License, Version 2.0 (the "License");
8
 *  you may not use this file except in compliance with the License.
9
 *  You may obtain a copy of the License at
10
 *
11
 *      http://www.apache.org/licenses/LICENSE-2.0
12
 *
13
 *  Unless required by applicable law or agreed to in writing, software
14
 *  distributed under the License is distributed on an "AS IS" BASIS,
15
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
 *  See the License for the specific language governing permissions and
17
 *  limitations under the License.
18
 */
19
20
#include <cfl/cfl.h>
21
#include <cfl/cfl_array.h>
22
#include <cfl/cfl_variant.h>
23
24
#include <stdint.h>
25
26
#include <cfl/cfl_container.h>
27
28
struct cfl_array *cfl_array_create(size_t slot_count)
29
873k
{
30
873k
    struct cfl_array *array;
31
873k
    size_t alloc_count;
32
33
873k
    array = malloc(sizeof(struct cfl_array));
34
873k
    if (array == NULL) {
35
0
        cfl_errno();
36
0
        return NULL;
37
0
    }
38
39
    /* by default arrays are not resizable */
40
873k
    array->resizable = CFL_FALSE;
41
42
    /* allocate fixed number of entries */
43
873k
    alloc_count = slot_count;
44
873k
    if (alloc_count == 0) {
45
2.28k
        alloc_count = 1;
46
2.28k
    }
47
873k
    if (alloc_count > SIZE_MAX / sizeof(void *)) {
48
0
        free(array);
49
0
        return NULL;
50
0
    }
51
52
873k
    array->entries = calloc(alloc_count, sizeof(void *));
53
873k
    if (array->entries == NULL) {
54
0
        cfl_errno();
55
0
        free(array);
56
0
        return NULL;
57
0
    }
58
59
873k
    array->entry_count = 0;
60
873k
    array->slot_count = slot_count;
61
873k
    array->owner = NULL;
62
873k
    array->parent_array = NULL;
63
873k
    array->parent_kvlist = NULL;
64
65
873k
    return array;
66
873k
}
67
68
void cfl_array_destroy(struct cfl_array *array)
69
873k
{
70
873k
    size_t index;
71
72
873k
    if (!array) {
73
0
        return;
74
0
    }
75
76
873k
    if (array->entries != NULL) {
77
13.4M
        for (index = 0 ; index < array->entry_count ; index++) {
78
12.5M
            if(array->entries[index] != NULL) {
79
12.5M
                cfl_variant_destroy(array->entries[index]);
80
12.5M
            }
81
12.5M
        }
82
83
873k
        free(array->entries);
84
873k
    }
85
873k
    free(array);
86
873k
}
87
88
int cfl_array_resizable(struct cfl_array *array, int v)
89
28.4k
{
90
28.4k
    if (array == NULL) {
91
0
        return -1;
92
0
    }
93
94
28.4k
    if (v != CFL_TRUE && v != CFL_FALSE) {
95
0
        return -1;
96
0
    }
97
98
28.4k
    array->resizable = v;
99
28.4k
    return 0;
100
28.4k
}
101
102
int cfl_array_remove_by_index(struct cfl_array *array,
103
                              size_t position)
104
0
{
105
0
    if (array == NULL) {
106
0
        return -1;
107
0
    }
108
109
0
    if (position >= array->entry_count) {
110
0
        return -1;
111
0
    }
112
113
0
    cfl_variant_destroy(array->entries[position]);
114
115
0
    if (position != array->entry_count - 1) {
116
0
        memmove(&array->entries[position],
117
0
                &array->entries[position + 1],
118
0
                sizeof(void *) * (array->entry_count - (position + 1)));
119
0
    }
120
0
    else {
121
0
        array->entries[position] = NULL;
122
0
    }
123
0
    array->entry_count--;
124
125
0
    return 0;
126
0
}
127
128
int cfl_array_remove_by_reference(struct cfl_array *array,
129
                                  struct cfl_variant *value)
130
0
{
131
0
    size_t index;
132
133
0
    if (array == NULL || value == NULL) {
134
0
        return -1;
135
0
    }
136
137
0
    for (index = 0 ; index < array->entry_count ; index++) {
138
0
        if (array->entries[index] == value) {
139
0
            return cfl_array_remove_by_index(array, index);
140
0
        }
141
0
    }
142
143
0
    return 0;
144
0
}
145
146
int cfl_array_append(struct cfl_array *array,
147
                     struct cfl_variant *value)
148
12.5M
{
149
12.5M
    void *tmp;
150
12.5M
    size_t new_slot_count;
151
12.5M
    size_t new_size;
152
12.5M
    size_t base_slot_count;
153
154
12.5M
    if (array == NULL || value == NULL) {
155
0
        return -1;
156
0
    }
157
158
12.5M
    if (array->entry_count >= array->slot_count) {
159
        /*
160
         * if there is no more space but the caller allowed to resize
161
         * the array, just double the size. Yeah, this is scary and should
162
         * be used only when the caller 'knows this is safe to do' because
163
         * it controls the input data.
164
         */
165
5.81k
        if (array->resizable) {
166
5.80k
            base_slot_count = array->slot_count;
167
5.80k
            if (base_slot_count == 0) {
168
0
                base_slot_count = 1;
169
0
            }
170
171
            /* set new number of slots and total size */
172
5.80k
            if (base_slot_count > SIZE_MAX / 2) {
173
0
                return -1;
174
0
            }
175
176
5.80k
            new_slot_count = (base_slot_count * 2);
177
5.80k
            if (new_slot_count > SIZE_MAX / sizeof(void *)) {
178
0
                return -1;
179
0
            }
180
181
5.80k
            new_size = (new_slot_count * sizeof(void *));
182
183
5.80k
            tmp = realloc(array->entries, new_size);
184
5.80k
            if (!tmp) {
185
0
                cfl_report_runtime_error();
186
0
                return -1;
187
0
            }
188
5.80k
            array->slot_count = new_slot_count;
189
5.80k
            array->entries = tmp;
190
5.80k
        }
191
10
        else {
192
10
            return -1;
193
10
        }
194
5.81k
    }
195
196
    /* this is just a double check to make sure the slot is really available */
197
12.5M
    if (array->entry_count >= array->slot_count) {
198
0
        return -1;
199
0
    }
200
201
12.5M
    if (cfl_container_move_variant_to_array(array, value) != 0) {
202
0
        return -1;
203
0
    }
204
205
12.5M
    array->entries[array->entry_count++] = value;
206
12.5M
    return 0;
207
12.5M
}
208
209
int cfl_array_append_string(struct cfl_array *array, char *value)
210
145k
{
211
145k
    struct cfl_variant *value_instance;
212
145k
    int                 result;
213
214
145k
    value_instance = cfl_variant_create_from_string(value);
215
216
145k
    if (value_instance == NULL) {
217
0
        return -1;
218
0
    }
219
220
145k
    result = cfl_array_append(array, value_instance);
221
145k
    if (result) {
222
0
        cfl_variant_destroy(value_instance);
223
0
        return -2;
224
0
    }
225
226
145k
    return 0;
227
145k
}
228
229
int cfl_array_append_string_s(struct cfl_array *array, char *str, size_t str_len, int referenced)
230
0
{
231
0
    struct cfl_variant *value_instance;
232
0
    int                 result;
233
234
0
    value_instance = cfl_variant_create_from_string_s(str, str_len, referenced);
235
0
    if (value_instance == NULL) {
236
0
        return -1;
237
0
    }
238
239
0
    result = cfl_array_append(array, value_instance);
240
0
    if (result) {
241
0
        cfl_variant_destroy(value_instance);
242
0
        return -2;
243
0
    }
244
245
0
    return 0;
246
0
}
247
248
int cfl_array_append_bytes(struct cfl_array *array,
249
                           char *value,
250
                           size_t length,
251
                           int referenced)
252
217
{
253
217
    struct cfl_variant *value_instance;
254
217
    int                 result;
255
256
217
    value_instance = cfl_variant_create_from_bytes(value, length, referenced);
257
217
    if (value_instance == NULL) {
258
0
        return -1;
259
0
    }
260
261
217
    result = cfl_array_append(array, value_instance);
262
263
217
    if (result) {
264
0
        cfl_variant_destroy(value_instance);
265
266
0
        return -2;
267
0
    }
268
269
217
    return 0;
270
217
}
271
272
int cfl_array_append_reference(struct cfl_array *array, void *value)
273
0
{
274
0
    struct cfl_variant *value_instance;
275
0
    int                 result;
276
277
0
    value_instance = cfl_variant_create_from_reference(value);
278
279
0
    if (value_instance == NULL) {
280
0
        return -1;
281
0
    }
282
283
0
    result = cfl_array_append(array, value_instance);
284
285
0
    if (result) {
286
0
        cfl_variant_destroy(value_instance);
287
288
0
        return -2;
289
0
    }
290
291
0
    return 0;
292
0
}
293
294
int cfl_array_append_bool(struct cfl_array *array, int value)
295
220
{
296
220
    struct cfl_variant *value_instance;
297
220
    int                 result;
298
299
220
    value_instance = cfl_variant_create_from_bool(value);
300
301
220
    if (value_instance == NULL) {
302
0
        return -1;
303
0
    }
304
305
220
    result = cfl_array_append(array, value_instance);
306
307
220
    if (result) {
308
0
        cfl_variant_destroy(value_instance);
309
310
0
        return -2;
311
0
    }
312
313
220
    return 0;
314
220
}
315
316
int cfl_array_append_int64(struct cfl_array *array, int64_t value)
317
663
{
318
663
    struct cfl_variant *value_instance;
319
663
    int                 result;
320
321
663
    value_instance = cfl_variant_create_from_int64(value);
322
323
663
    if (value_instance == NULL) {
324
0
        return -1;
325
0
    }
326
327
663
    result = cfl_array_append(array, value_instance);
328
329
663
    if (result) {
330
0
        cfl_variant_destroy(value_instance);
331
0
        return -2;
332
0
    }
333
334
663
    return 0;
335
663
}
336
337
int cfl_array_append_uint64(struct cfl_array *array, uint64_t value)
338
0
{
339
0
    struct cfl_variant *value_instance;
340
0
    int                 result;
341
342
0
    value_instance = cfl_variant_create_from_uint64(value);
343
344
0
    if (value_instance == NULL) {
345
0
        return -1;
346
0
    }
347
348
0
    result = cfl_array_append(array, value_instance);
349
350
0
    if (result) {
351
0
        cfl_variant_destroy(value_instance);
352
0
        return -2;
353
0
    }
354
355
0
    return 0;
356
0
}
357
358
359
int cfl_array_append_double(struct cfl_array *array, double value)
360
0
{
361
0
    struct cfl_variant *value_instance;
362
0
    int                 result;
363
364
0
    value_instance = cfl_variant_create_from_double(value);
365
366
0
    if (value_instance == NULL) {
367
0
        return -1;
368
0
    }
369
370
0
    result = cfl_array_append(array, value_instance);
371
372
0
    if (result) {
373
0
        cfl_variant_destroy(value_instance);
374
375
0
        return -2;
376
0
    }
377
378
0
    return 0;
379
0
}
380
381
int cfl_array_append_null(struct cfl_array *array)
382
0
{
383
0
    struct cfl_variant *value_instance;
384
0
    int                 result;
385
386
0
    value_instance = cfl_variant_create_from_null();
387
0
    if (value_instance == NULL) {
388
0
        return -1;
389
0
    }
390
391
0
    result = cfl_array_append(array, value_instance);
392
0
    if (result) {
393
0
        cfl_variant_destroy(value_instance);
394
0
        return -2;
395
0
    }
396
397
0
    return 0;
398
0
}
399
400
int cfl_array_append_array(struct cfl_array *array, struct cfl_array *value)
401
78
{
402
78
    struct cfl_variant *value_instance;
403
78
    int                 result;
404
405
78
    if (array == NULL || value == NULL) {
406
0
        return -1;
407
0
    }
408
409
78
    if (array == value) {
410
0
        return -1;
411
0
    }
412
413
78
    value_instance = cfl_variant_create_from_array(value);
414
415
78
    if (value_instance == NULL) {
416
0
        return -1;
417
0
    }
418
419
78
    result = cfl_array_append(array, value_instance);
420
78
    if (result) {
421
0
        cfl_container_release_variant(value_instance);
422
0
        value_instance->data.as_array = NULL;
423
0
        cfl_variant_destroy(value_instance);
424
0
        return -2;
425
0
    }
426
427
78
    return 0;
428
78
}
429
430
431
int cfl_array_append_new_array(struct cfl_array *array, size_t size)
432
0
{
433
0
    int               result;
434
0
    struct cfl_array *value;
435
436
0
    if (array == NULL) {
437
0
        return -1;
438
0
    }
439
440
0
    value = cfl_array_create(size);
441
442
0
    if (value == NULL) {
443
0
        return -1;
444
0
    }
445
446
0
    result = cfl_array_append_array(array, value);
447
0
    if (result < 0) {
448
0
        cfl_array_destroy(value);
449
0
    }
450
451
0
    return result;
452
0
}
453
454
int cfl_array_append_kvlist(struct cfl_array *array, struct cfl_kvlist *value)
455
3.67k
{
456
3.67k
    struct cfl_variant *value_instance;
457
3.67k
    int                 result;
458
459
3.67k
    if (array == NULL || value == NULL) {
460
0
        return -1;
461
0
    }
462
463
3.67k
    value_instance = cfl_variant_create_from_kvlist(value);
464
3.67k
    if (value_instance == NULL) {
465
0
        return -1;
466
0
    }
467
3.67k
    result = cfl_array_append(array, value_instance);
468
469
3.67k
    if (result) {
470
0
        cfl_container_release_variant(value_instance);
471
0
        value_instance->data.as_kvlist = NULL;
472
0
        cfl_variant_destroy(value_instance);
473
474
0
        return -2;
475
0
    }
476
477
3.67k
    return 0;
478
3.67k
}
479
480
481
int cfl_array_print(FILE *fp, struct cfl_array *array)
482
0
{
483
0
    size_t size;
484
0
    size_t i;
485
0
    int ret;
486
487
0
    if (fp == NULL || array == NULL) {
488
0
        return -1;
489
0
    }
490
491
0
    size = array->entry_count;
492
0
    if (size == 0) {
493
0
        if (fputs("[]", fp) == EOF) {
494
0
            return -1;
495
0
        }
496
497
0
        return 0;
498
0
    }
499
500
0
    if (fputc('[', fp) == EOF) {
501
0
        return -1;
502
0
    }
503
504
0
    for (i=0; i<size-1; i++) {
505
0
        ret = cfl_variant_print(fp, array->entries[i]);
506
0
        if (ret < 0) {
507
0
            return -1;
508
0
        }
509
510
0
        if (fputc(',', fp) == EOF) {
511
0
            return -1;
512
0
        }
513
0
    }
514
515
0
    ret = cfl_variant_print(fp, array->entries[size-1]);
516
0
    if (ret < 0) {
517
0
        return -1;
518
0
    }
519
520
0
    if (fputc(']', fp) == EOF) {
521
0
        return -1;
522
0
    }
523
524
0
    return ret;
525
0
}