summaryrefslogtreecommitdiffstats
path: root/src/strbuf.c
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2004-06-08 23:54:24 +0000
committerLennart Poettering <lennart@poettering.net>2004-06-08 23:54:24 +0000
commit9cb0b933e260008c6a03e24a4a149f726b8d86b2 (patch)
treeb54651bafe32d1a817e779f884d1628176465bf0 /src/strbuf.c
parentb1c00dcd0ae51d201f772e7f5fa61acae436a2cf (diff)
initial commit
git-svn-id: file:///home/lennart/svn/public/pulseaudio/trunk@3 fefdeb5f-60dc-0310-8127-8f9354f1896f
Diffstat (limited to 'src/strbuf.c')
-rw-r--r--src/strbuf.c122
1 files changed, 122 insertions, 0 deletions
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 <sys/types.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <string.h>
+#include <stdarg.h>
+#include <stdio.h>
+
+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