diff --git a/core/ptrbox.c b/core/ptrbox.c new file mode 100644 index 0000000..6db8e2c --- /dev/null +++ b/core/ptrbox.c @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2026, Mirocom Laboratories + * Provided under the BSD-3 clause + * + * Abtract: + * This file implements pointer boxes used to provide RAII-like + * allocation behavior. + * Author: + * Ian M. Moffett + */ + +#include +#include +#include +#include +#include +#include "common/ptrbox.h" + +/* + * Allocate a new entry from a reference to some + * data. + * + * @data: Data reference to associate pointer box entry with + */ +static struct ptrbox_entry * +entry_from_data(void *data) +{ + struct ptrbox_entry *entry; + + if ((entry = malloc(sizeof(*entry))) == NULL) { + return NULL; + } + + entry->data = data; + entry->next = NULL; + return entry; +} + +/* + * Add an entry to a pointer box + * + * @ptrbox: Pointer box to add entry to + * @entry: Entry to add to pointer box + */ +static void +ptrbox_add_entry(struct ptrbox *ptrbox, struct ptrbox_entry *entry) +{ + struct ptrbox_entry *ep; + + if (ptrbox == NULL || entry == NULL) { + return; + } + + if (ptrbox->head == NULL || ptrbox->tail == NULL) { + ptrbox->head = entry; + ptrbox->tail = entry; + } else { + ep = ptrbox->tail; + ep->next = entry; + ptrbox->tail = entry; + } +} + +char * +ptrbox_strdup(struct ptrbox *ptrbox, const char *s) +{ + struct ptrbox_entry *entry; + char *p; + + if (ptrbox == NULL || s == NULL) { + return NULL; + } + + if ((p = strdup(s)) == NULL) { + return NULL; + } + + if ((entry = entry_from_data(p)) == NULL) { + return NULL; + } + + ptrbox_add_entry(ptrbox, entry); + return p; +} + +int +ptrbox_init(struct ptrbox *ptrbox) +{ + if (ptrbox == NULL) { + errno = -EINVAL; + return -1; + } + + ptrbox->entry_count = 0; + ptrbox->head = NULL; + ptrbox->tail = NULL; + return 0; +} + +void +ptrbox_destroy(struct ptrbox *ptrbox) +{ + struct ptrbox_entry *entry, *tmp; + + entry = ptrbox->head; + while (entry != NULL) { + if (entry->data != NULL) + free(entry->data); + + tmp = entry; + entry = entry->next; + free(tmp); + } +} diff --git a/include/common/ptrbox.h b/include/common/ptrbox.h new file mode 100644 index 0000000..1e4aa0d --- /dev/null +++ b/include/common/ptrbox.h @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2026, Mirocom Laboratories + * Provided under the BSD-3 clause + * + * Abtract: + * This file implements pointer boxes used to provide RAII-like + * allocation behavior. + * Author: + * Ian M. Moffett + */ + +#ifndef COMMON_PTRBOX_H +#define COMMON_PTRBOX_H 1 + +#include +#include + +/* + * Represents a pointer box entry which stores + * a reference to allocated data and a next pointer. + * + * @data: Allocated data reference + * @next: Next entry + */ +struct ptrbox_entry { + void *data; + struct ptrbox_entry *next; +}; + +/* + * Represents a pointer box which holds a list of pointer + * box entries + * + * @head: Pointer box entry list head + * @entry_count: Number of entries + */ +struct ptrbox { + struct ptrbox_entry *head; + struct ptrbox_entry *tail; + size_t entry_count; +}; + +/* + * Initialize a pointer box + * + * @ptrbox: Pointer box to initialize + * + * Returns zero on success + */ +int ptrbox_init(struct ptrbox *ptrbox); + +/* + * Duplicate a string and store the reference in a pointer box + * + * @ptrbox: Pointerbox to store reference within + * @s: String to duplicate + * + * Returns the duplicated string on success, otherwise a value + * of NULL on failure. + */ +char *ptrbox_strdup(struct ptrbox *ptrbox, const char *s); + +/* + * Destroy all elements within a pointer box + * + * @ptrbox: Pointer box to destroy + */ +void ptrbox_destroy(struct ptrbox *ptrbox); + +#endif /* !COMMON_PTRBOX_H */