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