"SfR Fresh" - the SfR Freeware/Shareware Archive 
Member "odt2txt-0.4/strbuf.c" of archive odt2txt-0.4.tar.gz:
As a special service "SfR Fresh" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting with prefixed line numbers.
Alternatively you can here view or download the uninterpreted source code file.
That can be also achieved for any archive member file by clicking within an archive contents listing on the first character of the file(path) respectively on the according byte size field.
1 /*
2 * strbuf.c: A simple string buffer
3 *
4 * Copyright (c) 2006-2008 Dennis Stosberg <dennis@stosberg.net>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License,
8 * version 2 as published by the Free Software Foundation
9 */
10
11 #include "strbuf.h"
12
13 static const size_t strbuf_start_sz = 128;
14 static const size_t strbuf_grow_sz = 128;
15
16 static void strbuf_grow(STRBUF *buf); /* enlarge a buffer by strbuf_grow_sz */
17
18 #ifdef STRBUF_CHECK
19 static void die(const char *format, ...) {
20 va_list argp;
21 va_start(argp, format);
22 vfprintf(stderr, format, argp);
23 va_end(argp);
24 fprintf(stderr, "\n");
25 exit(EXIT_FAILURE);
26 }
27
28 static void strbuf_check(STRBUF *buf)
29 {
30 if (!buf)
31 die("buf is null");
32
33 if (!buf->data)
34 die("buf->data is null");
35
36 if (!(buf->opt & STRBUF_NULLOK) && strlen(buf->data) != buf->len)
37 die("length mismatch. strlen says %u, len says %u",
38 (unsigned int)strlen(buf->data), buf->len);
39
40 if (buf->len + 1 > buf->buf_sz)
41 die("overlap");
42 }
43 #else
44 #define strbuf_check(a)
45 #endif
46
47 STRBUF *strbuf_new(void)
48 {
49 STRBUF *buf = ymalloc(sizeof(STRBUF));
50
51 buf->buf_sz = strbuf_start_sz;
52 buf->data = ymalloc(strbuf_start_sz);
53
54 buf->len = 0;
55 buf->data[0] = '\0';
56
57 buf->opt = 0;
58
59 strbuf_check(buf);
60 return buf;
61 }
62
63 void strbuf_free(STRBUF *buf)
64 {
65 strbuf_check(buf);
66
67 yfree(buf->data);
68 yfree(buf);
69 }
70
71 void strbuf_shrink(STRBUF *buf)
72 {
73 strbuf_check(buf);
74
75 buf->buf_sz = buf->len + 1;
76 buf->data = yrealloc(buf->data, buf->buf_sz);
77
78 strbuf_check(buf);
79 }
80
81 size_t strbuf_append_n(STRBUF *buf, const char *str, size_t n)
82 {
83 strbuf_check(buf);
84
85 if (n == 0)
86 return buf->len;
87
88 while (buf->len + n + 1 > buf->buf_sz)
89 strbuf_grow(buf);
90
91 memcpy(buf->data + buf->len, str, n);
92 buf->len += n;
93 *(buf->data + buf->len) = 0;
94
95 strbuf_check(buf);
96 return buf->len;
97 }
98
99 size_t strbuf_append(STRBUF *buf, const char *str)
100 {
101 return strbuf_append_n(buf, str, strlen(str));
102 }
103
104 const char *strbuf_get(STRBUF *buf)
105 {
106 strbuf_check(buf);
107 return buf->data;
108 }
109
110 size_t strbuf_len(STRBUF *buf)
111 {
112 strbuf_check(buf);
113 return buf->len;
114 }
115
116 int strbuf_subst(STRBUF *buf,
117 size_t start, size_t stop,
118 const char *subst)
119 {
120 size_t len;
121 size_t subst_len;
122 int diff;
123
124 strbuf_check(buf);
125
126 if (start > stop) {
127 size_t tmp = start;
128 start = stop;
129 stop = tmp;
130 }
131
132 len = stop - start;
133 subst_len = strlen(subst);
134 diff = subst_len - len;
135
136 if (0 > diff) {
137 memcpy(buf->data + start, subst, subst_len);
138 memmove(buf->data + start + subst_len, buf->data + stop,
139 buf->len - stop + 1);
140
141 } else if (0 == diff) {
142 memcpy(buf->data + start, subst, subst_len);
143
144 } else { /* 0 < diff */
145 while (buf->len + diff + 1 > buf->buf_sz)
146 strbuf_grow(buf);
147
148 memmove(buf->data + start + subst_len, buf->data + stop,
149 buf->len - stop + 1);
150 memcpy(buf->data + start, subst, subst_len);
151 }
152
153 buf->len += diff;
154
155 strbuf_check(buf);
156 return diff;
157 }
158
159 size_t strbuf_append_inflate(STRBUF *buf, FILE *in)
160 {
161 size_t len;
162 z_stream strm;
163 Bytef readbuf[1024];
164 int z_ret;
165 int nullok;
166
167 strbuf_check(buf);
168
169 /* save NULLOK flag */
170 nullok = (buf->opt & STRBUF_NULLOK) ? 1 : 0;
171 strbuf_setopt(buf, STRBUF_NULLOK);
172
173 /* zlib init */
174 strm.zalloc = Z_NULL;
175 strm.zfree = Z_NULL;
176 strm.opaque = Z_NULL;
177 strm.next_in = Z_NULL;
178 strm.avail_in = 0;
179
180 z_ret = inflateInit2(&strm, -15);
181 if (z_ret != Z_OK) {
182 fprintf(stderr, "A: zlib returned error: %d\n", z_ret);
183 exit(EXIT_FAILURE);
184 }
185
186 do {
187 int f_err;
188
189 strm.avail_in = (uInt)fread(readbuf, 1, sizeof(readbuf), in);
190
191 f_err = ferror(in);
192 if (f_err) {
193 (void)inflateEnd(&strm);
194 fprintf(stderr, "stdio error: %d\n", f_err);
195 exit(EXIT_FAILURE); /* TODO: errmsg? continue? */
196 }
197
198 if (strm.avail_in == 0)
199 break;
200
201 strm.next_in = readbuf;
202 do {
203 size_t bytes_inflated;
204
205 while (buf->buf_sz < buf->len + sizeof(readbuf) * 2)
206 strbuf_grow(buf);
207
208 strm.next_out = (Bytef*)(buf->data + buf->len);
209 strm.avail_out = (uInt)(buf->buf_sz - buf->len);
210
211 z_ret = inflate(&strm, Z_SYNC_FLUSH);
212 switch (z_ret) {
213 case Z_NEED_DICT:
214 case Z_DATA_ERROR:
215 case Z_MEM_ERROR:
216 (void)inflateEnd(&strm);
217 fprintf(stderr, "B: zlib returned error: %d\n", z_ret);
218 exit(EXIT_FAILURE);
219 }
220
221 bytes_inflated = (buf->buf_sz - buf->len) - strm.avail_out;
222 buf->len += bytes_inflated;
223
224 } while (strm.avail_out == 0);
225
226 } while (z_ret != Z_STREAM_END);
227
228 /* terminate buffer */
229 if (buf->len + 1 > buf->buf_sz)
230 strbuf_grow(buf);
231 *(buf->data + buf->len) = '\0';
232
233 /* restore NULLOK option */
234 if (!nullok)
235 strbuf_unsetopt(buf, STRBUF_NULLOK);
236
237 strbuf_check(buf);
238
239 len = (size_t)strm.total_out;
240 (void)inflateEnd(&strm);
241
242 if (z_ret != Z_STREAM_END) {
243 fprintf(stderr, "ERR\n");
244 exit(EXIT_FAILURE);
245 }
246
247 return len;
248 }
249
250 static void strbuf_grow(STRBUF *buf)
251 {
252 buf->buf_sz += strbuf_grow_sz;
253 buf->data = yrealloc(buf->data, buf->buf_sz);
254
255 strbuf_check(buf);
256 }
257
258 STRBUF *strbuf_slurp(char *str)
259 {
260 return strbuf_slurp_n(str, strlen(str));
261 }
262
263 STRBUF *strbuf_slurp_n(char *str, size_t len)
264 {
265 STRBUF *buf = ymalloc(sizeof(STRBUF));
266 buf->len = len;
267 buf->buf_sz = len + 1;
268 buf->data = yrealloc(str, buf->buf_sz);
269 *(buf->data + len) = '\0';
270
271 buf->opt = 0;
272
273 return buf;
274 }
275
276 char *strbuf_spit(STRBUF *buf)
277 {
278 char *data;
279
280 strbuf_check(buf);
281
282 strbuf_shrink(buf);
283 data = buf->data;
284 yfree(buf);
285
286 return data;
287 }
288
289 unsigned int strbuf_crc32(STRBUF *buf)
290 {
291 uLong crc = crc32(0L, Z_NULL, 0);
292 crc = crc32(crc, (Bytef *)buf->data, buf->len);
293
294 return (unsigned int)crc;
295 }
296
297 void strbuf_setopt(STRBUF *buf, enum strbuf_opt opt)
298 {
299 buf->opt |= opt;
300 }
301
302 void strbuf_unsetopt(STRBUF *buf, enum strbuf_opt opt)
303 {
304 buf->opt &= ~opt;
305 }