Mercurial > libbuf
view buf.h @ 3:9c6b686f797d
misc: add extern C for C++ friends
author | David Demelier <markand@malikania.fr> |
---|---|
date | Thu, 29 Oct 2020 17:40:28 +0100 |
parents | b1991ee4451d |
children | 9f4f7a266c0b |
line wrap: on
line source
/* * buf.h -- simple string buffer for C * * Copyright (c) 2019-2020 David Demelier <markand@malikania.fr> * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #ifndef BUF_H #define BUF_H /** * \file buf.h * \brief Simple string buffer for C * * This module is meant to be copied directly into your source code and adapted * to your needs. * * # Portability * * This module uses almost pure C99 functions without extensions but uses a few * POSIX macros: ENOMEM. The errno global value won't be set if those macros * are not present. * * It also requires the C99 features: `vsnprintf`, `va_copy`. * * # Allocation strategy * * This module will always try to allocate twice the existing buffer capacity * unless it reaches an overflow. If overflow occurs, it will try to reallocate * only the required portion instead. In any case, on 64-bits machine the * maximum number is usually around 18.5PB which is far from what the system * will allow. * * Functions use standard `malloc(3)`, `realloc(3)` and `free(3)` functions, if * custom allocations are desired, simply edit buf.c and adapt BUF_ macros * at the top of the file or set them at compile time. */ #include <stdarg.h> #include <stdbool.h> #include <stddef.h> /* * User/developer options. * * These macros are only used at compile time and can be redefined using * preprocessor directives. * * - BUF_MALLOC: defaults to malloc * - BUF_REALLOC: defaults to realloc * - BUF_FREE: defaults to free */ /** * \brief Function to allocate memory (defaults to malloc). */ #if !defined(BUF_MALLOC) # define BUF_MALLOC malloc #endif /** * \brief Function to reallocate memory (defaults to realloc). */ #if !defined(BUF_REALLOC) # define BUF_REALLOC realloc #endif /** * \brief Function to free memory (defaults to free). */ #if !defined(BUF_FREE) # define BUF_FREE free #endif #if defined(__cplusplus) extern "C" { #endif /** * \brief Buffer structure. * * You can initialize this structure with 0 before use. * * You may modify the data member yourself but make sure length member is set * accordingly if you change its length. * * The capacity member contains the available size **without** including the * null terminator, this means that a capacity of 5 means you can write 5 * characters plus the null terminator as every function always allocate one * more byte to terminate strings. */ struct buf { char *data; /*!< String data. */ size_t length; /*!< String length */ size_t capacity; /*!< Capacity **not** including null */ }; /** * Initialize the string. * * This is equivalent to `memset(b, 0, sizeof (*b))`. * * \pre b != NULL * \param b the buffer to initialize to 0 */ void buf_init(struct buf *b); /** * Reserve more storage to avoid reallocations. * * This function only change capacity and may reallocate the buffer, length * is unchanged. * * \pre b != NULL * \param b the buffer to grow * \param desired the additional space to request * \return false on error and sets errno */ bool buf_reserve(struct buf *b, size_t desired); /** * Resize the string and sets character into the new storage area if needed. * * In contrast to \ref buf_reserve, this function change the string length * and update the new storage with the given character. If the new size is * smaller then only length is updated, otherwise new memory can be reallocated * if needed. * * Use '\0' if you only want to change the length but still have a NUL * terminated string. * * \pre b != NULL * \param b the buffer to grow * \param size the new size to set * \param c the character to fill (use '\0' if not needed) * \return false on error and sets errno */ bool buf_resize(struct buf *b, size_t size, char c); /** * Reallocate the string to the string's length. * * If the function could not reallocate the memory, the old string buffer is * kept so it is not strictly necessary to check the result. * * \pre b != NULL * \param b the buffer to grow * \return true if the string buffer was actually shrinked */ bool buf_shrink(struct buf *b); /** * Erase a portion of the string. * * \pre b != NULL * \pre pos <= b->length * \param b the string buffer * \param pos the beginning of the portion * \param count the number of characters to remove or -1 to remove up to the end */ void buf_erase(struct buf *b, size_t pos, size_t count); /** * Put a single character. * * \note This function can be slow for large amount of data. * \pre b != NULL * \param b the string buffer * \param c the character to append * \return false on error and sets errno */ bool buf_putc(struct buf *b, char c); /** * Put a string. * * \pre b != NULL * \pre s != NULL * \param b the string buffer * \param s the string to append * \return false on error and sets errno */ bool buf_puts(struct buf *b, const char *s); /** * Append to the string using printf(3) format. * * \pre b != NULL * \pre fmt != NULL * \param b the string buffer * \param fmt the printf(3) format string * \param ... additional arguments * \return false on error and sets errno */ bool buf_printf(struct buf *b, const char *fmt, ...); /** * Similar to \ref buf_printf but using `va_list`. * * \pre b != NULL * \pre fmt != NULL * \param b the string buffer * \param fmt the printf(3) format string * \param ap the variadic arguments pointer * \return false on error and sets errno */ bool buf_vprintf(struct buf *b, const char *fmt, va_list ap); /** * Cut a portion of the string pointed by src into b. * * The pointer b must not contain data as it will be overriden and may be let * uninitialized. * * \pre b != NULL * \pre src != NULL * \pre pos <= b->length * \param b the string buffer * \param src the source origin * \param pos the beginning of the portion * \param count the number of characters to remove or -1 to split up to the end * \return false on error and sets errno */ bool buf_sub(struct buf *b, const struct buf *src, size_t pos, size_t count); /** * Duplicate a string buffer. * * The pointer b must not contain data as it will be overriden and may be let * uninitialized. * * \pre b != NULL * \pre src != NULL * \param b the string buffer * \param src the source origin * \return false on error and sets errno */ bool buf_dup(struct buf *b, const struct buf *src); /** * Clear the buffer. * * This function only change the string length, use \ref buf_shrink if you * want to reduce memory usage. * * \pre b != NULL * \param b the string to update */ void buf_clear(struct buf *b); /** * Clear the buffer. * * This function will effectively free the data member and set all members to * 0. * * \pre b != NULL * \param b the buffer to clear */ void buf_finish(struct buf *b); #if defined(__cplusplus) } #endif #endif /* !BUF_H */