#ifndef STRINGBUF_H1#define STRINGBUF_H2/**3* resizable string buffer4*5* (c) 2017-2020 Steve Bennett <[email protected]>6*7* See utf8.c for licence details.8*/9#ifdef __cplusplus10extern "C" {11#endif1213/** @file14* A stringbuf is a resizing, null terminated string buffer.15*16* The buffer is reallocated as necessary.17*18* In general it is *not* OK to call these functions with a NULL pointer19* unless stated otherwise.20*21* If USE_UTF8 is defined, supports utf8.22*/2324/**25* The stringbuf structure should not be accessed directly.26* Use the functions below.27*/28typedef struct {29int remaining; /**< Allocated, but unused space */30int last; /**< Index of the null terminator (and thus the length of the string) */31#ifdef USE_UTF832int chars; /**< Count of characters */33#endif34char *data; /**< Allocated memory containing the string or NULL for empty */35} stringbuf;3637/**38* Allocates and returns a new stringbuf with no elements.39*/40stringbuf *sb_alloc(void);4142/**43* Frees a stringbuf.44* It is OK to call this with NULL.45*/46void sb_free(stringbuf *sb);4748/**49* Returns an allocated copy of the stringbuf50*/51stringbuf *sb_copy(stringbuf *sb);5253/**54* Returns the byte length of the buffer.55*56* Returns 0 for both a NULL buffer and an empty buffer.57*/58static inline int sb_len(stringbuf *sb) {59return sb->last;60}6162/**63* Returns the utf8 character length of the buffer.64*65* Returns 0 for both a NULL buffer and an empty buffer.66*/67static inline int sb_chars(stringbuf *sb) {68#ifdef USE_UTF869return sb->chars;70#else71return sb->last;72#endif73}7475/**76* Appends a null terminated string to the stringbuf77*/78void sb_append(stringbuf *sb, const char *str);7980/**81* Like sb_append() except does not require a null terminated string.82* The length of 'str' is given as 'len'83*84* Note that in utf8 mode, characters will *not* be counted correctly85* if a partial utf8 sequence is added with sb_append_len()86*/87void sb_append_len(stringbuf *sb, const char *str, int len);8889/**90* Returns a pointer to the null terminated string in the buffer.91*92* Note this pointer only remains valid until the next modification to the93* string buffer.94*95* The returned pointer can be used to update the buffer in-place96* as long as care is taken to not overwrite the end of the buffer.97*/98static inline char *sb_str(const stringbuf *sb)99{100return sb->data;101}102103/**104* Inserts the given string *before* (zero-based) byte 'index' in the stringbuf.105* If index is past the end of the buffer, the string is appended,106* just like sb_append()107*/108void sb_insert(stringbuf *sb, int index, const char *str);109110/**111* Delete 'len' bytes in the string at the given index.112*113* Any bytes past the end of the buffer are ignored.114* The buffer remains null terminated.115*116* If len is -1, deletes to the end of the buffer.117*/118void sb_delete(stringbuf *sb, int index, int len);119120/**121* Clear to an empty buffer.122*/123void sb_clear(stringbuf *sb);124125/**126* Return an allocated copy of buffer and frees 'sb'.127*128* If 'sb' is empty, returns an allocated copy of "".129*/130char *sb_to_string(stringbuf *sb);131132#ifdef __cplusplus133}134#endif135136#endif137138139