diff options
Diffstat (limited to 'src/dynstr.c')
| -rw-r--r-- | src/dynstr.c | 95 |
1 files changed, 95 insertions, 0 deletions
diff --git a/src/dynstr.c b/src/dynstr.c new file mode 100644 index 0000000..fa9e9e0 --- /dev/null +++ b/src/dynstr.c @@ -0,0 +1,95 @@ +#include "common.h" + +#include "dynstr.h" + +dynstr_t* dynstr_new(void) +{ + dynstr_t* str = calloc(1, sizeof(dynstr_t)); + if (str) + { + str->size = 64; + str->data = malloc(str->size); + if (!str->data) + { + free(str); + return NULL; + } + } + return str; +} + +dynstr_t* dynstr_new_strn(const char* cstr, size_t len) +{ + dynstr_t* str = calloc(1, sizeof(dynstr_t)); + assert(cstr); + if (str) + { + str->len = len; + str->size = len + 1; + str->data = malloc(str->size); + if (!str->data) + { + free(str); + return NULL; + } + memcpy(str->data, cstr, len); + } + return str; +} + +void dynstr_free(dynstr_t* str) +{ + if (str) + { + free(str->data); + free(str); + } +} + +char* dynstr_done(dynstr_t* str) +{ + char* ret; + assert(str); + assert(str->len < str->size); + str->data[str->len] = '\0'; + ret = str->data; + free(str); + return ret; +} + +const char* dynstr_peek(dynstr_t* str) +{ + assert(str); + assert(str->len < str->size); + str->data[str->len] = '\0'; + return str->data; +} + +bool dynstr_nappend(dynstr_t* str, const char* add, size_t len) +{ + assert(str && add); + if (str->len + len >= str->size) + { + size_t ns = MAX(str->size * 2, str->len + len + 1); + char* tmp = realloc(str->data, ns); + if (!tmp) + { + return false; + } + str->data = tmp; + str->size = ns; + } + memcpy(str->data + str->len, add, len); + str->len += len; + return true; +} + +void dynstr_cut(dynstr_t* str, size_t newlen) +{ + assert(str); + assert(newlen <= str->len); + if (newlen < str->len) + { + str->len = newlen; + } +} |
