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