#include #include #include #include #include #include "buffer.h" #include "util.h" static void buf_realloc(struct buffer *buf, size_t new_size) { if (new_size > buf->size) { buf->size = new_size + 1; buf->data = realloc(buf->data, buf->size); } } struct buffer *buf_new(const char *init) { struct buffer *buf = malloc(sizeof(struct buffer)); if (init) { buf->data = strdup(init); buf->len = strlen(init); buf->size = buf->len + 1; } else { buf->size = 1024; buf->data = malloc(buf->size); *buf->data = '\0'; buf->len = 0; } return buf; } void buf_del(struct buffer **buf) { assert(*buf); struct buffer *tmp = *buf; free(tmp->data); free(tmp); *buf = NULL; } struct buffer *buf_dup(struct buffer *src) { struct buffer *dest = malloc(sizeof(struct buffer)); dest->len = src->len; dest->size = src->size; dest->data = malloc(dest->size); memcpy(dest->data, src->data, dest->size); return dest; } char *buf_strdup(struct buffer *buf) { return strdup(buf->data); } void buf_append(struct buffer *buf, const char *str) { size_t len = strlen(str); buf_realloc(buf, buf->len + len + 1); strncat(buf->data, str, buf->size); } void buf_printf(struct buffer *buf, char *fmt, ...) { va_list ap; ssize_t len; va_start(ap, fmt); len = vsnprintf(buf->data, buf->size, fmt, ap); va_end(ap); if (len >= buf->size) { buf_realloc(buf, len + 1); va_start(ap, fmt); len = vsnprintf(buf->data, buf->size, fmt, ap); va_end(ap); } if (len < 0 || len >= buf->size) { fprintf(stderr, "buf_printf: failed to format str"); exit(EXIT_FAILURE); } buf->len = len; }