view th_datastruct.h @ 751:3091fd1987e9

Rename function argument.
author Matti Hamalainen <ccr@tnsp.org>
date Mon, 09 Jan 2023 09:49:13 +0200
parents ca837a4417f5
children 64cb2b1777a9
line wrap: on
line source

/*
 * Various data structure functions
 * Programmed and designed by Matti 'ccr' Hamalainen
 * (C) Copyright 2002-2022 Tecnic Software productions (TNSP)
 *
 * Please read file 'COPYING' for information on license and distribution.
 */
/// @file
/// @brief Implementations of common data structures like linked lists, ring buffers, autogrowing buffers, etc.
#ifndef TH_DATASTRUCT_H
#define TH_DATASTRUCT_H

#include "th_util.h"

#ifdef __cplusplus
extern "C" {
#endif


/** @brief
 * Doubly linked list structure.
 */
typedef struct th_llist_t
{
    size_t num;  ///< Number of nodes in the list, meaningful ONLY in the current root node of the list
    struct th_llist_t *prev, *next; ///< Pointers to previous and next nodes.
    void *data;  ///< Pointer to data payload of this node, if any
} th_llist_t;


th_llist_t *   th_llist_new(void *data);
void           th_llist_free(th_llist_t *list);
void           th_llist_free_func_data(th_llist_t *list, void (*freefunc)(void *data));
void           th_llist_free_func_node(th_llist_t *list, void (*freefunc)(th_llist_t *node));

void           th_llist_append_node(th_llist_t **list, th_llist_t *node);
th_llist_t *   th_llist_append(th_llist_t **list, void *data);
void           th_llist_prepend_node(th_llist_t **list, th_llist_t *node);
th_llist_t *   th_llist_prepend(th_llist_t **list, void *data);
void           th_llist_delete_node(th_llist_t **list, th_llist_t *node);

th_llist_t *   th_llist_get_nth(th_llist_t *list, const size_t n);
size_t         th_llist_length(const th_llist_t *list);
ssize_t        th_llist_position(const th_llist_t *list, const th_llist_t *node);

void           th_llist_foreach(th_llist_t *list, void (*func)(th_llist_t *node, void *userdata), void *data);
int            th_llist_foreach_cond(th_llist_t *list, int (*func)(th_llist_t *node, void *userdata), void *data, th_llist_t **res);

th_llist_t *   th_llist_find(th_llist_t *list, const void *data);
th_llist_t *   th_llist_find_func(th_llist_t *list, const void *userdata, int (compare)(const void *, const void *));


/** @brief
 * Ringbuffer data structure
 */
typedef struct
{
    bool is_allocated; ///< True if this structure has been allocated dynamically
    void **data;    ///< Array of pointers to the data
    size_t size;    ///< Size of this ringbuffer in elements (aka pointers to data)
    size_t n;       ///< Number of elements currently in the ringbuffer (@p n <= @p size)
    void (*deallocator)(void *data); ///< De-allocator function that frees one element.
} th_ringbuf_t;


int            th_ringbuf_init(th_ringbuf_t *buf, const size_t size, void (*mdeallocator)(void *data));
int            th_ringbuf_new(th_ringbuf_t **buf, const size_t size, void (*mdeallocator)(void *data));
int            th_ringbuf_grow(th_ringbuf_t *buf, const size_t n);
void           th_ringbuf_free(th_ringbuf_t *buf);
void           th_ringbuf_add(th_ringbuf_t *buf, void *ptr);


/* Growing buffers
 */
#define TH_BUFGROW       (32)


/* Simple growing string buffer
 */
bool    th_strbuf_grow(char **buf, size_t *bufsize, size_t *len, const size_t grow);
bool    th_strbuf_putch(char **buf, size_t *bufsize, size_t *len, const uint8_t ch);
bool    th_strbuf_putsn(char **buf, size_t *bufsize, size_t *len, const char *str, const size_t slen);
bool    th_strbuf_puts(char **buf, size_t *bufsize, size_t *len, const char *str);


/** @brief
 * Simple growing buffer structure
 */
typedef struct
{
    bool is_allocated; ///< True if this structure has been allocated dynamically
    uint8_t *data;     ///< Pointer to data
    size_t size;       ///< Current allocated size of data
    size_t len;        ///< Actual used size of data (must be < size)
    size_t mingrow;    ///< Minimum amount of bytes to grow allocation by
                       ///< If 0, grow by TH_BUFGROW
} th_growbuf_t;


/* Growing byte buffer
 */
void    th_growbuf_init(th_growbuf_t *buf, const size_t mingrow);
void    th_growbuf_clear(th_growbuf_t *buf);
th_growbuf_t *th_growbuf_new(const size_t mingrow);
void    th_growbuf_free(th_growbuf_t *buf);


bool    th_growbuf_grow(th_growbuf_t *buf, const size_t grow);
bool    th_growbuf_puts(th_growbuf_t *buf, const char *str, bool eos);
bool    th_growbuf_putch(th_growbuf_t *buf, const char ch);
bool    th_growbuf_put_str(th_growbuf_t *buf, const void *s, const size_t len);
bool    th_growbuf_put_u8(th_growbuf_t *buf, const uint8_t val);
bool    th_growbuf_put_u16_be(th_growbuf_t *buf, const uint16_t val);
bool    th_growbuf_put_u16_le(th_growbuf_t *buf, const uint16_t val);
bool    th_growbuf_put_u32_be(th_growbuf_t *buf, const uint32_t val);
bool    th_growbuf_put_u32_le(th_growbuf_t *buf, const uint32_t val);


/** @brief
 * Growing pointerlist/array structure
 */
typedef struct
{
    bool is_allocated;
    size_t nitems, nallocated, ngrow;
    void **items;
} th_ptrlist_t;


int     th_ptrlist_init(th_ptrlist_t *list, const size_t ninitial, const size_t ngrow);
int     th_ptrlist_new(th_ptrlist_t **list, const size_t ninitial, const size_t ngrow);
int     th_ptrlist_append(th_ptrlist_t *list, void *data);
void    th_ptrlist_free(th_ptrlist_t *list, void (*mdeallocator)(void *data));


#ifdef __cplusplus
}
#endif
#endif // TH_DATASTRUCT_H