diff --git a/Makefile b/Makefile index 72a0eab0..ff1230e5 100644 --- a/Makefile +++ b/Makefile @@ -194,6 +194,7 @@ objects = \ kernel-shared/uuid-tree.o \ kernel-shared/volumes.o \ kernel-shared/zoned.o \ + common/array.o \ common/cpu-utils.o \ common/device-scan.o \ common/device-utils.o \ diff --git a/common/array.c b/common/array.c new file mode 100644 index 00000000..c1c4417e --- /dev/null +++ b/common/array.c @@ -0,0 +1,99 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License v2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 021110-1307, USA. + */ + +#define _GNU_SOURCE 1 +#include +#include +#include +#include "common/array.h" + +/* + * Extensible array of pointers. Length is the number of user defined pointers, + * capacity is the whole allocated size. Pointers are potentially unstable after + * an append operation. Array initialized to all zeros is valid and can be extended. + */ + +static const int alloc_increment = 32; + +/* Initialize new array, preallocate @capacity elemennts. */ +int array_init(struct array *arr, unsigned int capacity) +{ + void *tmp; + + arr->data = NULL; + arr->length = 0; + arr->capacity = capacity; + if (arr->capacity == 0) + arr->capacity = alloc_increment; + + tmp = calloc(arr->capacity, sizeof(void *)); + if (!tmp) + return -1; + arr->data = tmp; + return 0; +} + +/* Free internal data array. */ +void array_free(struct array *arr) +{ + free(arr->data); + arr->length = 0; + arr->capacity = 0; + arr->data = NULL; +} + +/* Free all elements up to length. */ +void array_free_elements(struct array *arr) +{ + unsigned int i; + + for (i = 0; i < arr->length; i++) { + free(arr->data[i]); + arr->data[i] = NULL; + } + arr->length = 0; +} + +/* Reset all elements to NULL up to capacity. */ +void array_clear(struct array *arr) +{ + for (unsigned int i = 0; i < arr->capacity; i++) + arr->data[i] = NULL; +} + +/* Use the whole capacity for elements. */ +void array_use_capacity(struct array *arr) +{ + arr->length = arr->capacity; +} + +/* Append a new element (increas length), extend the array if needed. */ +int array_append(struct array *arr, void *element) +{ + if (arr->length == arr->capacity) { + void **tmp; + + tmp = realloc(arr->data, (arr->capacity + alloc_increment) * sizeof(void *)); + if (!tmp) + return -1; + arr->data = tmp; + memset(&arr->data[arr->capacity], 0, alloc_increment * sizeof(void *)); + arr->capacity += alloc_increment; + } + arr->data[arr->length] = element; + arr->length++; + return 0; +} diff --git a/common/array.h b/common/array.h new file mode 100644 index 00000000..087a85d4 --- /dev/null +++ b/common/array.h @@ -0,0 +1,36 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License v2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 021110-1307, USA. + */ + +#ifndef __COMMON_ARRAY_H__ +#define __COMMON_ARRAY_H__ + +/* + * Extensible array of pointers. + */ +struct array { + void **data; + unsigned int length; + unsigned int capacity; +}; + +int array_init(struct array *arr, unsigned int capacity); +void array_free(struct array *arr); +void array_free_elements(struct array *arr); +void array_clear(struct array *arr); +void array_use_capacity(struct array *arr); +int array_append(struct array *arr, void *element); + +#endif