]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - contrib/subversion/subversion/include/svn_xml.h
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / contrib / subversion / subversion / include / svn_xml.h
1 /**
2  * @copyright
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
11  *
12  *      http://www.apache.org/licenses/LICENSE-2.0
13  *
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
19  *    under the License.
20  * ====================================================================
21  * @endcopyright
22  *
23  * @file svn_xml.h
24  * @brief XML code shared by various Subversion libraries.
25  */
26
27 #ifndef SVN_XML_H
28 #define SVN_XML_H
29
30 #include <apr.h>
31 #include <apr_pools.h>
32 #include <apr_hash.h>
33
34 #include "svn_types.h"
35 #include "svn_string.h"
36
37 #ifdef __cplusplus
38 extern "C" {
39 #endif /* __cplusplus */
40
41 /** The namespace all Subversion XML uses. */
42 #define SVN_XML_NAMESPACE "svn:"
43
44 /** Used as style argument to svn_xml_make_open_tag() and friends. */
45 enum svn_xml_open_tag_style {
46   /** <tag ...> */
47   svn_xml_normal = 1,
48
49   /** <tag ...>, no cosmetic newline */
50   svn_xml_protect_pcdata,
51
52   /** <tag .../>  */
53   svn_xml_self_closing
54 };
55
56 \f
57
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
60  * header.
61  *
62  * Return @c TRUE if it is, @c FALSE otherwise.
63  *
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).
69  */
70 svn_boolean_t
71 svn_xml_is_xml_safe(const char *data,
72                     apr_size_t len);
73
74 /** Create or append in @a *outstr an xml-escaped version of @a string,
75  * suitable for output as character data.
76  *
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.
79  */
80 void
81 svn_xml_escape_cdata_stringbuf(svn_stringbuf_t **outstr,
82                                const svn_stringbuf_t *string,
83                                apr_pool_t *pool);
84
85 /** Same as svn_xml_escape_cdata_stringbuf(), but @a string is an
86  * @c svn_string_t.
87  */
88 void
89 svn_xml_escape_cdata_string(svn_stringbuf_t **outstr,
90                             const svn_string_t *string,
91                             apr_pool_t *pool);
92
93 /** Same as svn_xml_escape_cdata_stringbuf(), but @a string is a
94  * NULL-terminated C string.
95  */
96 void
97 svn_xml_escape_cdata_cstring(svn_stringbuf_t **outstr,
98                              const char *string,
99                              apr_pool_t *pool);
100
101
102 /** Create or append in @a *outstr an xml-escaped version of @a string,
103  * suitable for output as an attribute value.
104  *
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.
107  */
108 void
109 svn_xml_escape_attr_stringbuf(svn_stringbuf_t **outstr,
110                               const svn_stringbuf_t *string,
111                               apr_pool_t *pool);
112
113 /** Same as svn_xml_escape_attr_stringbuf(), but @a string is an
114  * @c svn_string_t.
115  */
116 void
117 svn_xml_escape_attr_string(svn_stringbuf_t **outstr,
118                            const svn_string_t *string,
119                            apr_pool_t *pool);
120
121 /** Same as svn_xml_escape_attr_stringbuf(), but @a string is a
122  * NULL-terminated C string.
123  */
124 void
125 svn_xml_escape_attr_cstring(svn_stringbuf_t **outstr,
126                             const char *string,
127                             apr_pool_t *pool);
128
129 /**
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
134  * of that character.
135  *
136  * Neither the input nor the output need be valid XML; however, the
137  * output can always be safely XML-escaped.
138  *
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.
145  *
146  * @since New in 1.2.
147  */
148 const char *
149 svn_xml_fuzzy_escape(const char *string,
150                      apr_pool_t *pool);
151
152
153 /*---------------------------------------------------------------*/
154 \f
155 /* Generalized Subversion XML Parsing */
156
157 /** A generalized Subversion XML parser object */
158 typedef struct svn_xml_parser_t svn_xml_parser_t;
159
160 typedef void (*svn_xml_start_elem)(void *baton,
161                                    const char *name,
162                                    const char **atts);
163
164 typedef void (*svn_xml_end_elem)(void *baton, const char *name);
165
166 /* data is not NULL-terminated. */
167 typedef void (*svn_xml_char_data)(void *baton,
168                                   const char *data,
169                                   apr_size_t len);
170
171
172 /** Create a general Subversion XML parser */
173 svn_xml_parser_t *
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,
178                     apr_pool_t *pool);
179
180
181 /** Free a general Subversion XML parser */
182 void
183 svn_xml_free_parser(svn_xml_parser_t *svn_parser);
184
185
186 /** Push @a len bytes of xml data in @a buf at @a svn_parser.
187  *
188  * If this is the final push, @a is_final must be set.
189  *
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().
193  *
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().
196  */
197 svn_error_t *
198 svn_xml_parse(svn_xml_parser_t *svn_parser,
199               const char *buf,
200               apr_size_t len,
201               svn_boolean_t is_final);
202
203
204
205 /** The way to officially bail out of xml parsing.
206  *
207  * Store @a error in @a svn_parser and set all expat callbacks to @c NULL.
208  */
209 void
210 svn_xml_signal_bailout(svn_error_t *error,
211                        svn_xml_parser_t *svn_parser);
212
213
214
215
216 \f
217 /*** Helpers for dealing with the data Expat gives us. ***/
218
219 /** Return the value associated with @a name in expat attribute array @a atts,
220  * else return @c NULL.
221  *
222  * (There could never be a @c NULL attribute value in the XML,
223  * although the empty string is possible.)
224  *
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.
228  */
229 const char *
230 svn_xml_get_attr_value(const char *name,
231                        const char *const *atts);
232
233
234 \f
235 /* Converting between Expat attribute lists and APR hash tables. */
236
237
238 /** Create an attribute hash from @c va_list @a ap.
239  *
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).
243  */
244 apr_hash_t *
245 svn_xml_ap_to_hash(va_list ap,
246                    apr_pool_t *pool);
247
248 /** Create a hash that corresponds to Expat xml attribute list @a atts.
249  *
250  * The hash's keys and values are <tt>char *</tt>'s.
251  *
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).
254  */
255 apr_hash_t *
256 svn_xml_make_att_hash(const char **atts,
257                       apr_pool_t *pool);
258
259
260 /** Like svn_xml_make_att_hash(), but takes a hash and preserves any
261  * key/value pairs already in it.
262  */
263 void
264 svn_xml_hash_atts_preserving(const char **atts,
265                              apr_hash_t *ht,
266                              apr_pool_t *pool);
267
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.
270  */
271 void
272 svn_xml_hash_atts_overlaying(const char **atts,
273                              apr_hash_t *ht,
274                              apr_pool_t *pool);
275
276
277 \f
278 /* Printing XML */
279
280 /** Create an XML header and return it in @a *str.
281  *
282  * Fully-formed XML documents should start out with a header,
283  * something like <pre>
284  *         \<?xml version="1.0" encoding="UTF-8"?\>
285  * </pre>
286  *
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".
292  *
293  * @since New in 1.7.
294  */
295 void
296 svn_xml_make_header2(svn_stringbuf_t **str,
297                      const char *encoding,
298                      apr_pool_t *pool);
299
300 /** Like svn_xml_make_header2(), but does not emit encoding information.
301  *
302  * @deprecated Provided for backward compatibility with the 1.6 API.
303  */
304 SVN_DEPRECATED
305 void
306 svn_xml_make_header(svn_stringbuf_t **str,
307                     apr_pool_t *pool);
308
309
310 /** Store a new xml tag @a tagname in @a *str.
311  *
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.
314  *
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
317  * on each val.
318  *
319  * @a style is one of the enumerated styles in @c svn_xml_open_tag_style.
320  */
321 void
322 svn_xml_make_open_tag(svn_stringbuf_t **str,
323                       apr_pool_t *pool,
324                       enum svn_xml_open_tag_style style,
325                       const char *tagname,
326                       ...);
327
328
329 /** Like svn_xml_make_open_tag(), but takes a @c va_list instead of being
330  * variadic.
331  */
332 void
333 svn_xml_make_open_tag_v(svn_stringbuf_t **str,
334                         apr_pool_t *pool,
335                         enum svn_xml_open_tag_style style,
336                         const char *tagname,
337                         va_list ap);
338
339
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).
342  *
343  * You might ask, why not just provide svn_xml_make_tag_atts()?
344  *
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
352  * with apr hashes.
353  *
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.
357  */
358 void
359 svn_xml_make_open_tag_hash(svn_stringbuf_t **str,
360                            apr_pool_t *pool,
361                            enum svn_xml_open_tag_style style,
362                            const char *tagname,
363                            apr_hash_t *attributes);
364
365
366 /** Store an xml close tag @a tagname in @a str.
367  *
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.
370  */
371 void
372 svn_xml_make_close_tag(svn_stringbuf_t **str,
373                        apr_pool_t *pool,
374                        const char *tagname);
375
376
377 #ifdef __cplusplus
378 }
379 #endif /* __cplusplus */
380
381 #endif /* SVN_XML_H */