Merge jrn/db/vcs-svn-housekeeping:vcs-svn into master
[svn-fe.git] / compat / strbuf.c
blob6138d860d7acc8859b6ad4117e17006d685bc51f
1 /*
2 * From git 1.7.3.1
3 * License: GPL-2
5 * Modifications (2010-10-19):
6 * - add license header.
7 * - use compat-util.h in place of cache.h.
8 * - include strbuf.h directly instead of through refs.h.
9 * - remove unneeded functions.
10 * Modifications (2012-05-18):
11 * - restore functions needed for downstream changes.
14 #include "compat-util.h"
15 #include "strbuf.h"
18 * Used as the default ->buf value, so that people can always assume
19 * buf is non NULL and ->buf is NUL terminated even for a freshly
20 * initialized strbuf.
22 char strbuf_slopbuf[1];
24 void strbuf_init(struct strbuf *sb, size_t hint)
26 sb->alloc = sb->len = 0;
27 sb->buf = strbuf_slopbuf;
28 if (hint)
29 strbuf_grow(sb, hint);
32 void strbuf_release(struct strbuf *sb)
34 if (sb->alloc) {
35 free(sb->buf);
36 strbuf_init(sb, 0);
40 void strbuf_grow(struct strbuf *sb, size_t extra)
42 if (sb->len + extra + 1 <= sb->len)
43 die("you want to use way too much memory");
44 if (!sb->alloc)
45 sb->buf = NULL;
46 ALLOC_GROW(sb->buf, sb->len + extra + 1, sb->alloc);
49 void strbuf_add(struct strbuf *sb, const void *data, size_t len)
51 strbuf_grow(sb, len);
52 memcpy(sb->buf + sb->len, data, len);
53 strbuf_setlen(sb, sb->len + len);
56 size_t strbuf_fread(struct strbuf *sb, size_t size, FILE *f)
58 size_t res;
59 size_t oldalloc = sb->alloc;
61 strbuf_grow(sb, size);
62 res = fread(sb->buf + sb->len, 1, size, f);
63 if (res > 0)
64 strbuf_setlen(sb, sb->len + res);
65 else if (oldalloc == 0)
66 strbuf_release(sb);
67 return res;
70 void strbuf_splice(struct strbuf *sb, size_t pos, size_t len,
71 const void *data, size_t dlen)
73 if (unsigned_add_overflows(pos, len))
74 die("you want to use way too much memory");
75 if (pos > sb->len)
76 die("`pos' is too far after the end of the buffer");
77 if (pos + len > sb->len)
78 die("`pos + len' is too far after the end of the buffer");
80 if (dlen >= len)
81 strbuf_grow(sb, dlen - len);
82 memmove(sb->buf + pos + dlen,
83 sb->buf + pos + len,
84 sb->len - pos - len);
85 memcpy(sb->buf + pos, data, dlen);
86 strbuf_setlen(sb, sb->len + dlen - len);
89 void strbuf_insert(struct strbuf *sb, size_t pos, const void *data, size_t len)
91 strbuf_splice(sb, pos, 0, data, len);
94 void strbuf_remove(struct strbuf *sb, size_t pos, size_t len)
96 strbuf_splice(sb, pos, len, NULL, 0);