1 /* ====================================================================
2 * The Apache Software License, Version 1.1
4 * Copyright (c) 2000 The Apache Software Foundation. All rights
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in
16 * the documentation and/or other materials provided with the
19 * 3. The end-user documentation included with the redistribution,
20 * if any, must include the following acknowledgment:
21 * "This product includes software developed by the
22 * Apache Software Foundation (http://www.apache.org/)."
23 * Alternately, this acknowledgment may appear in the software itself,
24 * if and wherever such third-party acknowledgments normally appear.
26 * 4. The names "Apache" and "Apache Software Foundation" must
27 * not be used to endorse or promote products derived from this
28 * software without prior written permission. For written
29 * permission, please contact apache@apache.org.
31 * 5. Products derived from this software may not be called "Apache",
32 * nor may "Apache" appear in their name, without prior written
33 * permission of the Apache Software Foundation.
35 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
36 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
37 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
38 * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
39 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
41 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
42 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
43 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
44 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
45 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47 * ====================================================================
49 * This software consists of voluntary contributions made by many
50 * individuals on behalf of the Apache Software Foundation. For more
51 * information on the Apache Software Foundation, please see
52 * <http://www.apache.org/>.
66 /* -------------------------------------------------------------------- */
68 /* ### these will need to move at some point to a more logical spot */
70 /* simple strutures to keep a linked list of pieces of text */
71 typedef struct ap_text ap_text;
73 /** Structure to keep a linked list of pieces of text */
75 /** The current piece of text */
77 /** a pointer to the next piece of text
78 * @defvar ap_text *next */
82 typedef struct ap_text_header ap_text_header;
84 /** A list of pieces of text */
85 struct ap_text_header {
86 /** The first piece of text in the list */
88 /** The last piece of text in the list */
93 * Append a piece of text to the end of a list
94 * @param p The pool to allocate out of
95 * @param hdr The text header to append to
96 * @param text The new text to append
97 * @deffunc void ap_text_append(apr_pool_t *p, ap_text_header *hdr, const char *text)
99 API_EXPORT(void) ap_text_append(apr_pool_t *p, ap_text_header *hdr,
103 /* --------------------------------------------------------------------
109 ** Qualified namespace values
112 ** We always insert the "DAV:" namespace URI at the head of the
113 ** namespace array. This means that it will always be at ID==0,
114 ** making it much easier to test for.
117 ** This special ID is used for two situations:
119 ** 1) The namespace prefix begins with "xml" (and we do not know
120 ** what it means). Namespace prefixes with "xml" (any case) as
121 ** their first three characters are reserved by the XML Namespaces
122 ** specification for future use. mod_dav will pass these through
123 ** unchanged. When this identifier is used, the prefix is LEFT in
124 ** the element/attribute name. Downstream processing should not
125 ** prepend another prefix.
127 ** 2) The element/attribute does not have a namespace.
129 ** a) No prefix was used, and a default namespace has not been
131 ** b) No prefix was used, and the default namespace was specified
132 ** to mean "no namespace". This is done with a namespace
133 ** declaration of: xmlns=""
134 ** (this declaration is typically used to override a previous
135 ** specification for the default namespace)
137 ** In these cases, we need to record that the elem/attr has no
138 ** namespace so that we will not attempt to prepend a prefix.
139 ** All namespaces that are used will have a prefix assigned to
140 ** them -- mod_dav will never set or use the default namespace
141 ** when generating XML. This means that "no prefix" will always
142 ** mean "no namespace".
144 ** In both cases, the XML generation will avoid prepending a prefix.
145 ** For the first case, this means the original prefix/name will be
146 ** inserted into the output stream. For the latter case, it means
147 ** the name will have no prefix, and since we never define a default
148 ** namespace, this means it will have no namespace.
150 ** Note: currently, mod_dav understands the "xmlns" prefix and the
151 ** "xml:lang" attribute. These are handled specially (they aren't
152 ** left within the XML tree), so the AP_XML_NS_NONE value won't ever
153 ** really apply to these values.
155 #define AP_XML_NS_DAV_ID 0 /* namespace ID for "DAV:" */
156 #define AP_XML_NS_NONE -10 /* no namespace for this elem/attr */
158 #define AP_XML_NS_ERROR_BASE -100 /* used only during processing */
159 #define AP_XML_NS_IS_ERROR(e) ((e) <= AP_XML_NS_ERROR_BASE)
162 typedef struct ap_xml_attr ap_xml_attr;
163 typedef struct ap_xml_elem ap_xml_elem;
164 typedef struct ap_xml_doc ap_xml_doc;
166 /** ap_xml_attr: holds a parsed XML attribute */
168 /** attribute name */
170 /** index into namespace array */
173 /** attribute value */
177 * @defvar ap_xml_attr *next */
178 struct ap_xml_attr *next;
181 /** ap_xml_elem: holds a parsed XML element */
185 /** index into namespace array */
187 /** xml:lang for attrs/contents */
190 /** cdata right after start tag */
191 ap_text_header first_cdata;
192 /** cdata after MY end tag */
193 ap_text_header following_cdata;
196 * @defvar ap_xml_elem *parent */
197 struct ap_xml_elem *parent;
198 /** next (sibling) element
199 * @defvar ap_xml_elem *next */
200 struct ap_xml_elem *next;
201 /** first child element
202 * @defvar ap_xml_elem *first_child */
203 struct ap_xml_elem *first_child;
205 * @defvar ap_xml_attr *attr */
206 struct ap_xml_attr *attr;
208 /* used only during parsing */
209 /** last child element
210 * @defvar ap_xml_elem *last_child */
211 struct ap_xml_elem *last_child;
212 /** namespaces scoped by this elem
213 * @defvar ap_xml_ns_scope *ns_scope */
214 struct ap_xml_ns_scope *ns_scope;
216 /* used by modules during request processing */
217 /** Place for modules to store private data */
221 #define AP_XML_ELEM_IS_EMPTY(e) ((e)->first_child == NULL && \
222 (e)->first_cdata.first == NULL)
224 /** ap_xml_doc: holds a parsed XML document */
228 /** array of namespaces used */
229 apr_array_header_t *namespaces;
233 * Get XML post data and parse it
234 * @param r The current request
235 * @param pdoc The XML post data
236 * @return HTTP status code
237 * @deffunc int ap_xml_parse_input(request_rec *r, ap_xml_doc **pdoc)
239 API_EXPORT(int) ap_xml_parse_input(request_rec *r, ap_xml_doc **pdoc);
243 * Converts an XML element tree to flat text
244 * @param p The pool to allocate out of
245 * @param elem The XML element to convert
246 * @param style How to covert the XML. One of:
248 * AP_XML_X2T_FULL start tag, contents, end tag
249 * AP_XML_X2T_INNER contents only
250 * AP_XML_X2T_LANG_INNER xml:lang + inner contents
251 * AP_XML_X2T_FULL_NS_LANG FULL + ns defns + xml:lang
253 * @param namespaces The namespace of the current XML element
254 * @param ns_map Namespace mapping
255 * @param pbuf Buffer to put the converted text into
256 * @param psize Size of the converted text
257 * @deffunc void ap_xml_to_text(apr_pool_t *p, const ap_xml_elem *elem, int style, apr_array_header_t *namespaces, int *ns_map, const char **pbuf, size_t *psize);
259 API_EXPORT(void) ap_xml_to_text(apr_pool_t *p, const ap_xml_elem *elem,
260 int style, apr_array_header_t *namespaces,
261 int *ns_map, const char **pbuf, size_t *psize);
263 /* style argument values: */
264 #define AP_XML_X2T_FULL 0 /* start tag, contents, end tag */
265 #define AP_XML_X2T_INNER 1 /* contents only */
266 #define AP_XML_X2T_LANG_INNER 2 /* xml:lang + inner contents */
267 #define AP_XML_X2T_FULL_NS_LANG 3 /* FULL + ns defns + xml:lang */
271 * @param p The pool to allocate out of
272 * @param elem The XML element to empty
273 * @return the string that was stored in the XML element
274 * @deffunc const char *ap_xml_empty_elem(apr_pool_t *p, const ap_xml_elem *elem)
276 API_EXPORT(const char *) ap_xml_empty_elem(apr_pool_t *p,
277 const ap_xml_elem *elem);
280 * quote an XML string
281 * Replace '<', '>', and '&' with '<', '>', and '&'.
282 * @param p The pool to allocate out of
283 * @param s The string to quote
284 * @param quotes If quotes is true, then replace '"' with '"'.
285 * @return The quoted string
286 * @deffunc const char *ap_xml_quote_string(apr_pool_t *p, const char *s, int quotes)
288 API_EXPORT(const char *) ap_xml_quote_string(apr_pool_t *p, const char *s,
292 * Quote an XML element
293 * @param p The pool to allocate out of
294 * @param elem The element to quote
295 * @deffunc void ap_xml_quote_elem(apr_pool_t *p, ap_xml_elem *elem)
297 API_EXPORT(void) ap_xml_quote_elem(apr_pool_t *p, ap_xml_elem *elem);
299 /* manage an array of unique URIs: ap_xml_insert_uri() and AP_XML_URI_ITEM() */
302 * return the URI's (existing) index, or insert it and return a new index
303 * @param uri_array array to insert into
304 * @param uri The uri to insert
305 * @return int The uri's index
306 * @deffunc int ap_xml_insert_uri(apr_array_header_t *uri_array, const char *uri)
308 API_EXPORT(int) ap_xml_insert_uri(apr_array_header_t *uri_array,
310 #define AP_XML_GET_URI_ITEM(ary, i) (((const char * const *)(ary)->elts)[i])
316 #endif /* UTIL_XML_H */