Handle streams separately in tree_add_track()
[cmus.git] / gbuf.c
blob95851485851dbec58cc2ab6678900f0131febb87
1 /*
2 * This code is largely based on strbuf in the GIT version control system.
3 */
5 #include "gbuf.h"
6 #include "xmalloc.h"
8 #include <stdarg.h>
10 char gbuf_empty_buffer[1];
12 static inline void gbuf_init(struct gbuf *buf)
14 buf->buffer = gbuf_empty_buffer;
15 buf->alloc = 0;
16 buf->len = 0;
19 void gbuf_grow(struct gbuf *buf, size_t more)
21 size_t align = 16 - 1;
22 size_t alloc = (buf->len + more + 1 + align) & ~align;
24 if (alloc > buf->alloc) {
25 if (!buf->alloc)
26 buf->buffer = NULL;
27 buf->alloc = alloc;
28 buf->buffer = xrealloc(buf->buffer, buf->alloc);
29 // gbuf is not NUL terminated if this was first alloc
30 buf->buffer[buf->len] = 0;
34 void gbuf_free(struct gbuf *buf)
36 if (buf->alloc)
37 free(buf->buffer);
38 gbuf_init(buf);
41 void gbuf_add_ch(struct gbuf *buf, char ch)
43 gbuf_grow(buf, 1);
44 buf->buffer[buf->len++] = ch;
45 buf->buffer[buf->len] = 0;
48 void gbuf_add_bytes(struct gbuf *buf, const void *data, size_t len)
50 gbuf_grow(buf, len);
51 memcpy(buf->buffer + buf->len, data, len);
52 buf->len += len;
53 buf->buffer[buf->len] = 0;
56 void gbuf_add_str(struct gbuf *buf, const char *str)
58 int len = strlen(str);
60 if (!len)
61 return;
62 gbuf_grow(buf, len);
63 memcpy(buf->buffer + buf->len, str, len + 1);
64 buf->len += len;
67 void gbuf_addf(struct gbuf *buf, const char *fmt, ...)
69 va_list ap;
70 int slen;
72 va_start(ap, fmt);
73 slen = vsnprintf(buf->buffer + buf->len, buf->alloc - buf->len, fmt, ap);
74 va_end(ap);
76 if (slen > gbuf_avail(buf)) {
77 gbuf_grow(buf, slen + 1);
79 va_start(ap, fmt);
80 slen = vsnprintf(buf->buffer + buf->len, buf->alloc - buf->len, fmt, ap);
81 va_end(ap);
84 buf->len += slen;
87 void gbuf_set(struct gbuf *buf, int c, size_t count)
89 gbuf_grow(buf, count);
90 memset(buf->buffer + buf->len, c, count);
91 buf->len += count;
92 buf->buffer[buf->len] = 0;
95 char *gbuf_steal(struct gbuf *buf)
97 char *b = buf->buffer;
98 if (!buf->alloc)
99 b = xnew0(char, 1);
100 gbuf_init(buf);
101 return b;