1 /** \file
2 * XML quoting routines.
3 */
5 /* Based on Lauris' repr_quote_write in repr-io.cpp.
6 *
7 * Copyright (C) 1999-2002 Lauris Kaplinski
8 * Copyright (C) 2004 Monash University
9 *
10 * May be modified and/or redistributed under the terms of version 2
11 * of the GNU General Public License: see the file `COPYING'.
12 */
14 #include <string.h>
15 #include <glib/gmem.h>
18 /** \return strlen(xml_quote_strdup(\a val)) (without doing the malloc).
19 * \pre val != NULL
20 */
21 static size_t
22 xml_quoted_strlen(char const *val)
23 {
24 size_t ret = 0;
25 for (; *val != '\0'; val++) {
26 switch (*val) {
27 case '"': ret += sizeof(""") - 1; break;
28 case '&': ret += sizeof("&") - 1; break;
29 case '<': ret += sizeof("<") - 1; break;
30 case '>': ret += sizeof(">") - 1; break;
31 default: ++ret; break;
32 }
33 }
34 return ret;
35 }
37 /** Writes \a src (including the NUL byte) to \a dest, doing XML quoting as necessary.
38 *
39 * \pre \a src != NULL.
40 * \pre \a dest must have enough space for (xml_quoted_strlen(src) + 1) bytes.
41 */
42 static void
43 xml_quote(char *dest, char const *src)
44 {
45 #define COPY_LIT(_lit) do { \
46 size_t cpylen = sizeof(_lit "") - 1; \
47 memcpy(dest, _lit, cpylen); \
48 dest += cpylen; \
49 } while(0)
51 for (; *src != '\0'; ++src) {
52 switch (*src) {
53 case '"': COPY_LIT("""); break;
54 case '&': COPY_LIT("&"); break;
55 case '<': COPY_LIT("<"); break;
56 case '>': COPY_LIT(">"); break;
57 default: *dest++ = *src; break;
58 }
59 }
60 *dest = '\0';
62 #undef COPY_LIT
63 }
65 /** \return A g_malloc'd buffer containing an XML-quoted version of \a src.
66 * \pre src != NULL.
67 */
68 char *
69 xml_quote_strdup(char const *src)
70 {
71 size_t const quoted_size = xml_quoted_strlen(src) + 1;
72 char *ret = (char *) g_malloc(quoted_size);
73 xml_quote(ret, src);
74 return ret;
75 }
77 /*
78 Local Variables:
79 mode:c++
80 c-file-style:"stroustrup"
81 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
82 indent-tabs-mode:nil
83 fill-column:99
84 End:
85 */
86 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :