source: trunk/src/core/RpEntityRef.cc @ 829

Last change on this file since 829 was 788, checked in by dkearney, 17 years ago

adjustments to entity references encoding to include the length of the string to encode and decode.
this is used for the python bindings, so we can know the length of the string being returned and allow embedded nulls.

File size: 4.1 KB
Line 
1/*
2 * ----------------------------------------------------------------------
3 *  Rappture Library Entity Reference Translation Header
4 *
5 *  Begin Character Entity Translator
6 *
7 *  The next section of code implements routines used to translate
8 *  character entity references into their corresponding strings.
9 *
10 *  Examples:
11 *
12 *        &          "&"
13 *        &lt;           "<"
14 *        &gt;           ">"
15 *        &nbsp;         " "
16 *
17 *
18 * ======================================================================
19 *  AUTHOR:  Derrick Kearney, Purdue University
20 *  Copyright (c) 2004-2006  Purdue Research Foundation
21 *
22 *  See the file "license.terms" for information on usage and
23 *  redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
24 *
25 *  Also see below text for additional information on usage and redistribution
26 *
27 * ======================================================================
28 */
29
30#include "RpEntityRef.h"
31#include <cctype>
32#include <cstring>
33
34#ifdef __cplusplus
35    extern "C" {
36#endif // ifdef __cplusplus
37
38using namespace Rappture;
39
40const char*
41EntityRef::decode (
42    const char* value,
43    unsigned int len
44)
45{
46    unsigned int pos = 0;
47
48    if (value == NULL) {
49        // empty string, noting to do
50        return NULL;
51    }
52
53    _bout.clear();
54    if (len == 0) {
55        len = strlen(value);
56    }
57
58    while (pos < len) {
59        if (value[pos] == '&') {
60            pos++;
61            if ((pos < len)) {
62                if (value[pos] && isalpha(value[pos])) {
63                    if (        (value[pos] == 'q')
64                            &&  (strncmp("quot;",value+pos,5) == 0) ) {
65                        _bout.append("\"");
66                        pos += 5;
67                    }
68                    else if (   (value[pos] == 'a')
69                            &&  (strncmp("amp;",value+pos,4) == 0) ) {
70                        _bout.append("&");
71                        pos += 4;
72                    }
73                    else if (   (value[pos] == 'l')
74                            &&  (strncmp("lt;",value+pos,3) == 0) ) {
75                        _bout.append("<");
76                        pos += 3;
77                    }
78                    else if (   (value[pos] == 'g')
79                            &&  (strncmp("gt;",value+pos,3) == 0) ) {
80                        _bout.append(">");
81                        pos += 3;
82                    }
83                    else {
84                        // unrecognized
85                        _bout.append(value+pos,1);
86                        pos++;
87                    }
88                }
89                else {
90                    _bout.append(value+pos,1);
91                    pos++;
92                }
93            }
94            else {
95                // last character was really an ampersand
96                // add it to the buffer
97                pos--;
98                _bout.append(value+pos,1);
99                pos++;
100            }
101        }
102        else
103        {
104            // non entity ref character
105            _bout.append(value+pos,1);
106            pos++;
107        }
108    }
109
110    _bout.append("\0",1);
111    return _bout.bytes();
112}
113
114const char*
115EntityRef::encode (
116    const char* value,
117    unsigned int len
118)
119{
120    unsigned int pos = 0;
121
122
123    if (value == NULL) {
124        // empty string, noting to do
125        return NULL;
126    }
127
128    _bout.clear();
129    if (len == 0) {
130        len = strlen(value);
131    }
132
133    while (pos < len) {
134        if (*(value+pos) == '"') {
135            _bout.append("&quot;");
136        }
137        else if (*(value+pos) == '&') {
138            _bout.append("&amp;");
139        }
140        else if (*(value+pos) == '<') {
141            _bout.append("&lt;");
142        }
143        else if (*(value+pos) == '>') {
144            _bout.append("&gt;");
145        }
146        /*
147        else if (*(value+pos) == '\n') {
148            _bout.append("&#xA;");
149        }
150        */
151        else
152        {
153            _bout.append(value+pos,1);
154        }
155        pos++;
156    }
157
158    _bout.append("\0",1);
159    return _bout.bytes();
160}
161
162int
163EntityRef::size () {
164    return _bout.size();
165}
166
167
168#ifdef __cplusplus
169    } // extern c
170#endif // ifdef __cplusplus
Note: See TracBrowser for help on using the repository browser.