xref: /aosp_15_r20/external/kmod/shared/array.c (revision cc4ad7da8cefe208cb129ac2aa9a357c7c72deb2)
1*cc4ad7daSAndroid Build Coastguard Worker /*
2*cc4ad7daSAndroid Build Coastguard Worker  * libkmod - interface to kernel module operations
3*cc4ad7daSAndroid Build Coastguard Worker  *
4*cc4ad7daSAndroid Build Coastguard Worker  * Copyright (C) 2011-2013  ProFUSION embedded systems
5*cc4ad7daSAndroid Build Coastguard Worker  *
6*cc4ad7daSAndroid Build Coastguard Worker  * This library is free software; you can redistribute it and/or
7*cc4ad7daSAndroid Build Coastguard Worker  * modify it under the terms of the GNU Lesser General Public
8*cc4ad7daSAndroid Build Coastguard Worker  * License as published by the Free Software Foundation; either
9*cc4ad7daSAndroid Build Coastguard Worker  * version 2.1 of the License, or (at your option) any later version.
10*cc4ad7daSAndroid Build Coastguard Worker  *
11*cc4ad7daSAndroid Build Coastguard Worker  * This library is distributed in the hope that it will be useful,
12*cc4ad7daSAndroid Build Coastguard Worker  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13*cc4ad7daSAndroid Build Coastguard Worker  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14*cc4ad7daSAndroid Build Coastguard Worker  * Lesser General Public License for more details.
15*cc4ad7daSAndroid Build Coastguard Worker  *
16*cc4ad7daSAndroid Build Coastguard Worker  * You should have received a copy of the GNU Lesser General Public
17*cc4ad7daSAndroid Build Coastguard Worker  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
18*cc4ad7daSAndroid Build Coastguard Worker  */
19*cc4ad7daSAndroid Build Coastguard Worker 
20*cc4ad7daSAndroid Build Coastguard Worker #include <assert.h>
21*cc4ad7daSAndroid Build Coastguard Worker #include <errno.h>
22*cc4ad7daSAndroid Build Coastguard Worker #include <stdlib.h>
23*cc4ad7daSAndroid Build Coastguard Worker #include <string.h>
24*cc4ad7daSAndroid Build Coastguard Worker 
25*cc4ad7daSAndroid Build Coastguard Worker #include <shared/array.h>
26*cc4ad7daSAndroid Build Coastguard Worker 
27*cc4ad7daSAndroid Build Coastguard Worker /* basic pointer array growing in steps */
28*cc4ad7daSAndroid Build Coastguard Worker 
29*cc4ad7daSAndroid Build Coastguard Worker 
array_realloc(struct array * array,size_t new_total)30*cc4ad7daSAndroid Build Coastguard Worker static int array_realloc(struct array *array, size_t new_total)
31*cc4ad7daSAndroid Build Coastguard Worker {
32*cc4ad7daSAndroid Build Coastguard Worker 	void *tmp = realloc(array->array, sizeof(void *) * new_total);
33*cc4ad7daSAndroid Build Coastguard Worker 	if (tmp == NULL)
34*cc4ad7daSAndroid Build Coastguard Worker 		return -ENOMEM;
35*cc4ad7daSAndroid Build Coastguard Worker 	array->array = tmp;
36*cc4ad7daSAndroid Build Coastguard Worker 	array->total = new_total;
37*cc4ad7daSAndroid Build Coastguard Worker 	return 0;
38*cc4ad7daSAndroid Build Coastguard Worker }
39*cc4ad7daSAndroid Build Coastguard Worker 
array_init(struct array * array,size_t step)40*cc4ad7daSAndroid Build Coastguard Worker void array_init(struct array *array, size_t step)
41*cc4ad7daSAndroid Build Coastguard Worker {
42*cc4ad7daSAndroid Build Coastguard Worker 	assert(step > 0);
43*cc4ad7daSAndroid Build Coastguard Worker 	array->array = NULL;
44*cc4ad7daSAndroid Build Coastguard Worker 	array->count = 0;
45*cc4ad7daSAndroid Build Coastguard Worker 	array->total = 0;
46*cc4ad7daSAndroid Build Coastguard Worker 	array->step = step;
47*cc4ad7daSAndroid Build Coastguard Worker }
48*cc4ad7daSAndroid Build Coastguard Worker 
array_append(struct array * array,const void * element)49*cc4ad7daSAndroid Build Coastguard Worker int array_append(struct array *array, const void *element)
50*cc4ad7daSAndroid Build Coastguard Worker {
51*cc4ad7daSAndroid Build Coastguard Worker 	size_t idx;
52*cc4ad7daSAndroid Build Coastguard Worker 
53*cc4ad7daSAndroid Build Coastguard Worker 	if (array->count + 1 >= array->total) {
54*cc4ad7daSAndroid Build Coastguard Worker 		int r = array_realloc(array, array->total + array->step);
55*cc4ad7daSAndroid Build Coastguard Worker 		if (r < 0)
56*cc4ad7daSAndroid Build Coastguard Worker 			return r;
57*cc4ad7daSAndroid Build Coastguard Worker 	}
58*cc4ad7daSAndroid Build Coastguard Worker 	idx = array->count;
59*cc4ad7daSAndroid Build Coastguard Worker 	array->array[idx] = (void *)element;
60*cc4ad7daSAndroid Build Coastguard Worker 	array->count++;
61*cc4ad7daSAndroid Build Coastguard Worker 	return idx;
62*cc4ad7daSAndroid Build Coastguard Worker }
63*cc4ad7daSAndroid Build Coastguard Worker 
array_append_unique(struct array * array,const void * element)64*cc4ad7daSAndroid Build Coastguard Worker int array_append_unique(struct array *array, const void *element)
65*cc4ad7daSAndroid Build Coastguard Worker {
66*cc4ad7daSAndroid Build Coastguard Worker 	void **itr = array->array;
67*cc4ad7daSAndroid Build Coastguard Worker 	void **itr_end = itr + array->count;
68*cc4ad7daSAndroid Build Coastguard Worker 	for (; itr < itr_end; itr++)
69*cc4ad7daSAndroid Build Coastguard Worker 		if (*itr == element)
70*cc4ad7daSAndroid Build Coastguard Worker 			return -EEXIST;
71*cc4ad7daSAndroid Build Coastguard Worker 	return array_append(array, element);
72*cc4ad7daSAndroid Build Coastguard Worker }
73*cc4ad7daSAndroid Build Coastguard Worker 
array_pop(struct array * array)74*cc4ad7daSAndroid Build Coastguard Worker void array_pop(struct array *array) {
75*cc4ad7daSAndroid Build Coastguard Worker 	array->count--;
76*cc4ad7daSAndroid Build Coastguard Worker 	if (array->count + array->step < array->total) {
77*cc4ad7daSAndroid Build Coastguard Worker 		int r = array_realloc(array, array->total - array->step);
78*cc4ad7daSAndroid Build Coastguard Worker 		if (r < 0)
79*cc4ad7daSAndroid Build Coastguard Worker 			return;
80*cc4ad7daSAndroid Build Coastguard Worker 	}
81*cc4ad7daSAndroid Build Coastguard Worker }
82*cc4ad7daSAndroid Build Coastguard Worker 
array_free_array(struct array * array)83*cc4ad7daSAndroid Build Coastguard Worker void array_free_array(struct array *array) {
84*cc4ad7daSAndroid Build Coastguard Worker 	free(array->array);
85*cc4ad7daSAndroid Build Coastguard Worker 	array->count = 0;
86*cc4ad7daSAndroid Build Coastguard Worker 	array->total = 0;
87*cc4ad7daSAndroid Build Coastguard Worker }
88*cc4ad7daSAndroid Build Coastguard Worker 
89*cc4ad7daSAndroid Build Coastguard Worker 
array_sort(struct array * array,int (* cmp)(const void * a,const void * b))90*cc4ad7daSAndroid Build Coastguard Worker void array_sort(struct array *array, int (*cmp)(const void *a, const void *b))
91*cc4ad7daSAndroid Build Coastguard Worker {
92*cc4ad7daSAndroid Build Coastguard Worker 	qsort(array->array, array->count, sizeof(void *), cmp);
93*cc4ad7daSAndroid Build Coastguard Worker }
94*cc4ad7daSAndroid Build Coastguard Worker 
array_remove_at(struct array * array,unsigned int pos)95*cc4ad7daSAndroid Build Coastguard Worker int array_remove_at(struct array *array, unsigned int pos)
96*cc4ad7daSAndroid Build Coastguard Worker {
97*cc4ad7daSAndroid Build Coastguard Worker 	if (array->count <= pos)
98*cc4ad7daSAndroid Build Coastguard Worker 		return -ENOENT;
99*cc4ad7daSAndroid Build Coastguard Worker 
100*cc4ad7daSAndroid Build Coastguard Worker 	array->count--;
101*cc4ad7daSAndroid Build Coastguard Worker 	if (pos < array->count)
102*cc4ad7daSAndroid Build Coastguard Worker 		memmove(array->array + pos, array->array + pos + 1,
103*cc4ad7daSAndroid Build Coastguard Worker 			sizeof(void *) * (array->count - pos));
104*cc4ad7daSAndroid Build Coastguard Worker 
105*cc4ad7daSAndroid Build Coastguard Worker 	if (array->count + array->step < array->total) {
106*cc4ad7daSAndroid Build Coastguard Worker 		int r = array_realloc(array, array->total - array->step);
107*cc4ad7daSAndroid Build Coastguard Worker 		/* ignore error */
108*cc4ad7daSAndroid Build Coastguard Worker 		if (r < 0)
109*cc4ad7daSAndroid Build Coastguard Worker 			return 0;
110*cc4ad7daSAndroid Build Coastguard Worker 	}
111*cc4ad7daSAndroid Build Coastguard Worker 
112*cc4ad7daSAndroid Build Coastguard Worker 	return 0;
113*cc4ad7daSAndroid Build Coastguard Worker }
114