summaryrefslogtreecommitdiffstats
path: root/common/refarray/ref_array.c
diff options
context:
space:
mode:
Diffstat (limited to 'common/refarray/ref_array.c')
-rw-r--r--common/refarray/ref_array.c489
1 files changed, 0 insertions, 489 deletions
diff --git a/common/refarray/ref_array.c b/common/refarray/ref_array.c
deleted file mode 100644
index d02f9aed8..000000000
--- a/common/refarray/ref_array.c
+++ /dev/null
@@ -1,489 +0,0 @@
-/*
- REF ARRAY
-
- Implementation of the dynamic array with reference count.
-
- Copyright (C) Dmitri Pal <dpal@redhat.com> 2009
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
- 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, see <http://www.gnu.org/licenses/>.
-*/
-
-#define _GNU_SOURCE
-#include <errno.h> /* for errors */
-#include <stdint.h>
-#include <malloc.h>
-#include <string.h>
-#include <stdio.h>
-
-#include "ref_array.h"
-#include "config.h"
-#include "trace.h"
-
-/* The structure used in referenced array */
-struct ref_array {
- void *storage; /* The storage buffer */
- size_t elsize; /* Size of one element in the buffer */
- uint32_t size; /* Size of the storage in items */
- uint32_t grow_by; /* What increment use to reallocate memory */
- uint32_t len; /* Number of the elements in the array */
- uint32_t refcount; /* Reference count */
- ref_array_fn cb; /* Cleanup callback */
- void *cb_data; /* Caller's callback data */
-};
-
-/****************************************************/
-/* INTERNAL FUNCTIONS */
-/****************************************************/
-static int ref_array_grow(struct ref_array *ra)
-{
- int error = EOK;
- void *newbuf = NULL;
-
- TRACE_FLOW_STRING("ref_array_grow", "Entry");
-
- TRACE_INFO_NUMBER("Current length: ", ra->len);
- TRACE_INFO_NUMBER("Current size: ", ra->size);
-
- /* Grow buffer if needed */
- newbuf = realloc(ra->storage, (ra->size + ra->grow_by) * ra->elsize);
- if (newbuf == NULL) {
- TRACE_ERROR_NUMBER("Failed to allocate memory.", ENOMEM);
- return ENOMEM;
- }
-
- ra->storage = newbuf;
- ra->size += ra->grow_by;
-
- TRACE_INFO_NUMBER("Final size: ", ra->size);
- TRACE_FLOW_NUMBER("elapi_grow_data. Exit. Returning", error);
- return error;
-
-}
-
-
-/****************************************************/
-/* PUBLIC FUNCTIONS */
-/****************************************************/
-
-/* Create referenced array */
-int ref_array_create(struct ref_array **ra,
- size_t elemsz,
- uint32_t grow_by,
- ref_array_fn cb,
- void *data)
-{
- struct ref_array *new_ra = NULL;
-
- TRACE_FLOW_STRING("ref_array_create", "Entry");
-
- if (!ra) {
- TRACE_ERROR_NUMBER("Uninitialized argument.", EINVAL);
- return EINVAL;
- }
-
- if ((!elemsz) || (!grow_by)) {
- TRACE_ERROR_NUMBER("Invalid argument.", EINVAL);
- return EINVAL;
- }
-
- new_ra = (struct ref_array *)malloc(sizeof(struct ref_array));
-
- if (!new_ra) {
- TRACE_ERROR_NUMBER("Failed to allocate memory.", ENOMEM);
- return ENOMEM;
- }
-
- new_ra->storage = NULL;
- new_ra->elsize = elemsz;
- new_ra->size = 0;
- new_ra->grow_by = grow_by;
- new_ra->len = 0;
- new_ra->refcount = 1;
- new_ra->cb = cb;
- new_ra->cb_data = data;
-
- *ra = new_ra;
-
- TRACE_FLOW_STRING("ref_array_create", "Exit");
- return EOK;
-}
-
-/* Get new reference to an array */
-struct ref_array *ref_array_getref(struct ref_array *ra)
-{
- TRACE_FLOW_STRING("ref_array_getref", "Entry");
-
- /* Check if array is not NULL */
- if (ra) {
- TRACE_INFO_NUMBER("Increasing reference count. Current: ", ra->refcount);
- /* Increase reference count */
- ra->refcount++;
- TRACE_INFO_NUMBER("Increased reference count. New: ", ra->refcount);
-
- }
- else {
- TRACE_ERROR_STRING("Uninitialized array.", "Returning NULL");
- }
-
- TRACE_FLOW_STRING("ref_array_getref", "Exit");
- return ra;
-}
-
-/* Delete the array */
-void ref_array_destroy(struct ref_array *ra)
-{
- int idx;
-
- TRACE_FLOW_STRING("ref_array_destroy", "Entry");
-
- /* Check if array is not NULL */
- if (!ra) {
- TRACE_ERROR_STRING("Uninitialized array.", "Coding error???");
- return;
- }
-
- TRACE_INFO_NUMBER("Current reference count: ", ra->refcount);
- if (ra->refcount) {
- /* Decrease reference count */
- ra->refcount--;
- if (ra->refcount == 0) {
- TRACE_INFO_NUMBER("It is time to delete array. Count:", ra->refcount);
- if (ra->cb) {
- for (idx = 0; idx < ra->len; idx++) {
- ra->cb((unsigned char *)(ra->storage) + idx * ra->elsize,
- REF_ARRAY_DESTROY, ra->cb_data);
- }
- }
- free(ra->storage);
- free(ra);
- }
- }
- else {
- /* Should never be here...
- * This can happen if the caller by mistake would try to
- * destroy the object from within the callback. Brrr....
- */
- TRACE_ERROR_STRING("Reference count is 0.", "Coding error???");
- }
-
- TRACE_FLOW_STRING("ref_array_destroy", "Exit");
-}
-
-/* Add new element to the array */
-int ref_array_append(struct ref_array *ra, void *element)
-{
- int error = EOK;
-
- TRACE_FLOW_STRING("ref_array_append", "Entry");
- if ((!ra) || (!element)) {
- TRACE_ERROR_NUMBER("Uninitialized argument.", EINVAL);
- return EINVAL;
- }
-
- /* Do we have enough room for a new element? */
- if (ra->size == ra->len) {
- error = ref_array_grow(ra);
- if (error) {
- TRACE_ERROR_NUMBER("Failed to grow array.", error);
- return error;
- }
- }
-
- /* Copy element */
- memcpy((unsigned char *)(ra->storage) + ra->len * ra->elsize,
- element,
- ra->elsize);
-
- ra->len++;
-
- TRACE_FLOW_STRING("ref_array_append", "Exit");
- return error;
-}
-
-/* Get element */
-void *ref_array_get(struct ref_array *ra, uint32_t idx, void *acptr)
-{
- TRACE_FLOW_STRING("ref_array_get", "Entry");
-
- if (!ra) {
- TRACE_ERROR_STRING("Uninitialized argument.", "");
- return NULL;
- }
-
- if (idx >= ra->len) {
- TRACE_ERROR_NUMBER("Invalid idx.", idx);
- return NULL;
- }
-
- TRACE_INFO_NUMBER("Index: ", idx);
-
- if (acptr) {
-
- TRACE_INFO_STRING("Copying data.", "");
- memcpy(acptr,
- (unsigned char *)(ra->storage) + idx * ra->elsize,
- ra->elsize);
-
- }
-
- TRACE_FLOW_STRING("ref_array_get returning internal storage", "Exit");
- return (unsigned char *)(ra->storage) + idx * ra->elsize;
-}
-
-
-/* Get length */
-int ref_array_getlen(struct ref_array *ra, uint32_t *len)
-{
- TRACE_FLOW_STRING("ref_array_getlen", "Entry");
-
- if ((!ra) || (!len)) {
- TRACE_ERROR_STRING("Uninitialized argument.", "");
- return EINVAL;
- }
-
- *len = ra->len;
-
- TRACE_FLOW_STRING("ref_array_getlen", "Exit");
- return EOK;
-}
-
-/* Alternative function to get length */
-uint32_t ref_array_len(struct ref_array *ra)
-{
- TRACE_FLOW_STRING("ref_array_len", "Entry");
-
- if (!ra) {
- TRACE_ERROR_STRING("Uninitialized argument.", "");
- errno = EINVAL;
- return 0;
- }
-
- TRACE_FLOW_STRING("ref_array_len", "Exit");
- return ra->len;
-}
-
-
-/* Insert a new element into the array */
-int ref_array_insert(struct ref_array *ra,
- uint32_t idx,
- void *element)
-{
- int error = EOK;
- uint32_t i;
-
- TRACE_FLOW_STRING("ref_array_insert", "Entry");
-
- if ((!ra) || (!element)) {
- TRACE_ERROR_NUMBER("Uninitialized argument.", EINVAL);
- return EINVAL;
- }
-
- if (idx > ra->len) {
- TRACE_ERROR_NUMBER("Index is out of range", ERANGE);
- return ERANGE;
- }
-
- /* Do we have enough room for a new element? */
- if (ra->size == ra->len) {
- error = ref_array_grow(ra);
- if (error) {
- TRACE_ERROR_NUMBER("Failed to grow array.", error);
- return error;
- }
- }
-
- /* Shift elements right */
- for (i = ra->len; i >= (idx + 1); i--) {
- memcpy((unsigned char *)(ra->storage) + i * ra->elsize,
- (unsigned char *)(ra->storage) + (i - 1) * ra->elsize,
- ra->elsize);
- }
-
- /* Overwrite element */
- memcpy((unsigned char *)(ra->storage) + idx * ra->elsize,
- element,
- ra->elsize);
-
- ra->len++;
-
- TRACE_FLOW_STRING("ref_array_insert", "Exit");
- return error;
-
-}
-
-
-/* Replace element in the array */
-int ref_array_replace(struct ref_array *ra,
- uint32_t idx,
- void *element)
-{
- int error = EOK;
-
- TRACE_FLOW_STRING("ref_array_replace", "Entry");
-
- if ((!ra) || (!element)) {
- TRACE_ERROR_NUMBER("Uninitialized argument.", EINVAL);
- return EINVAL;
- }
-
- if (idx > ra->len) {
- TRACE_ERROR_NUMBER("Index is out of range", ERANGE);
- return ERANGE;
- }
-
- /* Clear old element */
- ra->cb((unsigned char *)(ra->storage) + idx * ra->elsize,
- REF_ARRAY_DELETE, ra->cb_data);
-
- /* Overwrite element */
- memcpy((unsigned char *)(ra->storage) + idx * ra->elsize,
- element,
- ra->elsize);
-
-
- TRACE_FLOW_STRING("ref_array_replace", "Exit");
- return error;
-}
-
-
-/* Remove element from the array */
-int ref_array_remove(struct ref_array *ra,
- uint32_t idx)
-{
- int error = EOK;
- uint32_t i;
-
- TRACE_FLOW_STRING("ref_array_remove", "Entry");
-
- if (!ra) {
- TRACE_ERROR_NUMBER("Uninitialized argument.", EINVAL);
- return EINVAL;
- }
-
- if (idx >= ra->len) {
- TRACE_ERROR_NUMBER("Index is out of range", ERANGE);
- return ERANGE;
- }
-
- /* Clear old element */
- ra->cb((unsigned char *)(ra->storage) + idx * ra->elsize,
- REF_ARRAY_DELETE, ra->cb_data);
-
- /* Shift elements left */
- for (i = idx + 1; i < ra->len; i++) {
- memcpy((unsigned char *)(ra->storage) + (i - 1) * ra->elsize,
- (unsigned char *)(ra->storage) + i * ra->elsize,
- ra->elsize);
- }
-
- ra->len--;
-
- TRACE_FLOW_STRING("ref_array_remove", "Exit");
- return error;
-}
-
-/* Reset array */
-void ref_array_reset(struct ref_array *ra)
-{
- int idx;
-
- TRACE_FLOW_STRING("ref_array_reset", "Entry");
-
- /* Check if array is not NULL */
- if (!ra) {
- TRACE_ERROR_STRING("Uninitialized array.", "Coding error???");
- return;
- }
-
- if (ra->cb) {
- for (idx = 0; idx < ra->len; idx++) {
- ra->cb((unsigned char *)(ra->storage) + idx * ra->elsize,
- REF_ARRAY_DESTROY, ra->cb_data);
- }
- }
-
- free(ra->storage);
- ra->storage = NULL;
- ra->size = 0;
- ra->len = 0;
-
- TRACE_FLOW_STRING("ref_array_reset", "Exit");
-}
-
-/* Swap two elements in the array */
-int ref_array_swap(struct ref_array *ra,
- uint32_t idx1,
- uint32_t idx2)
-{
- int error = EOK;
- void *temp = NULL;
-
- TRACE_FLOW_STRING("ref_array_swap", "Entry");
-
- if (!ra) {
- TRACE_ERROR_NUMBER("Uninitialized argument.", EINVAL);
- return EINVAL;
- }
-
- if ((idx1 >= ra->len) ||
- (idx2 >= ra->len)) {
- TRACE_ERROR_NUMBER("Index is out of range", ERANGE);
- return ERANGE;
- }
-
- if (idx1 == idx2) {
- TRACE_FLOW_STRING("ref_array_swap", "Noop return");
- return EOK;
- }
-
- temp = malloc(ra->elsize);
- if (!temp) {
- TRACE_FLOW_STRING("Failed to allocate memory for temp storage.", "");
- return ENOMEM;
- }
-
- memcpy(temp,
- (unsigned char *)(ra->storage) + idx2 * ra->elsize,
- ra->elsize);
- memcpy((unsigned char *)(ra->storage) + idx2 * ra->elsize,
- (unsigned char *)(ra->storage) + idx1 * ra->elsize,
- ra->elsize);
- memcpy((unsigned char *)(ra->storage) + idx1 * ra->elsize,
- temp,
- ra->elsize);
-
- free(temp);
-
- TRACE_FLOW_STRING("ref_array_swap", "Exit");
- return error;
-}
-
-/* Debug function */
-void ref_array_debug(struct ref_array *ra)
-{
- int i,j;
-
- printf("\nARRAY DUMP START\n");
- printf("Length = %u\n", ra->len);
- printf("Size = %u\n", ra->size);
- printf("Element = %u\n", (unsigned int)(ra->elsize));
- printf("Grow by = %u\n", ra->grow_by);
- printf("Count = %u\n", ra->refcount);
- printf("ARRAY:\n");
- for (i = 0; i < ra->len; i++) {
- for (j = 0; j < ra->elsize; j++) {
- printf("%x", *((unsigned char *)(ra->storage) + i * ra->elsize + j));
- }
- printf("\n%s\n", *((char **)((unsigned char *)(ra->storage) + i * ra->elsize)));
- }
- printf("\nARRAY DUMP END\n\n");
-}