strbuf.h (4242B)
1 /* strbuf - String buffer routines 2 * 3 * Copyright (c) 2010-2012 Mark Pulford <mark@kyne.com.au> 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining 6 * a copy of this software and associated documentation files (the 7 * "Software"), to deal in the Software without restriction, including 8 * without limitation the rights to use, copy, modify, merge, publish, 9 * distribute, sublicense, and/or sell copies of the Software, and to 10 * permit persons to whom the Software is furnished to do so, subject to 11 * the following conditions: 12 * 13 * The above copyright notice and this permission notice shall be 14 * included in all copies or substantial portions of the Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 20 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 21 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 22 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 */ 24 25 #include <stdlib.h> 26 #include <stdarg.h> 27 28 /* Workaround for MSVC */ 29 #ifdef _MSC_VER 30 #define inline __inline 31 #endif 32 33 /* Size: Total bytes allocated to *buf 34 * Length: String length, excluding optional NULL terminator. 35 * Dynamic: True if created via strbuf_new() 36 */ 37 38 typedef struct { 39 char *buf; 40 size_t size; 41 size_t length; 42 int dynamic; 43 int reallocs; 44 int debug; 45 } strbuf_t; 46 47 #ifndef STRBUF_DEFAULT_SIZE 48 #define STRBUF_DEFAULT_SIZE 1023 49 #endif 50 51 /* Initialise */ 52 extern strbuf_t *strbuf_new(size_t len); 53 extern void strbuf_init(strbuf_t *s, size_t len); 54 55 /* Release */ 56 extern void strbuf_free(strbuf_t *s); 57 extern char *strbuf_free_to_string(strbuf_t *s, size_t *len); 58 59 /* Management */ 60 extern void strbuf_resize(strbuf_t *s, size_t len); 61 static size_t strbuf_empty_length(strbuf_t *s); 62 static size_t strbuf_length(strbuf_t *s); 63 static char *strbuf_string(strbuf_t *s, size_t *len); 64 static void strbuf_ensure_empty_length(strbuf_t *s, size_t len); 65 static char *strbuf_empty_ptr(strbuf_t *s); 66 static void strbuf_extend_length(strbuf_t *s, size_t len); 67 static void strbuf_set_length(strbuf_t *s, int len); 68 69 /* Update */ 70 static void strbuf_append_mem(strbuf_t *s, const char *c, size_t len); 71 extern void strbuf_append_string(strbuf_t *s, const char *str); 72 static void strbuf_append_char(strbuf_t *s, const char c); 73 static void strbuf_ensure_null(strbuf_t *s); 74 75 /* Reset string for before use */ 76 static inline void strbuf_reset(strbuf_t *s) 77 { 78 s->length = 0; 79 } 80 81 static inline int strbuf_allocated(strbuf_t *s) 82 { 83 return s->buf != NULL; 84 } 85 86 /* Return bytes remaining in the string buffer 87 * Ensure there is space for a NULL terminator. */ 88 static inline size_t strbuf_empty_length(strbuf_t *s) 89 { 90 return s->size - s->length - 1; 91 } 92 93 static inline void strbuf_ensure_empty_length(strbuf_t *s, size_t len) 94 { 95 if (len > strbuf_empty_length(s)) 96 strbuf_resize(s, s->length + len); 97 } 98 99 static inline char *strbuf_empty_ptr(strbuf_t *s) 100 { 101 return s->buf + s->length; 102 } 103 104 static inline void strbuf_set_length(strbuf_t *s, int len) 105 { 106 s->length = len; 107 } 108 109 static inline void strbuf_extend_length(strbuf_t *s, size_t len) 110 { 111 s->length += len; 112 } 113 114 static inline size_t strbuf_length(strbuf_t *s) 115 { 116 return s->length; 117 } 118 119 static inline void strbuf_append_char(strbuf_t *s, const char c) 120 { 121 strbuf_ensure_empty_length(s, 1); 122 s->buf[s->length++] = c; 123 } 124 125 static inline void strbuf_append_char_unsafe(strbuf_t *s, const char c) 126 { 127 s->buf[s->length++] = c; 128 } 129 130 static inline void strbuf_append_mem(strbuf_t *s, const char *c, size_t len) 131 { 132 strbuf_ensure_empty_length(s, len); 133 memcpy(s->buf + s->length, c, len); 134 s->length += len; 135 } 136 137 static inline void strbuf_append_mem_unsafe(strbuf_t *s, const char *c, size_t len) 138 { 139 memcpy(s->buf + s->length, c, len); 140 s->length += len; 141 } 142 143 static inline void strbuf_ensure_null(strbuf_t *s) 144 { 145 s->buf[s->length] = 0; 146 } 147 148 static inline char *strbuf_string(strbuf_t *s, size_t *len) 149 { 150 if (len) 151 *len = s->length; 152 153 return s->buf; 154 } 155 156 /* vi:ai et sw=4 ts=4: 157 */