Back to index

avfs  1.0.1
hip_xml.h
Go to the documentation of this file.
00001 /* 
00002    Higher Level Interface to XML Parsers.
00003    Copyright (C) 1999-2001, Joe Orton <joe@light.plus.com>
00004 
00005    This library is free software; you can redistribute it and/or
00006    modify it under the terms of the GNU Library General Public
00007    License as published by the Free Software Foundation; either
00008    version 2 of the License, or (at your option) any later version.
00009    
00010    This library is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013    Library General Public License for more details.
00014 
00015    You should have received a copy of the GNU Library General Public
00016    License along with this library; if not, write to the Free
00017    Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
00018    MA 02111-1307, USA
00019 
00020 */
00021 
00022 #ifndef HIP_XML_H
00023 #define HIP_XML_H
00024 
00025 /* for sbuffer */
00026 #include "string_utils.h"
00027 
00028 BEGIN_NEON_DECLS
00029 
00030 /* Generic XML parsing interface...
00031    
00032    Definitions:
00033    
00034    * A handler knows how to parse a certain set of XML elements.
00035    * The handler stack
00036 
00037    * 
00038    
00039 
00040    Basic principle is that you provide these things:
00041      1) a list of elements which you wish to handle 
00042      2) a validation callback which tells the parser whether you
00043      want to handle this element.
00044      3) a callback function which is called when a complete element
00045      has been parsed (provided you are handling the element).
00046     
00047    This code then deals with the boring stuff like:
00048      - Dealing with XML namespaces   
00049      - Collecting CDATA
00050 
00051    The element list is stored in a 'hip_xml_elm' array.  For each
00052    element, you specify the element name, an element id, and some
00053    flags for that element.
00054 
00055 const static struct hip_xml_elm[] = {
00056    { "DAV:", "resourcetype", ELM_resourcetype, 0 },
00057    { "DAV:", "collection", ELM_collection, HIP_ELM_CDATA },
00058    { NULL }
00059 };
00060 
00061    This list contains two elements, resourcetype and collection, both in 
00062    the "DAV:" namespace.  The collection element can contain cdata.
00063    
00064 */
00065 
00066 /* Reserved element id's */
00067 #define HIP_ELM_unknown -1
00068 #define HIP_ELM_root 0
00069 
00070 #define HIP_ELM_UNUSED (100)
00071 
00072 typedef int hip_xml_elmid;
00073 
00074 struct hip_xml_elm;
00075 
00076 /* An element */
00077 struct hip_xml_elm {
00078     const char *nspace, *name;
00079     hip_xml_elmid id;
00080     unsigned int flags;
00081 };
00082 
00083 /* Function to check element context... 
00084    This callback must return:
00085      HIP_XML_VALID ->
00086        Yes, this is valid XML, and I want to handle this element.
00087      HIP_XML_INVALID ->
00088        No, this is NOT valid XML, and parsing should stop.
00089      HIP_XML_DECLINE ->
00090        I don't know anything about this element, someone else
00091        can handle it.
00092 */
00093 
00094 
00095 #define HIP_XML_VALID (0)
00096 #define HIP_XML_INVALID (-1)
00097 #define HIP_XML_DECLINE (-2)
00098 
00099 typedef int (*hip_xml_validate_cb)
00100     (hip_xml_elmid parent, hip_xml_elmid child);
00101 
00102 typedef int (*hip_xml_startelm_cb)
00103     (void *userdata, const struct hip_xml_elm *elm, const char **atts);
00104 
00105 /* Called when a complete element is parsed */
00106 typedef int (*hip_xml_endelm_cb)
00107     (void *userdata, const struct hip_xml_elm *s, const char *cdata);
00108 
00109 typedef void (*hip_xml_cdata_cb)
00110     (void *userdata, const struct hip_xml_elm *s, 
00111      const char *cdata, int len);
00112 
00113 struct hip_xml_parser_s;
00114 typedef struct hip_xml_parser_s hip_xml_parser;
00115 
00116 /* Flags */
00117 /* This element has no children */
00118 #define HIP_XML_CDATA (1<<1)
00119 /* Collect complete contents of this node as cdata */
00120 #define HIP_XML_COLLECT ((1<<2) | HIP_XML_CDATA)
00121 /* Decode UTF-8 data in cdata. */
00122 #define HIP_XML_UTF8DECODE (1<<3)
00123 /* This element uses MIXED mode */
00124 #define HIP_XML_MIXED (1<<4)
00125 
00126 /* Initialise the parser */
00127 hip_xml_parser *hip_xml_create(void);
00128 
00129 /* Push a handler onto the handler stack for the given list of elements.
00130  * elements must be an array, with the last element .nspace being NULL.
00131  * Callbacks are called in order:
00132  *   1. validate_cb
00133  *   2. startelm_cb
00134  *   3. endelm_cb
00135  * (then back to the beginning again).
00136  * If any of the callbacks ever return non-zero, the parse will STOP.
00137  * userdata is passed as the first argument to startelm_cb and endelm_cb.
00138  */
00139 void hip_xml_push_handler(hip_xml_parser *p,
00140                        const struct hip_xml_elm *elements, 
00141                        hip_xml_validate_cb validate_cb, 
00142                        hip_xml_startelm_cb startelm_cb, 
00143                        hip_xml_endelm_cb endelm_cb,
00144                        void *userdata);
00145 
00146 /* Add a handler which uses a mixed-mode cdata callback */
00147 void hip_xml_push_mixed_handler(hip_xml_parser *p,
00148                             const struct hip_xml_elm *elements,
00149                             hip_xml_validate_cb validate_cb,
00150                             hip_xml_startelm_cb startelm_cb,
00151                             hip_xml_cdata_cb cdata_cb,
00152                             hip_xml_endelm_cb endelm_cb,
00153                             void *userdata);
00154 
00155 /* Returns non-zero if the parse was valid, zero if it failed (e.g.,
00156  * any of the callbacks return non-zero, the XML was not well-formed,
00157  * etc).  Use hip_xml_get_error to retrieve the error message if it
00158  * failed. */
00159 int hip_xml_valid(hip_xml_parser *p);
00160 
00161 /* Destroys the parser. Any operations on it then have 
00162  * undefined results. */
00163 void hip_xml_destroy(hip_xml_parser *p);
00164 
00165 /* Parse the given block of input of length len. Block does 
00166  * not need to be NULL-terminated. */
00167 void hip_xml_parse(hip_xml_parser *p, const char *block, size_t len);
00168 
00169 /* As above, casting (hip_xml_parser *)userdata internally.
00170  * (This function can be passed to http_add_response_body_reader) */
00171 void hip_xml_parse_v(void *userdata, const char *block, size_t len);
00172 
00173 /* Return current parse line for errors */
00174 int hip_xml_currentline(hip_xml_parser *p);
00175 
00176 /* Set error message for parser */
00177 void hip_xml_set_error(hip_xml_parser *p, const char *msg);
00178 
00179 const char *hip_xml_get_error(hip_xml_parser *p);
00180 
00181 END_NEON_DECLS
00182 
00183 #endif /* HIP_XML_H */