Subversion
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
svn_xml.h
Go to the documentation of this file.
1 /**
2  * @copyright
3  * ====================================================================
4  * Copyright (c) 2000-2006, 2008 CollabNet. All rights reserved.
5  *
6  * This software is licensed as described in the file COPYING, which
7  * you should have received as part of this distribution. The terms
8  * are also available at http://subversion.tigris.org/license-1.html.
9  * If newer versions of this license are posted there, you may use a
10  * newer version instead, at your option.
11  *
12  * This software consists of voluntary contributions made by many
13  * individuals. For exact contribution history, see the revision
14  * history and logs, available at http://subversion.tigris.org/.
15  * ====================================================================
16  * @endcopyright
17  *
18  * @file svn_xml.h
19  * @brief XML code shared by various Subversion libraries.
20  */
21 
22 #ifndef SVN_XML_H
23 #define SVN_XML_H
24 
25 #include <apr.h>
26 #include <apr_pools.h>
27 #include <apr_hash.h>
28 
29 #include "svn_types.h"
30 #include "svn_string.h"
31 
32 #ifdef __cplusplus
33 extern "C" {
34 #endif /* __cplusplus */
35 
36 /** The namespace all Subversion XML uses. */
37 #define SVN_XML_NAMESPACE "svn:"
38 
39 /** Used as style argument to svn_xml_make_open_tag() and friends. */
41  /** <tag ...> */
43 
44  /** <tag ...>, no cosmetic newline */
46 
47  /** <tag .../> */
49 };
50 
51 
52 
53 /** Determine if a string of character @a data of length @a len is a
54  * safe bet for use with the svn_xml_escape_* functions found in this
55  * header.
56  *
57  * Return @c TRUE if it is, @c FALSE otherwise.
58  *
59  * Essentially, this function exists to determine whether or not
60  * simply running a string of bytes through the Subversion XML escape
61  * routines will produce legitimate XML. It should only be necessary
62  * for data which might contain bytes that cannot be safely encoded
63  * into XML (certain control characters, for example).
64  */
66 svn_xml_is_xml_safe(const char *data,
67  apr_size_t len);
68 
69 /** Create or append in @a *outstr an xml-escaped version of @a string,
70  * suitable for output as character data.
71  *
72  * If @a *outstr is @c NULL, set @a *outstr to a new stringbuf allocated
73  * in @a pool, else append to the existing stringbuf there.
74  */
75 void
77  const svn_stringbuf_t *string,
78  apr_pool_t *pool);
79 
80 /** Same as svn_xml_escape_cdata_stringbuf(), but @a string is an
81  * @c svn_string_t.
82  */
83 void
85  const svn_string_t *string,
86  apr_pool_t *pool);
87 
88 /** Same as svn_xml_escape_cdata_stringbuf(), but @a string is a
89  * NULL-terminated C string.
90  */
91 void
93  const char *string,
94  apr_pool_t *pool);
95 
96 
97 /** Create or append in @a *outstr an xml-escaped version of @a string,
98  * suitable for output as an attribute value.
99  *
100  * If @a *outstr is @c NULL, set @a *outstr to a new stringbuf allocated
101  * in @a pool, else append to the existing stringbuf there.
102  */
103 void
105  const svn_stringbuf_t *string,
106  apr_pool_t *pool);
107 
108 /** Same as svn_xml_escape_attr_stringbuf(), but @a string is an
109  * @c svn_string_t.
110  */
111 void
113  const svn_string_t *string,
114  apr_pool_t *pool);
115 
116 /** Same as svn_xml_escape_attr_stringbuf(), but @a string is a
117  * NULL-terminated C string.
118  */
119 void
121  const char *string,
122  apr_pool_t *pool);
123 
124 /**
125  * Return UTF-8 string @a string if it contains no characters that are
126  * unrepresentable in XML. Else, return a copy of @a string,
127  * allocated in @a pool, with each unrepresentable character replaced
128  * by "?\uuu", where "uuu" is the three-digit unsigned decimal value
129  * of that character.
130  *
131  * Neither the input nor the output need be valid XML; however, the
132  * output can always be safely XML-escaped.
133  *
134  * @note The current implementation treats all Unicode characters as
135  * representable, except for most ASCII control characters (the
136  * exceptions being CR, LF, and TAB, which are valid in XML). There
137  * may be other UTF-8 characters that are invalid in XML; see
138  * http://subversion.tigris.org/servlets/ReadMsg?list=dev&msgNo=90591
139  * and its thread for details.
140  *
141  * @since New in 1.2.
142  */
143 const char *
144 svn_xml_fuzzy_escape(const char *string,
145  apr_pool_t *pool);
146 
147 
148 /*---------------------------------------------------------------*/
149 
150 /* Generalized Subversion XML Parsing */
151 
152 /** A generalized Subversion XML parser object */
154 
155 typedef void (*svn_xml_start_elem)(void *baton,
156  const char *name,
157  const char **atts);
158 
159 typedef void (*svn_xml_end_elem)(void *baton, const char *name);
160 
161 /* data is not NULL-terminated. */
162 typedef void (*svn_xml_char_data)(void *baton,
163  const char *data,
164  apr_size_t len);
165 
166 
167 /** Create a general Subversion XML parser */
169 svn_xml_make_parser(void *baton,
170  svn_xml_start_elem start_handler,
171  svn_xml_end_elem end_handler,
172  svn_xml_char_data data_handler,
173  apr_pool_t *pool);
174 
175 
176 /** Free a general Subversion XML parser */
177 void
179 
180 
181 /** Push @a len bytes of xml data in @a buf at @a svn_parser.
182  *
183  * If this is the final push, @a is_final must be set.
184  *
185  * An error will be returned if there was a syntax problem in the XML,
186  * or if any of the callbacks set an error using
187  * svn_xml_signal_bailout().
188  *
189  * If an error is returned, the @c svn_xml_parser_t will have been freed
190  * automatically, so the caller should not call svn_xml_free_parser().
191  */
192 svn_error_t *
193 svn_xml_parse(svn_xml_parser_t *svn_parser,
194  const char *buf,
195  apr_size_t len,
196  svn_boolean_t is_final);
197 
198 
199 
200 /** The way to officially bail out of xml parsing.
201  *
202  * Store @a error in @a svn_parser and set all expat callbacks to @c NULL.
203  */
204 void
206  svn_xml_parser_t *svn_parser);
207 
208 
209 
210 
211 
212 /*** Helpers for dealing with the data Expat gives us. ***/
213 
214 /** Return the value associated with @a name in expat attribute array @a atts,
215  * else return @c NULL.
216  *
217  * (There could never be a @c NULL attribute value in the XML,
218  * although the empty string is possible.)
219  *
220  * @a atts is an array of c-strings: even-numbered indexes are names,
221  * odd-numbers hold values. If all is right, it should end on an
222  * even-numbered index pointing to @c NULL.
223  */
224 const char *
225 svn_xml_get_attr_value(const char *name,
226  const char **atts);
227 
228 
229 
230 /* Converting between Expat attribute lists and APR hash tables. */
231 
232 
233 /** Create an attribute hash from @c va_list @a ap.
234  *
235  * The contents of @a ap are alternating <tt>char *</tt> keys and
236  * <tt>char *</tt> vals, terminated by a final @c NULL falling on an
237  * even index (zero-based).
238  */
239 apr_hash_t *
240 svn_xml_ap_to_hash(va_list ap,
241  apr_pool_t *pool);
242 
243 /** Create a hash that corresponds to Expat xml attribute list @a atts.
244  *
245  * The hash's keys and values are <tt>char *</tt>'s.
246  *
247  * @a atts may be NULL, in which case you just get an empty hash back
248  * (this makes life more convenient for some callers).
249  */
250 apr_hash_t *
251 svn_xml_make_att_hash(const char **atts,
252  apr_pool_t *pool);
253 
254 
255 /** Like svn_xml_make_att_hash(), but takes a hash and preserves any
256  * key/value pairs already in it.
257  */
258 void
259 svn_xml_hash_atts_preserving(const char **atts,
260  apr_hash_t *ht,
261  apr_pool_t *pool);
262 
263 /** Like svn_xml_make_att_hash(), but takes a hash and overwrites
264  * key/value pairs already in it that also appear in @a atts.
265  */
266 void
267 svn_xml_hash_atts_overlaying(const char **atts,
268  apr_hash_t *ht,
269  apr_pool_t *pool);
270 
271 
272 
273 /* Printing XML */
274 
275 /** Create an XML header and return it in @a *str.
276  *
277  * Fully-formed XML documents should start out with a header,
278  * something like
279  * <?xml version="1.0" encoding="utf-8"?>
280  *
281  * This function returns such a header. @a *str must either be @c NULL, in
282  * which case a new string is created, or it must point to an existing
283  * string to be appended to.
284  */
285 void
287  apr_pool_t *pool);
288 
289 
290 /** Store a new xml tag @a tagname in @a *str.
291  *
292  * If @a *str is @c NULL, set @a *str to a new stringbuf allocated
293  * in @a pool, else append to the existing stringbuf there.
294  *
295  * Take the tag's attributes from varargs, a NULL-terminated list of
296  * alternating <tt>char *</tt> key and <tt>char *</tt> val. Do xml-escaping
297  * on each val.
298  *
299  * @a style is one of the enumerated styles in @c svn_xml_open_tag_style.
300  */
301 void
303  apr_pool_t *pool,
304  enum svn_xml_open_tag_style style,
305  const char *tagname,
306  ...);
307 
308 
309 /** Like svn_xml_make_open_tag(), but takes a @c va_list instead of being
310  * variadic.
311  */
312 void
314  apr_pool_t *pool,
315  enum svn_xml_open_tag_style style,
316  const char *tagname,
317  va_list ap);
318 
319 
320 /** Like svn_xml_make_open_tag(), but takes a hash table of attributes
321  * (<tt>char *</tt> keys mapping to <tt>char *</tt> values).
322  *
323  * You might ask, why not just provide svn_xml_make_tag_atts()?
324  *
325  * The reason is that a hash table is the most natural interface to an
326  * attribute list; the fact that Expat uses <tt>char **</tt> atts instead is
327  * certainly a defensible implementation decision, but since we'd have
328  * to have special code to support such lists throughout Subversion
329  * anyway, we might as well write that code for the natural interface
330  * (hashes) and then convert in the few cases where conversion is
331  * needed. Someday it might even be nice to change expat-lite to work
332  * with apr hashes.
333  *
334  * See conversion functions svn_xml_make_att_hash() and
335  * svn_xml_make_att_hash_overlaying(). Callers should use those to
336  * convert Expat attr lists into hashes when necessary.
337  */
338 void
340  apr_pool_t *pool,
341  enum svn_xml_open_tag_style style,
342  const char *tagname,
343  apr_hash_t *attributes);
344 
345 
346 /** Store an xml close tag @a tagname in @a str.
347  *
348  * If @a *str is @c NULL, set @a *str to a new stringbuf allocated
349  * in @a pool, else append to the existing stringbuf there.
350  */
351 void
353  apr_pool_t *pool,
354  const char *tagname);
355 
356 
357 #ifdef __cplusplus
358 }
359 #endif /* __cplusplus */
360 
361 #endif /* SVN_XML_H */