From 9cb0b933e260008c6a03e24a4a149f726b8d86b2 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 8 Jun 2004 23:54:24 +0000 Subject: initial commit git-svn-id: file:///home/lennart/svn/public/pulseaudio/trunk@3 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/strbuf.c | 122 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 122 insertions(+) create mode 100644 src/strbuf.c (limited to 'src/strbuf.c') diff --git a/src/strbuf.c b/src/strbuf.c new file mode 100644 index 00000000..7c8b965d --- /dev/null +++ b/src/strbuf.c @@ -0,0 +1,122 @@ +#ifndef foostrbufhfoo +#define foostrbufhfoo + +#include +#include +#include +#include +#include +#include + +struct chunk { + struct chunk *next; + char text[]; +}; + +struct strbuf { + size_t length; + struct chunk *head, *tail; +}; + +struct strbuf *strbuf_new(void) { + struct strbuf *sb = malloc(sizeof(struct strbuf)); + assert(sb); + sb->length = 0; + sb->head = sb->tail = NULL; + return sb; +} + +void strbuf_free(struct strbuf *sb) { + assert(sb); + while (sb->head) { + struct chunk *c = sb->head; + sb->head = sb->head->next; + free(c); + } + + free(sb); +} + +char *strbuf_tostring(struct strbuf *sb) { + char *t, *e; + struct chunk *c; + assert(sb); + + t = malloc(sb->length+1); + assert(t); + + e = t; + *e = 0; + for (c = sb->head; c; c = c->next) { + strcpy(e, c->text); + e = strchr(e, 0); + } + + return t; +} + +void strbuf_puts(struct strbuf *sb, const char *t) { + struct chunk *c; + size_t l; + assert(sb && t); + + l = strlen(t); + c = malloc(sizeof(struct chunk)+l); + assert(c); + + c->next = NULL; + strcpy(c->text, t); + + if (sb->tail) { + assert(sb->head); + sb->tail->next = c; + } else { + assert(!sb->head); + sb->head = c; + } + + sb->tail = c; + sb->length += l; +} + +int strbuf_printf(struct strbuf *sb, const char *format, ...) { + int r, size = 100; + struct chunk *c = NULL; + + assert(sb); + + for(;;) { + va_list ap; + + c = realloc(c, sizeof(struct chunk)+size); + assert(c); + + va_start(ap, format); + r = vsnprintf(c->text, size, format, ap); + va_end(ap); + + if (r > -1 && r < size) { + c->next = NULL; + + if (sb->tail) { + assert(sb->head); + sb->tail->next = c; + } else { + assert(!sb->head); + sb->head = c; + } + + sb->tail = c; + sb->length += r; + + return r; + } + + if (r > -1) /* glibc 2.1 */ + size = r+1; + else /* glibc 2.0 */ + size *= 2; + } +} + +#endif -- cgit