Code

7136de14c63b0a93c271156fcef86ca26cecea7a
[git.git] / strbuf.c
1 #include "cache.h"
2 #include "strbuf.h"
4 void strbuf_init(struct strbuf *sb) {
5         memset(sb, 0, sizeof(*sb));
6 }
8 void strbuf_release(struct strbuf *sb) {
9         free(sb->buf);
10         memset(sb, 0, sizeof(*sb));
11 }
13 void strbuf_reset(struct strbuf *sb) {
14         if (sb->len)
15                 strbuf_setlen(sb, 0);
16         sb->eof = 0;
17 }
19 char *strbuf_detach(struct strbuf *sb) {
20         char *res = sb->buf;
21         strbuf_init(sb);
22         return res;
23 }
25 void strbuf_grow(struct strbuf *sb, size_t extra) {
26         if (sb->len + extra + 1 <= sb->len)
27                 die("you want to use way too much memory");
28         ALLOC_GROW(sb->buf, sb->len + extra + 1, sb->alloc);
29 }
31 void strbuf_add(struct strbuf *sb, const void *data, size_t len) {
32         strbuf_grow(sb, len);
33         memcpy(sb->buf + sb->len, data, len);
34         strbuf_setlen(sb, sb->len + len);
35 }
37 void strbuf_addf(struct strbuf *sb, const char *fmt, ...) {
38         int len;
39         va_list ap;
41         va_start(ap, fmt);
42         len = vsnprintf(sb->buf + sb->len, sb->alloc - sb->len, fmt, ap);
43         va_end(ap);
44         if (len < 0) {
45                 len = 0;
46         }
47         if (len >= strbuf_avail(sb)) {
48                 strbuf_grow(sb, len);
49                 va_start(ap, fmt);
50                 len = vsnprintf(sb->buf + sb->len, sb->alloc - sb->len, fmt, ap);
51                 va_end(ap);
52                 if (len >= strbuf_avail(sb)) {
53                         die("this should not happen, your snprintf is broken");
54                 }
55         }
56         strbuf_setlen(sb, sb->len + len);
57 }
59 size_t strbuf_fread(struct strbuf *sb, size_t size, FILE *f) {
60         size_t res;
62         strbuf_grow(sb, size);
63         res = fread(sb->buf + sb->len, 1, size, f);
64         if (res > 0) {
65                 strbuf_setlen(sb, sb->len + res);
66         }
67         return res;
68 }
70 ssize_t strbuf_read(struct strbuf *sb, int fd)
71 {
72         size_t oldlen = sb->len;
74         for (;;) {
75                 ssize_t cnt;
77                 strbuf_grow(sb, 8192);
78                 cnt = xread(fd, sb->buf + sb->len, sb->alloc - sb->len - 1);
79                 if (cnt < 0) {
80                         strbuf_setlen(sb, oldlen);
81                         return -1;
82                 }
83                 if (!cnt)
84                         break;
85                 sb->len += cnt;
86         }
88         sb->buf[sb->len] = '\0';
89         return sb->len - oldlen;
90 }
92 void read_line(struct strbuf *sb, FILE *fp, int term) {
93         int ch;
94         if (feof(fp)) {
95                 strbuf_release(sb);
96                 sb->eof = 1;
97                 return;
98         }
100         strbuf_reset(sb);
101         while ((ch = fgetc(fp)) != EOF) {
102                 if (ch == term)
103                         break;
104                 strbuf_grow(sb, 1);
105                 sb->buf[sb->len++] = ch;
106         }
107         if (ch == EOF && sb->len == 0) {
108                 strbuf_release(sb);
109                 sb->eof = 1;
110         }
112         strbuf_grow(sb, 1);
113         sb->buf[sb->len] = '\0';