• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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 #include "drv_array_helpers.h"
7 
8 #include <assert.h>
9 #include <stdint.h>
10 #include <stdlib.h>
11 #include <string.h>
12 
13 #include "util.h"
14 
15 struct drv_array {
16 	void **items;
17 	uint32_t size;
18 	uint32_t item_size;
19 	uint32_t allocations;
20 };
21 
drv_array_init(uint32_t item_size)22 struct drv_array *drv_array_init(uint32_t item_size)
23 {
24 	struct drv_array *array;
25 
26 	array = calloc(1, sizeof(*array));
27 	if (!array)
28 		return NULL;
29 
30 	/* Start with a power of 2 number of allocations. */
31 	array->allocations = 2;
32 	array->items = calloc(array->allocations, sizeof(*array->items));
33 	if (!array->items) {
34 		free(array);
35 		return NULL;
36 	}
37 
38 	array->item_size = item_size;
39 	return array;
40 }
41 
drv_array_append(struct drv_array * array,void * data)42 void *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 
drv_array_remove(struct drv_array * array,uint32_t idx)61 void 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 
drv_array_at_idx(struct drv_array * array,uint32_t idx)84 void *drv_array_at_idx(struct drv_array *array, uint32_t idx)
85 {
86 	assert(idx < array->size);
87 	return array->items[idx];
88 }
89 
drv_array_size(struct drv_array * array)90 uint32_t drv_array_size(struct drv_array *array)
91 {
92 	return array->size;
93 }
94 
drv_array_destroy(struct drv_array * array)95 void 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 }
105