3 * ====================================================================
4 * Licensed to the Apache Software Foundation (ASF) under one
5 * or more contributor license agreements. See the NOTICE file
6 * distributed with this work for additional information
7 * regarding copyright ownership. The ASF licenses this file
8 * to you under the Apache License, Version 2.0 (the
9 * "License"); you may not use this file except in compliance
10 * with the License. You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing,
15 * software distributed under the License is distributed on an
16 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17 * KIND, either express or implied. See the License for the
18 * specific language governing permissions and limitations
20 * ====================================================================
24 * @brief XML code shared by various Subversion libraries.
31 #include <apr_pools.h>
34 #include "svn_types.h"
35 #include "svn_string.h"
39 #endif /* __cplusplus */
41 /** The namespace all Subversion XML uses. */
42 #define SVN_XML_NAMESPACE "svn:"
44 /** Used as style argument to svn_xml_make_open_tag() and friends. */
45 enum svn_xml_open_tag_style {
49 /** <tag ...>, no cosmetic newline */
50 svn_xml_protect_pcdata,
58 /** Determine if a string of character @a data of length @a len is a
59 * safe bet for use with the svn_xml_escape_* functions found in this
62 * Return @c TRUE if it is, @c FALSE otherwise.
64 * Essentially, this function exists to determine whether or not
65 * simply running a string of bytes through the Subversion XML escape
66 * routines will produce legitimate XML. It should only be necessary
67 * for data which might contain bytes that cannot be safely encoded
68 * into XML (certain control characters, for example).
71 svn_xml_is_xml_safe(const char *data,
74 /** Create or append in @a *outstr an xml-escaped version of @a string,
75 * suitable for output as character data.
77 * If @a *outstr is @c NULL, set @a *outstr to a new stringbuf allocated
78 * in @a pool, else append to the existing stringbuf there.
81 svn_xml_escape_cdata_stringbuf(svn_stringbuf_t **outstr,
82 const svn_stringbuf_t *string,
85 /** Same as svn_xml_escape_cdata_stringbuf(), but @a string is an
89 svn_xml_escape_cdata_string(svn_stringbuf_t **outstr,
90 const svn_string_t *string,
93 /** Same as svn_xml_escape_cdata_stringbuf(), but @a string is a
94 * NULL-terminated C string.
97 svn_xml_escape_cdata_cstring(svn_stringbuf_t **outstr,
102 /** Create or append in @a *outstr an xml-escaped version of @a string,
103 * suitable for output as an attribute value.
105 * If @a *outstr is @c NULL, set @a *outstr to a new stringbuf allocated
106 * in @a pool, else append to the existing stringbuf there.
109 svn_xml_escape_attr_stringbuf(svn_stringbuf_t **outstr,
110 const svn_stringbuf_t *string,
113 /** Same as svn_xml_escape_attr_stringbuf(), but @a string is an
117 svn_xml_escape_attr_string(svn_stringbuf_t **outstr,
118 const svn_string_t *string,
121 /** Same as svn_xml_escape_attr_stringbuf(), but @a string is a
122 * NULL-terminated C string.
125 svn_xml_escape_attr_cstring(svn_stringbuf_t **outstr,
130 * Return UTF-8 string @a string if it contains no characters that are
131 * unrepresentable in XML. Else, return a copy of @a string,
132 * allocated in @a pool, with each unrepresentable character replaced
133 * by "?\uuu", where "uuu" is the three-digit unsigned decimal value
136 * Neither the input nor the output need be valid XML; however, the
137 * output can always be safely XML-escaped.
139 * @note The current implementation treats all Unicode characters as
140 * representable, except for most ASCII control characters (the
141 * exceptions being CR, LF, and TAB, which are valid in XML). There
142 * may be other UTF-8 characters that are invalid in XML; see
143 * http://subversion.tigris.org/servlets/ReadMsg?list=dev&msgNo=90591
144 * and its thread for details.
149 svn_xml_fuzzy_escape(const char *string,
153 /*---------------------------------------------------------------*/
155 /* Generalized Subversion XML Parsing */
157 /** A generalized Subversion XML parser object */
158 typedef struct svn_xml_parser_t svn_xml_parser_t;
160 typedef void (*svn_xml_start_elem)(void *baton,
164 typedef void (*svn_xml_end_elem)(void *baton, const char *name);
166 /* data is not NULL-terminated. */
167 typedef void (*svn_xml_char_data)(void *baton,
172 /** Create a general Subversion XML parser */
174 svn_xml_make_parser(void *baton,
175 svn_xml_start_elem start_handler,
176 svn_xml_end_elem end_handler,
177 svn_xml_char_data data_handler,
181 /** Free a general Subversion XML parser */
183 svn_xml_free_parser(svn_xml_parser_t *svn_parser);
186 /** Push @a len bytes of xml data in @a buf at @a svn_parser.
188 * If this is the final push, @a is_final must be set.
190 * An error will be returned if there was a syntax problem in the XML,
191 * or if any of the callbacks set an error using
192 * svn_xml_signal_bailout().
194 * If an error is returned, the @c svn_xml_parser_t will have been freed
195 * automatically, so the caller should not call svn_xml_free_parser().
198 svn_xml_parse(svn_xml_parser_t *svn_parser,
201 svn_boolean_t is_final);
205 /** The way to officially bail out of xml parsing.
207 * Store @a error in @a svn_parser and set all expat callbacks to @c NULL.
210 svn_xml_signal_bailout(svn_error_t *error,
211 svn_xml_parser_t *svn_parser);
217 /*** Helpers for dealing with the data Expat gives us. ***/
219 /** Return the value associated with @a name in expat attribute array @a atts,
220 * else return @c NULL.
222 * (There could never be a @c NULL attribute value in the XML,
223 * although the empty string is possible.)
225 * @a atts is an array of c-strings: even-numbered indexes are names,
226 * odd-numbers hold values. If all is right, it should end on an
227 * even-numbered index pointing to @c NULL.
230 svn_xml_get_attr_value(const char *name,
231 const char *const *atts);
235 /* Converting between Expat attribute lists and APR hash tables. */
238 /** Create an attribute hash from @c va_list @a ap.
240 * The contents of @a ap are alternating <tt>char *</tt> keys and
241 * <tt>char *</tt> vals, terminated by a final @c NULL falling on an
242 * even index (zero-based).
245 svn_xml_ap_to_hash(va_list ap,
248 /** Create a hash that corresponds to Expat xml attribute list @a atts.
250 * The hash's keys and values are <tt>char *</tt>'s.
252 * @a atts may be NULL, in which case you just get an empty hash back
253 * (this makes life more convenient for some callers).
256 svn_xml_make_att_hash(const char **atts,
260 /** Like svn_xml_make_att_hash(), but takes a hash and preserves any
261 * key/value pairs already in it.
264 svn_xml_hash_atts_preserving(const char **atts,
268 /** Like svn_xml_make_att_hash(), but takes a hash and overwrites
269 * key/value pairs already in it that also appear in @a atts.
272 svn_xml_hash_atts_overlaying(const char **atts,
280 /** Create an XML header and return it in @a *str.
282 * Fully-formed XML documents should start out with a header,
283 * something like <pre>
284 * \<?xml version="1.0" encoding="UTF-8"?\>
287 * This function returns such a header. @a *str must either be @c NULL, in
288 * which case a new string is created, or it must point to an existing
289 * string to be appended to. @a encoding must either be NULL, in which case
290 * encoding information is omitted from the header, or must be the name of
291 * the encoding of the XML document, such as "UTF-8".
296 svn_xml_make_header2(svn_stringbuf_t **str,
297 const char *encoding,
300 /** Like svn_xml_make_header2(), but does not emit encoding information.
302 * @deprecated Provided for backward compatibility with the 1.6 API.
306 svn_xml_make_header(svn_stringbuf_t **str,
310 /** Store a new xml tag @a tagname in @a *str.
312 * If @a *str is @c NULL, set @a *str to a new stringbuf allocated
313 * in @a pool, else append to the existing stringbuf there.
315 * Take the tag's attributes from varargs, a NULL-terminated list of
316 * alternating <tt>char *</tt> key and <tt>char *</tt> val. Do xml-escaping
319 * @a style is one of the enumerated styles in @c svn_xml_open_tag_style.
322 svn_xml_make_open_tag(svn_stringbuf_t **str,
324 enum svn_xml_open_tag_style style,
329 /** Like svn_xml_make_open_tag(), but takes a @c va_list instead of being
333 svn_xml_make_open_tag_v(svn_stringbuf_t **str,
335 enum svn_xml_open_tag_style style,
340 /** Like svn_xml_make_open_tag(), but takes a hash table of attributes
341 * (<tt>char *</tt> keys mapping to <tt>char *</tt> values).
343 * You might ask, why not just provide svn_xml_make_tag_atts()?
345 * The reason is that a hash table is the most natural interface to an
346 * attribute list; the fact that Expat uses <tt>char **</tt> atts instead is
347 * certainly a defensible implementation decision, but since we'd have
348 * to have special code to support such lists throughout Subversion
349 * anyway, we might as well write that code for the natural interface
350 * (hashes) and then convert in the few cases where conversion is
351 * needed. Someday it might even be nice to change expat-lite to work
354 * See conversion functions svn_xml_make_att_hash() and
355 * svn_xml_make_att_hash_overlaying(). Callers should use those to
356 * convert Expat attr lists into hashes when necessary.
359 svn_xml_make_open_tag_hash(svn_stringbuf_t **str,
361 enum svn_xml_open_tag_style style,
363 apr_hash_t *attributes);
366 /** Store an xml close tag @a tagname in @a str.
368 * If @a *str is @c NULL, set @a *str to a new stringbuf allocated
369 * in @a pool, else append to the existing stringbuf there.
372 svn_xml_make_close_tag(svn_stringbuf_t **str,
374 const char *tagname);
379 #endif /* __cplusplus */
381 #endif /* SVN_XML_H */