Root/
1 | #include "cache.h" |
2 | #include <linux/kernel.h> |
3 | |
4 | int prefixcmp(const char *str, const char *prefix) |
5 | { |
6 | for (; ; str++, prefix++) |
7 | if (!*prefix) |
8 | return 0; |
9 | else if (*str != *prefix) |
10 | return (unsigned char)*prefix - (unsigned char)*str; |
11 | } |
12 | |
13 | /* |
14 | * Used as the default ->buf value, so that people can always assume |
15 | * buf is non NULL and ->buf is NUL terminated even for a freshly |
16 | * initialized strbuf. |
17 | */ |
18 | char strbuf_slopbuf[1]; |
19 | |
20 | void strbuf_init(struct strbuf *sb, ssize_t hint) |
21 | { |
22 | sb->alloc = sb->len = 0; |
23 | sb->buf = strbuf_slopbuf; |
24 | if (hint) |
25 | strbuf_grow(sb, hint); |
26 | } |
27 | |
28 | void strbuf_release(struct strbuf *sb) |
29 | { |
30 | if (sb->alloc) { |
31 | free(sb->buf); |
32 | strbuf_init(sb, 0); |
33 | } |
34 | } |
35 | |
36 | char *strbuf_detach(struct strbuf *sb, size_t *sz) |
37 | { |
38 | char *res = sb->alloc ? sb->buf : NULL; |
39 | if (sz) |
40 | *sz = sb->len; |
41 | strbuf_init(sb, 0); |
42 | return res; |
43 | } |
44 | |
45 | void strbuf_grow(struct strbuf *sb, size_t extra) |
46 | { |
47 | if (sb->len + extra + 1 <= sb->len) |
48 | die("you want to use way too much memory"); |
49 | if (!sb->alloc) |
50 | sb->buf = NULL; |
51 | ALLOC_GROW(sb->buf, sb->len + extra + 1, sb->alloc); |
52 | } |
53 | |
54 | static void strbuf_splice(struct strbuf *sb, size_t pos, size_t len, |
55 | const void *data, size_t dlen) |
56 | { |
57 | if (pos + len < pos) |
58 | die("you want to use way too much memory"); |
59 | if (pos > sb->len) |
60 | die("`pos' is too far after the end of the buffer"); |
61 | if (pos + len > sb->len) |
62 | die("`pos + len' is too far after the end of the buffer"); |
63 | |
64 | if (dlen >= len) |
65 | strbuf_grow(sb, dlen - len); |
66 | memmove(sb->buf + pos + dlen, |
67 | sb->buf + pos + len, |
68 | sb->len - pos - len); |
69 | memcpy(sb->buf + pos, data, dlen); |
70 | strbuf_setlen(sb, sb->len + dlen - len); |
71 | } |
72 | |
73 | void strbuf_remove(struct strbuf *sb, size_t pos, size_t len) |
74 | { |
75 | strbuf_splice(sb, pos, len, NULL, 0); |
76 | } |
77 | |
78 | void strbuf_add(struct strbuf *sb, const void *data, size_t len) |
79 | { |
80 | strbuf_grow(sb, len); |
81 | memcpy(sb->buf + sb->len, data, len); |
82 | strbuf_setlen(sb, sb->len + len); |
83 | } |
84 | |
85 | void strbuf_addf(struct strbuf *sb, const char *fmt, ...) |
86 | { |
87 | int len; |
88 | va_list ap; |
89 | |
90 | if (!strbuf_avail(sb)) |
91 | strbuf_grow(sb, 64); |
92 | va_start(ap, fmt); |
93 | len = vscnprintf(sb->buf + sb->len, sb->alloc - sb->len, fmt, ap); |
94 | va_end(ap); |
95 | if (len < 0) |
96 | die("your vscnprintf is broken"); |
97 | if (len > strbuf_avail(sb)) { |
98 | strbuf_grow(sb, len); |
99 | va_start(ap, fmt); |
100 | len = vscnprintf(sb->buf + sb->len, sb->alloc - sb->len, fmt, ap); |
101 | va_end(ap); |
102 | if (len > strbuf_avail(sb)) { |
103 | die("this should not happen, your snprintf is broken"); |
104 | } |
105 | } |
106 | strbuf_setlen(sb, sb->len + len); |
107 | } |
108 | |
109 | ssize_t strbuf_read(struct strbuf *sb, int fd, ssize_t hint) |
110 | { |
111 | size_t oldlen = sb->len; |
112 | size_t oldalloc = sb->alloc; |
113 | |
114 | strbuf_grow(sb, hint ? hint : 8192); |
115 | for (;;) { |
116 | ssize_t cnt; |
117 | |
118 | cnt = read(fd, sb->buf + sb->len, sb->alloc - sb->len - 1); |
119 | if (cnt < 0) { |
120 | if (oldalloc == 0) |
121 | strbuf_release(sb); |
122 | else |
123 | strbuf_setlen(sb, oldlen); |
124 | return -1; |
125 | } |
126 | if (!cnt) |
127 | break; |
128 | sb->len += cnt; |
129 | strbuf_grow(sb, 8192); |
130 | } |
131 | |
132 | sb->buf[sb->len] = '\0'; |
133 | return sb->len - oldlen; |
134 | } |
135 |
Branches:
ben-wpan
ben-wpan-stefan
javiroman/ks7010
jz-2.6.34
jz-2.6.34-rc5
jz-2.6.34-rc6
jz-2.6.34-rc7
jz-2.6.35
jz-2.6.36
jz-2.6.37
jz-2.6.38
jz-2.6.39
jz-3.0
jz-3.1
jz-3.11
jz-3.12
jz-3.13
jz-3.15
jz-3.16
jz-3.18-dt
jz-3.2
jz-3.3
jz-3.4
jz-3.5
jz-3.6
jz-3.6-rc2-pwm
jz-3.9
jz-3.9-clk
jz-3.9-rc8
jz47xx
jz47xx-2.6.38
master
Tags:
od-2011-09-04
od-2011-09-18
v2.6.34-rc5
v2.6.34-rc6
v2.6.34-rc7
v3.9