115 lines
2.1 KiB
C
115 lines
2.1 KiB
C
/*
|
|
* 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 <ian@mirocom.org>
|
|
*/
|
|
|
|
#include <stdlib.h>
|
|
#include <stdint.h>
|
|
#include <stddef.h>
|
|
#include <string.h>
|
|
#include <errno.h>
|
|
#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);
|
|
}
|
|
}
|