summaryrefslogtreecommitdiffstats
path: root/src/xml/quote.cpp
blob: 030a6c764f3f8fb147bdc24691e6d4452da72a4a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
/** \file
 * XML quoting routines.
 */

/* Based on Lauris' repr_quote_write in repr-io.cpp.
 *
 * Copyright (C) 1999-2002 Lauris Kaplinski
 * Copyright (C) 2004 Monash University
 *
 * May be modified and/or redistributed under the terms of version 2
 * of the GNU General Public License: see the file `COPYING'.
 */

#include <cstring>
#include <glib.h>
#include "quote.h"


/** \return strlen(xml_quote_strdup(\a val)) (without doing the malloc).
 *  \pre val != NULL
 */
static size_t
xml_quoted_strlen(char const *val)
{
    size_t ret = 0;
    for (; *val != '\0'; val++) {
        switch (*val) {
            case '"': ret += sizeof("&quot;") - 1; break;
            case '&': ret += sizeof("&amp;") - 1; break;
            case '<': ret += sizeof("&lt;") - 1; break;
            case '>': ret += sizeof("&gt;") - 1; break;
            default: ++ret; break;
        }
    }
    return ret;
}

/** Writes \a src (including the NUL byte) to \a dest, doing XML quoting as necessary.
 *
 *  \pre \a src != NULL.
 *  \pre \a dest must have enough space for (xml_quoted_strlen(src) + 1) bytes.
 */
static void
xml_quote(char *dest, char const *src)
{
#define COPY_LIT(_lit) do {	\
	    size_t cpylen = sizeof(_lit "") - 1; \
	    memcpy(dest, _lit, cpylen);	      \
	    dest += cpylen;	              \
	} while(0)

    for (; *src != '\0'; ++src) {
        switch (*src) {
            case '"': COPY_LIT("&quot;"); break;
            case '&': COPY_LIT("&amp;"); break;
            case '<': COPY_LIT("&lt;"); break;
            case '>': COPY_LIT("&gt;"); break;
            default: *dest++ = *src; break;
        }
    }
    *dest = '\0';

#undef COPY_LIT
}

/** \return A g_malloc'd buffer containing an XML-quoted version of \a src.
 *  \pre src != NULL.
 */
char *
xml_quote_strdup(char const *src)
{
    size_t const quoted_size = xml_quoted_strlen(src) + 1;
    char *ret = (char *) g_malloc(quoted_size);
    xml_quote(ret, src);
    return ret;
}

/*
  Local Variables:
  mode:c++
  c-file-style:"stroustrup"
  c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
  indent-tabs-mode:nil
  fill-column:99
  End:
*/
// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :