YAZ 5.35.1
wrbuf.c
Go to the documentation of this file.
1/* This file is part of the YAZ toolkit.
2 * Copyright (C) Index Data
3 * See the file LICENSE for details.
4 */
5
11#if HAVE_CONFIG_H
12#include <config.h>
13#endif
14
15#include <stdio.h>
16#include <stdlib.h>
17#include <string.h>
18#include <stdarg.h>
19#include <assert.h>
20
21#include <yaz/wrbuf.h>
22#include <yaz/snprintf.h>
23#include <yaz/yaz-iconv.h>
24
26{
27 WRBUF n;
28
29 if (!(n = (WRBUF)xmalloc(sizeof(*n))))
30 abort();
31 n->buf = 0;
32 n->size = 0;
33 n->pos = 0;
34 wrbuf_grow(n, 1);
35 return n;
36}
37
39{
40 if (b)
41 {
42 xfree(b->buf);
43 xfree(b);
44 }
45}
46
48{
49 b->pos = 0;
50}
51
52int wrbuf_grow(WRBUF b, size_t minsize)
53{
54 size_t togrow;
55
56 if (!b->size)
57 togrow = 1024;
58 else
59 togrow = b->size;
60 if (togrow < minsize)
61 togrow = minsize;
62 b->buf = (char *) xrealloc(b->buf, 1 + (b->size += togrow));
63 if (!b->buf)
64 abort();
65 return 0;
66}
67
68void wrbuf_write(WRBUF b, const char *buf, size_t size)
69{
70 if (size <= 0)
71 return;
72 if (b->pos + size >= b->size)
73 wrbuf_grow(b, size);
74 memcpy(b->buf + b->pos, buf, size);
75 b->pos += size;
76}
77
78void wrbuf_insert(WRBUF b, size_t pos, const char *buf, size_t size)
79{
80 if (size <= 0 || pos > b->pos)
81 return;
82 if (b->pos + size >= b->size)
83 wrbuf_grow(b, size);
84 memmove(b->buf + pos + size, b->buf + pos, b->pos - pos);
85 memcpy(b->buf + pos, buf, size);
86 b->pos += size;
87}
88
89void wrbuf_puts(WRBUF b, const char *buf)
90{
91 wrbuf_write(b, buf, strlen(buf));
92}
93
94void wrbuf_vp_puts(const char *buf, void *client_data)
95{
96 WRBUF b = (WRBUF) client_data;
97 wrbuf_puts(b, buf);
98}
99
100void wrbuf_puts_replace_char(WRBUF b, const char *buf,
101 const char from, const char to)
102{
103 while(*buf)
104 {
105 if (*buf == from)
106 wrbuf_putc(b, to);
107 else
108 wrbuf_putc(b, *buf);
109 buf++;
110 }
111}
112
113void wrbuf_puts_replace_str(WRBUF b, const char *buf,
114 const char *from, const char *to)
115{
116 const char *cp0 = buf;
117 for (;;)
118 {
119 const char *cp1 = strstr(cp0, from);
120 if (!cp1)
121 break;
122 if (cp1 != cp0)
123 wrbuf_write(b, cp0, cp1 - cp0);
124 wrbuf_puts(b, to);
125 cp0 = cp1 + strlen(from);
126 }
127 wrbuf_puts(b, cp0);
128}
129
131{
132 while (b->pos && b->buf[b->pos-1] == ' ')
133 {
134 (b->pos)--;
135 }
136}
137
138void wrbuf_xmlputs(WRBUF b, const char *cp)
139{
140 wrbuf_xmlputs_n(b, cp, strlen(cp));
141}
142
143void wrbuf_xmlputs_n(WRBUF b, const char *cp, size_t size)
144{
145 for (; size; size--)
146 {
147 /* only TAB,CR,LF of ASCII CTRL are allowed in XML 1.0! */
148 if (*cp >= 0 && *cp <= 31)
149 if (*cp != 9 && *cp != 10 && *cp != 13)
150 {
151 cp++; /* we silently ignore (delete) these.. */
152 continue;
153 }
154 switch(*cp)
155 {
156 case '<':
157 wrbuf_puts(b, "&lt;");
158 break;
159 case '>':
160 wrbuf_puts(b, "&gt;");
161 break;
162 case '&':
163 wrbuf_puts(b, "&amp;");
164 break;
165 case '"':
166 wrbuf_puts(b, "&quot;");
167 break;
168 case '\'':
169 wrbuf_puts(b, "&apos;");
170 break;
171 default:
172 wrbuf_putc(b, *cp);
173 }
174 cp++;
175 }
176}
177
178void wrbuf_xml_strip(WRBUF b, const char *cp, size_t size)
179{
180 for (; size; size--)
181 {
182 /* only TAB,CR,LF of ASCII CTRL are allowed in XML 1.0! */
183 if (!(*cp >= 0 && *cp <= 31 && *cp != 9 && *cp != 10 && *cp != 13))
184 wrbuf_putc(b, *cp);
185 cp++;
186 }
187}
188
189void wrbuf_printf(WRBUF b, const char *fmt, ...)
190{
191 va_list ap;
192 char buf[4096];
193
194 va_start(ap, fmt);
195 yaz_vsnprintf(buf, sizeof(buf)-1, fmt, ap);
196 wrbuf_puts (b, buf);
197
198 va_end(ap);
199}
200
201
202int wrbuf_iconv_puts2(WRBUF b, yaz_iconv_t cd, const char *buf,
203 void (*wfunc)(WRBUF, const char *, size_t))
204{
205 return wrbuf_iconv_write2(b, cd, buf, strlen(buf), wfunc);
206}
207
208int wrbuf_iconv_write2(WRBUF b, yaz_iconv_t cd, const char *buf,
209 size_t size,
210 void (*wfunc)(WRBUF, const char *, size_t))
211{
212 int ret = 0;
213 if (cd)
214 {
215 char outbuf[128];
216 size_t inbytesleft = size;
217 const char *inp = buf;
218 while (inbytesleft)
219 {
220 size_t outbytesleft = sizeof(outbuf);
221 char *outp = outbuf;
222 size_t r = yaz_iconv(cd, (char**) &inp, &inbytesleft,
223 &outp, &outbytesleft);
224 if (r == (size_t) (-1))
225 {
226 int e = yaz_iconv_error(cd);
227 if (e != YAZ_ICONV_E2BIG)
228 {
229 ret = -1;
230 break;
231 }
232 }
233 (*wfunc)(b, outbuf, outp - outbuf);
234 }
235 }
236 else
237 (*wfunc)(b, buf, size);
238 return ret;
239}
240
241int wrbuf_iconv_write_x(WRBUF b, yaz_iconv_t cd, const char *buf,
242 size_t size, int cdata)
243{
244 return wrbuf_iconv_write2(b, cd, buf, size,
245 cdata ? wrbuf_xmlputs_n : wrbuf_write);
246}
247
248void wrbuf_iconv_write(WRBUF b, yaz_iconv_t cd, const char *buf, size_t size)
249{
250 wrbuf_iconv_write2(b, cd, buf, size, wrbuf_write);
251}
252
253void wrbuf_iconv_puts(WRBUF b, yaz_iconv_t cd, const char *strz)
254{
255 wrbuf_iconv_write(b, cd, strz, strlen(strz));
256}
257
259{
260 char buf[1];
261 buf[0] = ch;
262 wrbuf_iconv_write(b, cd, buf, 1);
263}
264
265void wrbuf_iconv_write_cdata(WRBUF b, yaz_iconv_t cd, const char *buf, size_t size)
266{
267 wrbuf_iconv_write2(b, cd, buf, size, wrbuf_xmlputs_n);
268}
269
270void wrbuf_iconv_puts_cdata(WRBUF b, yaz_iconv_t cd, const char *strz)
271{
273}
274
276 const char *buf, size_t size)
277{
278 wrbuf_iconv_write2(b, cd, buf, size, wrbuf_json_write);
279}
280
281void wrbuf_iconv_json_puts(WRBUF b, yaz_iconv_t cd, const char *strz)
282{
284}
285
287{
288 if (cd)
289 {
290 char outbuf[16];
291 size_t outbytesleft = sizeof(outbuf);
292 char *outp = outbuf;
293 size_t r = yaz_iconv(cd, 0, 0, &outp, &outbytesleft);
294 if (r != (size_t) (-1))
295 wrbuf_write(b, outbuf, outp - outbuf);
296 }
297}
298
299const char *wrbuf_cstr(WRBUF b)
300{
301 assert(b && b->pos <= b->size);
302 b->buf[b->pos] = '\0';
303 return b->buf;
304}
305
306const char *wrbuf_cstr_null(WRBUF b)
307{
308 if (!b || b->pos == 0)
309 return 0;
310 assert(b->pos <= b->size);
311 b->buf[b->pos] = '\0';
312 return b->buf;
313}
314
315void wrbuf_cut_right(WRBUF b, size_t no_to_remove)
316{
317 if (no_to_remove > b->pos)
318 no_to_remove = b->pos;
319 b->pos = b->pos - no_to_remove;
320}
321
322void wrbuf_puts_escaped(WRBUF b, const char *str)
323{
324 wrbuf_write_escaped(b, str, strlen(str));
325}
326
327void wrbuf_write_escaped(WRBUF b, const char *str, size_t len)
328{
329 size_t i;
330 for (i = 0; i < len; i++)
331 if (str[i] < ' ' || str[i] > 126)
332 wrbuf_printf(b, "\\x%02X", str[i] & 0xff);
333 else
334 wrbuf_putc(b, str[i]);
335}
336
337void wrbuf_json_write(WRBUF b, const char *cp, size_t sz)
338{
339 size_t i;
340 for (i = 0; i < sz; i++)
341 {
342 if (cp[i] > 0 && cp[i] < 32)
343 {
344 wrbuf_putc(b, '\\');
345 switch (cp[i])
346 {
347 case '\b': wrbuf_putc(b, 'b'); break;
348 case '\f': wrbuf_putc(b, 'f'); break;
349 case '\n': wrbuf_putc(b, 'n'); break;
350 case '\r': wrbuf_putc(b, 'r'); break;
351 case '\t': wrbuf_putc(b, 't'); break;
352 default:
353 wrbuf_printf(b, "u%04x", cp[i]);
354 }
355 }
356 else if (cp[i] == '"')
357 {
358 wrbuf_putc(b, '\\'); wrbuf_putc(b, '"');
359 }
360 else if (cp[i] == '\\')
361 {
362 wrbuf_putc(b, '\\'); wrbuf_putc(b, '\\');
363 }
364 else
365 { /* leave encoding as raw UTF-8 */
366 wrbuf_putc(b, cp[i]);
367 }
368 }
369
370}
371
372void wrbuf_json_puts(WRBUF b, const char *str)
373{
374 wrbuf_json_write(b, str, strlen(str));
375}
376
377/*
378 * Local variables:
379 * c-basic-offset: 4
380 * c-file-style: "Stroustrup"
381 * indent-tabs-mode: nil
382 * End:
383 * vim: shiftwidth=4 tabstop=8 expandtab
384 */
385
size_t yaz_iconv(yaz_iconv_t cd, char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft)
just like iconv(3)
Definition siconv.c:146
int yaz_iconv_error(yaz_iconv_t cd)
returns last error - like errno for iconv(3)
Definition siconv.c:279
void yaz_vsnprintf(char *buf, size_t size, const char *fmt, va_list ap)
Definition snprintf.c:17
Header for config file reading utilities.
string buffer
Definition wrbuf.h:43
size_t size
Definition wrbuf.h:46
size_t pos
Definition wrbuf.h:45
char * buf
Definition wrbuf.h:44
void wrbuf_destroy(WRBUF b)
destroy WRBUF and its buffer
Definition wrbuf.c:38
void wrbuf_insert(WRBUF b, size_t pos, const char *buf, size_t size)
inserts buffer into WRBUF at some position
Definition wrbuf.c:78
void wrbuf_iconv_reset(WRBUF b, yaz_iconv_t cd)
iconv reset(flush) to WRBUF
Definition wrbuf.c:286
const char * wrbuf_cstr(WRBUF b)
returns WRBUF content as C-string
Definition wrbuf.c:299
void wrbuf_rewind(WRBUF b)
empty WRBUF content (length of buffer set to 0)
Definition wrbuf.c:47
WRBUF wrbuf_alloc(void)
construct WRBUF
Definition wrbuf.c:25
void wrbuf_iconv_putchar(WRBUF b, yaz_iconv_t cd, int ch)
iconv converts character and appends to WRBUF
Definition wrbuf.c:258
void wrbuf_json_puts(WRBUF b, const char *str)
writes JSON text to WRBUF with escaping
Definition wrbuf.c:372
void wrbuf_printf(WRBUF b, const char *fmt,...)
writes printf result to WRBUF
Definition wrbuf.c:189
void wrbuf_xml_strip(WRBUF b, const char *cp, size_t size)
writes buffer of certain size to WRBUF and strips non-allowed XML chars
Definition wrbuf.c:178
void wrbuf_chop_right(WRBUF b)
chips traling blanks away from WRBUF
Definition wrbuf.c:130
int wrbuf_iconv_write2(WRBUF b, yaz_iconv_t cd, const char *buf, size_t size, void(*wfunc)(WRBUF, const char *, size_t))
General writer of string using iconv and cdata.
Definition wrbuf.c:208
void wrbuf_xmlputs(WRBUF b, const char *cp)
writes C-String to WRBUF and XML encode (as CDATA)
Definition wrbuf.c:138
void wrbuf_puts_replace_str(WRBUF b, const char *buf, const char *from, const char *to)
puts buf to WRBUF and replaces a string with another
Definition wrbuf.c:113
void wrbuf_iconv_write(WRBUF b, yaz_iconv_t cd, const char *buf, size_t size)
Converts buffer using iconv and appends to WRBUF.
Definition wrbuf.c:248
void wrbuf_puts_escaped(WRBUF b, const char *str)
writes C-string to WRBUF and escape non-ASCII characters
Definition wrbuf.c:322
void wrbuf_iconv_puts_cdata(WRBUF b, yaz_iconv_t cd, const char *strz)
iconv converts C-string and appends to WRBUF as XML CDATA
Definition wrbuf.c:270
void wrbuf_iconv_json_write(WRBUF b, yaz_iconv_t cd, const char *buf, size_t size)
Definition wrbuf.c:275
int wrbuf_grow(WRBUF b, size_t minsize)
grow WRBUF larger
Definition wrbuf.c:52
void wrbuf_cut_right(WRBUF b, size_t no_to_remove)
cut size of WRBUF
Definition wrbuf.c:315
void wrbuf_puts_replace_char(WRBUF b, const char *buf, const char from, const char to)
puts buf to WRBUF and replaces a single char
Definition wrbuf.c:100
void wrbuf_write_escaped(WRBUF b, const char *str, size_t len)
writes buffer to WRBUF and escape non-ASCII characters
Definition wrbuf.c:327
int wrbuf_iconv_write_x(WRBUF b, yaz_iconv_t cd, const char *buf, size_t size, int cdata)
writer of string using iconv and cdata
Definition wrbuf.c:241
void wrbuf_vp_puts(const char *buf, void *client_data)
appends C-string to WRBUF - void pointer variant
Definition wrbuf.c:94
void wrbuf_iconv_puts(WRBUF b, yaz_iconv_t cd, const char *strz)
iconv converts C-string and appends to WRBUF
Definition wrbuf.c:253
void wrbuf_xmlputs_n(WRBUF b, const char *cp, size_t size)
writes buffer of certain size to WRBUF and XML encode (as CDATA)
Definition wrbuf.c:143
void wrbuf_puts(WRBUF b, const char *buf)
appends C-string to WRBUF
Definition wrbuf.c:89
int wrbuf_iconv_puts2(WRBUF b, yaz_iconv_t cd, const char *buf, void(*wfunc)(WRBUF, const char *, size_t))
General writer of string using iconv and cdata.
Definition wrbuf.c:202
void wrbuf_iconv_json_puts(WRBUF b, yaz_iconv_t cd, const char *strz)
Definition wrbuf.c:281
void wrbuf_write(WRBUF b, const char *buf, size_t size)
append constant size buffer to WRBUF
Definition wrbuf.c:68
void wrbuf_json_write(WRBUF b, const char *cp, size_t sz)
writes JSON text to WRBUF with escaping
Definition wrbuf.c:337
const char * wrbuf_cstr_null(WRBUF b)
returns WRBUF content as C-string or NULL
Definition wrbuf.c:306
void wrbuf_iconv_write_cdata(WRBUF b, yaz_iconv_t cd, const char *buf, size_t size)
Converts buffer using iconv and appends to WRBUF as XML CDATA.
Definition wrbuf.c:265
Header for WRBUF (growing buffer)
#define wrbuf_putc(b, c)
Definition wrbuf.h:287
struct wrbuf * WRBUF
#define xfree(x)
utility macro which calls xfree_f
Definition xmalloc.h:53
#define xrealloc(o, x)
utility macro which calls xrealloc_f
Definition xmalloc.h:47
#define xmalloc(x)
utility macro which calls malloc_f
Definition xmalloc.h:49
Header for YAZ iconv interface.
#define YAZ_ICONV_E2BIG
error code: Not sufficient room for output buffer
Definition yaz-iconv.h:47