blob: 2ec9063a3a3f756d40e6fda2734279018c03c758 [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 */
6
7#include <assert.h>
8#include <stdint.h>
9#include <stdlib.h>
10#include <string.h>
11
12#include "util.h"
13
14struct drv_array {
15 void **items;
16 uint32_t size;
17 uint32_t item_size;
18 uint32_t allocations;
19};
20
21struct drv_array *drv_array_init(uint32_t item_size)
22{
23 struct drv_array *array;
24
25 array = calloc(1, sizeof(*array));
Yiwei Zhangafdf87d2021-09-28 04:06:06 +000026 if (!array)
27 return NULL;
Gurchetan Singh39f66c02017-11-02 16:42:49 -070028
29 /* Start with a power of 2 number of allocations. */
30 array->allocations = 2;
31 array->items = calloc(array->allocations, sizeof(*array->items));
Yiwei Zhangafdf87d2021-09-28 04:06:06 +000032 if (!array->items) {
33 free(array);
34 return NULL;
35 }
36
Gurchetan Singh39f66c02017-11-02 16:42:49 -070037 array->item_size = item_size;
38 return array;
39}
40
41void *drv_array_append(struct drv_array *array, void *data)
42{
43 void *item;
44
45 if (array->size >= array->allocations) {
46 void **new_items = NULL;
47 array->allocations *= 2;
48 new_items = realloc(array->items, array->allocations * sizeof(*array->items));
49 assert(new_items);
50 array->items = new_items;
51 }
52
53 item = calloc(1, array->item_size);
54 memcpy(item, data, array->item_size);
55 array->items[array->size] = item;
56 array->size++;
57 return item;
58}
59
60void drv_array_remove(struct drv_array *array, uint32_t idx)
61{
62 uint32_t i;
63
64 assert(array);
65 assert(idx < array->size);
66
67 free(array->items[idx]);
68 array->items[idx] = NULL;
69
70 for (i = idx + 1; i < array->size; i++)
71 array->items[i - 1] = array->items[i];
72
73 array->size--;
74 if ((DIV_ROUND_UP(array->allocations, 2) > array->size) && array->allocations > 2) {
75 void **new_items = NULL;
76 array->allocations = DIV_ROUND_UP(array->allocations, 2);
77 new_items = realloc(array->items, array->allocations * sizeof(*array->items));
78 assert(new_items);
79 array->items = new_items;
80 }
81}
82
83void *drv_array_at_idx(struct drv_array *array, uint32_t idx)
84{
85 assert(idx < array->size);
86 return array->items[idx];
87}
88
89uint32_t drv_array_size(struct drv_array *array)
90{
91 return array->size;
92}
93
94void drv_array_destroy(struct drv_array *array)
95{
96 uint32_t i;
97
98 for (i = 0; i < array->size; i++)
99 free(array->items[i]);
100
101 free(array->items);
102 free(array);
103}