00001 /**
00002 * @copyright
00003 * ====================================================================
00004 * Copyright (c) 2000-2004 CollabNet. All rights reserved.
00005 *
00006 * This software is licensed as described in the file COPYING, which
00007 * you should have received as part of this distribution. The terms
00008 * are also available at http://subversion.tigris.org/license-1.html.
00009 * If newer versions of this license are posted there, you may use a
00010 * newer version instead, at your option.
00011 *
00012 * This software consists of voluntary contributions made by many
00013 * individuals. For exact contribution history, see the revision
00014 * history and logs, available at http://subversion.tigris.org/.
00015 * ====================================================================
00016 * @endcopyright
00017 *
00018 * @file svn_xml.h
00019 * @brief xml code shared by various Subversion libraries.
00020 */
00021
00022
00023
00024 #ifndef SVN_XML_H
00025 #define SVN_XML_H
00026
00027 #include <apr.h>
00028 #include <apr_pools.h>
00029 #include <apr_hash.h>
00030
00031 #include "svn_error.h"
00032 #include "svn_string.h"
00033
00034 #ifdef __cplusplus
00035 extern "C" {
00036 #endif /* __cplusplus */
00037
00038 /** The namespace all Subversion XML uses. */
00039 #define SVN_XML_NAMESPACE "svn:"
00040
00041 /** Used as style argument to @c svn_xml_make_open_tag() and friends. */
00042 enum svn_xml_open_tag_style {
00043 /** <tag ...> */
00044 svn_xml_normal = 1,
00045
00046 /** <tag ...>, no cosmetic newline */
00047 svn_xml_protect_pcdata,
00048
00049 /** <tag .../> */
00050 svn_xml_self_closing
00051 };
00052
00053
00054
00055 /** Determine if a string of character @a data of length @a len is a
00056 * safe bet for use with the svn_xml_escape_* functions found in this
00057 * header.
00058 *
00059 * Return @c TRUE if it is, @c FALSE otherwise.
00060 *
00061 * Essentially, this function exists to determine whether or not
00062 * simply running a string of bytes through the Subversion XML escape
00063 * routines will produce legitimate XML. It should only be necessary
00064 * for data which might contain bytes that cannot be safely encoded
00065 * into XML (upper ASCII and control characters, for example).
00066 */
00067 svn_boolean_t svn_xml_is_xml_safe (const char *data,
00068 apr_size_t len);
00069
00070
00071 /** Create or append in @a *outstr an xml-escaped version of @a string,
00072 * suitable for output as character data.
00073 *
00074 * If @a *outstr is @c NULL, store a new stringbuf, else append to the
00075 * existing stringbuf there.
00076 */
00077 void svn_xml_escape_cdata_stringbuf (svn_stringbuf_t **outstr,
00078 const svn_stringbuf_t *string,
00079 apr_pool_t *pool);
00080
00081 /** Same as @c svn_xml_escape_cdata_stringbuf, but @a string is an
00082 * @c svn_string_t.
00083 */
00084 void svn_xml_escape_cdata_string (svn_stringbuf_t **outstr,
00085 const svn_string_t *string,
00086 apr_pool_t *pool);
00087
00088 /** Same as @c svn_xml_escape_cdata_stringbuf, but @a string is a
00089 * null-terminated C string.
00090 */
00091 void svn_xml_escape_cdata_cstring (svn_stringbuf_t **outstr,
00092 const char *string,
00093 apr_pool_t *pool);
00094
00095
00096 /** Create or append in @a *outstr an xml-escaped version of @a string,
00097 * suitable for output as an attribute value.
00098 *
00099 * If @a *outstr is @c NULL, store a new stringbuf, else append to the
00100 * existing stringbuf there.
00101 */
00102 void svn_xml_escape_attr_stringbuf (svn_stringbuf_t **outstr,
00103 const svn_stringbuf_t *string,
00104 apr_pool_t *pool);
00105
00106 /** Same as @c svn_xml_escape_attr_stringbuf, but @a string is an
00107 * @c svn_string_t.
00108 */
00109 void svn_xml_escape_attr_string (svn_stringbuf_t **outstr,
00110 const svn_string_t *string,
00111 apr_pool_t *pool);
00112
00113 /** Same as @c svn_xml_escape_attr_stringbuf, but @a string is a
00114 * null-terminated C string.
00115 */
00116 void svn_xml_escape_attr_cstring (svn_stringbuf_t **outstr,
00117 const char *string,
00118 apr_pool_t *pool);
00119
00120
00121 /*---------------------------------------------------------------*/
00122
00123 /* Generalized Subversion XML Parsing */
00124
00125 /** A generalized Subversion XML parser object */
00126 typedef struct svn_xml_parser_t svn_xml_parser_t;
00127
00128 typedef void (*svn_xml_start_elem)(void *baton,
00129 const char *name,
00130 const char **atts);
00131
00132 typedef void (*svn_xml_end_elem)(void *baton, const char *name);
00133
00134 /* data is not NULL-terminated. */
00135 typedef void (*svn_xml_char_data)(void *baton,
00136 const char *data,
00137 apr_size_t len);
00138
00139
00140 /** Create a general Subversion XML parser */
00141 svn_xml_parser_t *svn_xml_make_parser (void *baton,
00142 svn_xml_start_elem start_handler,
00143 svn_xml_end_elem end_handler,
00144 svn_xml_char_data data_handler,
00145 apr_pool_t *pool);
00146
00147
00148 /** Free a general Subversion XML parser */
00149 void svn_xml_free_parser (svn_xml_parser_t *svn_parser);
00150
00151
00152 /** Push @a len bytes of xml data in @a buf at @a svn_parser.
00153 *
00154 * If this is the final push, @a is_final must be set.
00155 *
00156 * An error will be returned if there was a syntax problem in the XML,
00157 * or if any of the callbacks set an error using
00158 * @c svn_xml_signal_bailout().
00159 *
00160 * If an error is returned, the @c svn_xml_parser_t will have been freed
00161 * automatically, so the caller should not call @c svn_xml_free_parser().
00162 */
00163 svn_error_t *svn_xml_parse (svn_xml_parser_t *parser,
00164 const char *buf,
00165 apr_size_t len,
00166 svn_boolean_t is_final);
00167
00168
00169
00170 /** The way to officially bail out of xml parsing.
00171 *
00172 * Store @a error in @a svn_parser and set all expat callbacks to @c NULL.
00173 */
00174 void svn_xml_signal_bailout (svn_error_t *error,
00175 svn_xml_parser_t *svn_parser);
00176
00177
00178
00179
00180
00181 /*** Helpers for dealing with the data Expat gives us. ***/
00182
00183 /** Return the value associated with @a name in expat attribute array @a atts,
00184 * else return @c NULL.
00185 *
00186 * (There could never be a @c NULL attribute value in the XML,
00187 * although the empty string is possible.)
00188 *
00189 * @a atts is an array of c-strings: even-numbered indexes are names,
00190 * odd-numbers hold values. If all is right, it should end on an
00191 * even-numbered index pointing to @c NULL.
00192 */
00193 const char *svn_xml_get_attr_value (const char *name, const char **atts);
00194
00195
00196
00197 /* Converting between Expat attribute lists and APR hash tables. */
00198
00199
00200 /** Create an attribute hash from @c va_list @a ap.
00201 *
00202 * The contents of @a ap are alternating <tt>char *</tt> keys and
00203 * <tt>char *</tt> vals, terminated by a final @c NULL falling on an
00204 * odd index (zero-based).
00205 */
00206 apr_hash_t *svn_xml_ap_to_hash (va_list ap, apr_pool_t *pool);
00207
00208 /** Create a hash that corresponds to Expat xml attribute list @a atts.
00209 *
00210 * The hash's keys and values are <tt>char *</tt>'s.
00211 *
00212 * @a atts may be null, in which case you just get an empty hash back
00213 * (this makes life more convenient for some callers).
00214 */
00215 apr_hash_t *svn_xml_make_att_hash (const char **atts, apr_pool_t *pool);
00216
00217
00218 /** Like @c svn_xml_make_att_hash(), but takes a hash and preserves any
00219 * key/value pairs already in it.
00220 */
00221 void svn_xml_hash_atts_preserving (const char **atts,
00222 apr_hash_t *ht,
00223 apr_pool_t *pool);
00224
00225 /** Like @c svn_xml_make_att_hash(), but takes a hash and overwrites
00226 * key/value pairs already in it that also appear in @a atts.
00227 */
00228 void svn_xml_hash_atts_overlaying (const char **atts,
00229 apr_hash_t *ht,
00230 apr_pool_t *pool);
00231
00232
00233
00234 /* Printing XML */
00235
00236 /** Create an XML header and return it in @a *str.
00237 *
00238 * Fully-formed XML documents should start out with a header,
00239 * something like
00240 * <?xml version="1.0" encoding="utf-8"?>
00241 *
00242 * This function returns such a header. @a *str must either be @c NULL, in
00243 * which case a new string is created, or it must point to an existing
00244 * string to be appended to.
00245 */
00246 void svn_xml_make_header (svn_stringbuf_t **str, apr_pool_t *pool);
00247
00248
00249 /** Store a new xml tag @a tagname in @a *str.
00250 *
00251 * If @a str is @c NULL, allocate @a *str in @a pool; else append the new
00252 * tag to @a *str, allocating in @a str's pool
00253 *
00254 * Take the tag's attributes from varargs, a null-terminated list of
00255 * alternating <tt>char *</tt> key and <tt>char *</tt> val. Do xml-escaping
00256 * on each val.
00257 *
00258 * @a style is one of the enumerated styles in @c svn_xml_open_tag_style.
00259 */
00260 void svn_xml_make_open_tag (svn_stringbuf_t **str,
00261 apr_pool_t *pool,
00262 enum svn_xml_open_tag_style style,
00263 const char *tagname,
00264 ...);
00265
00266
00267 /** Like @c svn_xml_make_open_tag, but takes a @c va_list instead of being
00268 * variadic.
00269 */
00270 void svn_xml_make_open_tag_v (svn_stringbuf_t **str,
00271 apr_pool_t *pool,
00272 enum svn_xml_open_tag_style style,
00273 const char *tagname,
00274 va_list ap);
00275
00276
00277 /** Like @c svn_xml_make_tag, but takes a hash table of attributes
00278 * (<tt>char *</tt> keys mapping to <tt>char *</tt> values).
00279 *
00280 * You might ask, why not just provide @c svn_xml_make_tag_atts()?
00281 *
00282 * The reason is that a hash table is the most natural interface to an
00283 * attribute list; the fact that Expat uses <tt>char **</tt> atts instead is
00284 * certainly a defensible implementation decision, but since we'd have
00285 * to have special code to support such lists throughout Subversion
00286 * anyway, we might as well write that code for the natural interface
00287 * (hashes) and then convert in the few cases where conversion is
00288 * needed. Someday it might even be nice to change expat-lite to work
00289 * with apr hashes.
00290 *
00291 * See conversion functions @c svn_xml_make_att_hash() and
00292 * @c svn_xml_make_att_hash_overlaying(). Callers should use those to
00293 * convert Expat attr lists into hashes when necessary.
00294 */
00295 void svn_xml_make_open_tag_hash (svn_stringbuf_t **str,
00296 apr_pool_t *pool,
00297 enum svn_xml_open_tag_style style,
00298 const char *tagname,
00299 apr_hash_t *attributes);
00300
00301
00302 /** Makes a close tag. */
00303 void svn_xml_make_close_tag (svn_stringbuf_t **str,
00304 apr_pool_t *pool,
00305 const char *tagname);
00306
00307
00308
00309 #ifdef __cplusplus
00310 }
00311 #endif /* __cplusplus */
00312
00313 #endif /* SVN_XML_H */
1.2.14 written by Dimitri van Heesch,
© 1997-2002