blob: b4e77501d13a335a6dbf5d1de8c0de994b592cc7 [file] [log] [blame]
Gurchetan Singh39f66c02017-11-02 16:42:49 -07001/*
2 * Copyright 2017 The Chromium OS Authors. All rights reserved.
3 * Use of this source code is governed by a BSD-style license that can be
4 * found in the LICENSE file.
5 */
Yiwei Zhangb7a64442021-09-30 05:13:10 +00006#include "drv_array_helpers.h"
Gurchetan Singh39f66c02017-11-02 16:42:49 -07007
8#include <assert.h>
9#include <stdint.h>
10#include <stdlib.h>
11#include <string.h>
12
13#include "util.h"
14
15struct drv_array {
16 void **items;
17 uint32_t size;
18 uint32_t item_size;
19 uint32_t allocations;
20};
21
22struct drv_array *drv_array_init(uint32_t item_size)
23{
24 struct drv_array *array;
25
26 array = calloc(1, sizeof(*array));
Yiwei Zhangafdf87d2021-09-28 04:06:06 +000027 if (!array)
28 return NULL;
Gurchetan Singh39f66c02017-11-02 16:42:49 -070029
30 /* Start with a power of 2 number of allocations. */
31 array->allocations = 2;
32 array->items = calloc(array->allocations, sizeof(*array->items));
Yiwei Zhangafdf87d2021-09-28 04:06:06 +000033 if (!array->items) {
34 free(array);
35 return NULL;
36 }
37
Gurchetan Singh39f66c02017-11-02 16:42:49 -070038 array->item_size = item_size;
39 return array;
40}
41
42void *drv_array_append(struct drv_array *array, void *data)
43{
44 void *item;
45
46 if (array->size >= array->allocations) {
47 void **new_items = NULL;
48 array->allocations *= 2;
49 new_items = realloc(array->items, array->allocations * sizeof(*array->items));
50 assert(new_items);
51 array->items = new_items;
52 }
53
54 item = calloc(1, array->item_size);
55 memcpy(item, data, array->item_size);
56 array->items[array->size] = item;
57 array->size++;
58 return item;
59}
60
61void drv_array_remove(struct drv_array *array, uint32_t idx)
62{
63 uint32_t i;
64
65 assert(array);
66 assert(idx < array->size);
67
68 free(array->items[idx]);
69 array->items[idx] = NULL;
70
71 for (i = idx + 1; i < array->size; i++)
72 array->items[i - 1] = array->items[i];
73
74 array->size--;
75 if ((DIV_ROUND_UP(array->allocations, 2) > array->size) && array->allocations > 2) {
76 void **new_items = NULL;
77 array->allocations = DIV_ROUND_UP(array->allocations, 2);
78 new_items = realloc(array->items, array->allocations * sizeof(*array->items));
79 assert(new_items);
80 array->items = new_items;
81 }
82}
83
84void *drv_array_at_idx(struct drv_array *array, uint32_t idx)
85{
86 assert(idx < array->size);
87 return array->items[idx];
88}
89
90uint32_t drv_array_size(struct drv_array *array)
91{
92 return array->size;
93}
94
95void drv_array_destroy(struct drv_array *array)
96{
97 uint32_t i;
98
99 for (i = 0; i < array->size; i++)
100 free(array->items[i]);
101
102 free(array->items);
103 free(array);
104}