<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1"> <title>dbus-gloader-expat.c Source File</title> <link href="doxygen.css" rel="stylesheet" type="text/css"> </head><body> <!-- Generated by Doxygen 1.2.15 --> <center> <a class="qindex" href="index.html">Main Page</a> <a class="qindex" href="modules.html">Modules</a> <a class="qindex" href="annotated.html">Data Structures</a> <a class="qindex" href="files.html">File List</a> <a class="qindex" href="functions.html">Data Fields</a> <a class="qindex" href="pages.html">Related Pages</a> </center> <hr><h1>dbus-gloader-expat.c</h1><div class="fragment"><pre>00001 <font class="comment">/* -*- mode: C; c-file-style: "gnu" -*- */</font> 00002 <font class="comment">/* dbus-gloader-expat.c expat XML loader</font> 00003 <font class="comment"> *</font> 00004 <font class="comment"> * Copyright (C) 2003 Red Hat, Inc.</font> 00005 <font class="comment"> *</font> 00006 <font class="comment"> * Licensed under the Academic Free License version 2.0</font> 00007 <font class="comment"> *</font> 00008 <font class="comment"> * This program is free software; you can redistribute it and/or modify</font> 00009 <font class="comment"> * it under the terms of the GNU General Public License as published by</font> 00010 <font class="comment"> * the Free Software Foundation; either version 2 of the License, or</font> 00011 <font class="comment"> * (at your option) any later version.</font> 00012 <font class="comment"> *</font> 00013 <font class="comment"> * This program is distributed in the hope that it will be useful,</font> 00014 <font class="comment"> * but WITHOUT ANY WARRANTY; without even the implied warranty of</font> 00015 <font class="comment"> * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the</font> 00016 <font class="comment"> * GNU General Public License for more details.</font> 00017 <font class="comment"> *</font> 00018 <font class="comment"> * You should have received a copy of the GNU General Public License</font> 00019 <font class="comment"> * along with this program; if not, write to the Free Software</font> 00020 <font class="comment"> * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA</font> 00021 <font class="comment"> *</font> 00022 <font class="comment"> */</font> 00023 00024 <font class="preprocessor">#include "dbus-gparser.h"</font> 00025 <font class="preprocessor">#include <expat.h></font> 00026 00027 <font class="keyword">static</font> <font class="keywordtype">void</font>* 00028 expat_g_malloc (size_t sz) 00029 { 00030 <font class="keywordflow">return</font> g_malloc (sz); 00031 } 00032 00033 <font class="keyword">static</font> <font class="keywordtype">void</font>* 00034 expat_g_realloc (<font class="keywordtype">void</font> *mem, size_t sz) 00035 { 00036 <font class="keywordflow">return</font> g_realloc (mem, sz); 00037 } 00038 00039 <font class="keyword">static</font> XML_Memory_Handling_Suite memsuite = 00040 { 00041 expat_g_malloc, 00042 expat_g_realloc, 00043 g_free 00044 }; 00045 <a name="l00049"></a><a class="code" href="structExpatParseContext.html">00049</a> <font class="keyword">typedef</font> <font class="keyword">struct</font> 00050 <font class="keyword"></font>{ <a name="l00051"></a><a class="code" href="structExpatParseContext.html#m0">00051</a> Parser *parser; <a name="l00052"></a><a class="code" href="structExpatParseContext.html#m1">00052</a> <font class="keyword">const</font> <font class="keywordtype">char</font> *filename; <a name="l00053"></a><a class="code" href="structExpatParseContext.html#m2">00053</a> GString *content; <a name="l00054"></a><a class="code" href="structExpatParseContext.html#m3">00054</a> GError **error; <a name="l00055"></a><a class="code" href="structExpatParseContext.html#m4">00055</a> gboolean failed; 00056 } <a class="code" href="structExpatParseContext.html">ExpatParseContext</a>; 00057 00058 <font class="keyword">static</font> dbus_bool_t 00059 process_content (<a class="code" href="structExpatParseContext.html">ExpatParseContext</a> *context) 00060 { 00061 <font class="keywordflow">if</font> (context-><a class="code" href="structExpatParseContext.html#m4">failed</a>) 00062 <font class="keywordflow">return</font> FALSE; 00063 00064 <font class="keywordflow">if</font> (context-><a class="code" href="structExpatParseContext.html#m2">content</a>->len > 0) 00065 { 00066 <font class="keywordflow">if</font> (!parser_content (context-><a class="code" href="structExpatParseContext.html#m0">parser</a>, 00067 context-><a class="code" href="structExpatParseContext.html#m2">content</a>->str, 00068 context-><a class="code" href="structExpatParseContext.html#m2">content</a>->len, 00069 context-><a class="code" href="structExpatParseContext.html#m3">error</a>)) 00070 { 00071 context-><a class="code" href="structExpatParseContext.html#m4">failed</a> = TRUE; 00072 <font class="keywordflow">return</font> FALSE; 00073 } 00074 g_string_set_size (context-><a class="code" href="structExpatParseContext.html#m2">content</a>, 0); 00075 } 00076 00077 <font class="keywordflow">return</font> TRUE; 00078 } 00079 00080 <font class="keyword">static</font> <font class="keywordtype">void</font> 00081 expat_StartElementHandler (<font class="keywordtype">void</font> *userData, 00082 <font class="keyword">const</font> XML_Char *name, 00083 <font class="keyword">const</font> XML_Char **atts) 00084 { 00085 <a class="code" href="structExpatParseContext.html">ExpatParseContext</a> *context = userData; 00086 <font class="keywordtype">int</font> i; 00087 <font class="keywordtype">char</font> **names; 00088 <font class="keywordtype">char</font> **values; 00089 00090 <font class="comment">/* Expat seems to suck and can't abort the parse if we</font> 00091 <font class="comment"> * throw an error. Expat 2.0 is supposed to fix this.</font> 00092 <font class="comment"> */</font> 00093 <font class="keywordflow">if</font> (context-><a class="code" href="structExpatParseContext.html#m4">failed</a>) 00094 <font class="keywordflow">return</font>; 00095 00096 <font class="keywordflow">if</font> (!process_content (context)) 00097 <font class="keywordflow">return</font>; 00098 00099 <font class="comment">/* "atts" is key, value, key, value, NULL */</font> 00100 <font class="keywordflow">for</font> (i = 0; atts[i] != NULL; ++i) 00101 ; <font class="comment">/* nothing */</font> 00102 00103 g_assert (i % 2 == 0); 00104 names = g_new0 (<font class="keywordtype">char</font> *, i / 2 + 1); 00105 values = g_new0 (<font class="keywordtype">char</font> *, i / 2 + 1); 00106 00107 i = 0; 00108 <font class="keywordflow">while</font> (atts[i] != NULL) 00109 { 00110 g_assert (i % 2 == 0); 00111 names [i / 2] = (<font class="keywordtype">char</font>*) atts[i]; 00112 values[i / 2] = (<font class="keywordtype">char</font>*) atts[i+1]; 00113 00114 i += 2; 00115 } 00116 00117 <font class="keywordflow">if</font> (!parser_start_element (context-><a class="code" href="structExpatParseContext.html#m0">parser</a>, 00118 name, 00119 (<font class="keyword">const</font> <font class="keywordtype">char</font> **) names, 00120 (<font class="keyword">const</font> <font class="keywordtype">char</font> **) values, 00121 context-><a class="code" href="structExpatParseContext.html#m3">error</a>)) 00122 { 00123 g_free (names); 00124 g_free (values); 00125 context-><a class="code" href="structExpatParseContext.html#m4">failed</a> = TRUE; 00126 <font class="keywordflow">return</font>; 00127 } 00128 00129 g_free (names); 00130 g_free (values); 00131 } 00132 00133 <font class="keyword">static</font> <font class="keywordtype">void</font> 00134 expat_EndElementHandler (<font class="keywordtype">void</font> *userData, 00135 <font class="keyword">const</font> XML_Char *name) 00136 { 00137 <a class="code" href="structExpatParseContext.html">ExpatParseContext</a> *context = userData; 00138 00139 <font class="keywordflow">if</font> (!process_content (context)) 00140 <font class="keywordflow">return</font>; 00141 00142 <font class="keywordflow">if</font> (!parser_end_element (context-><a class="code" href="structExpatParseContext.html#m0">parser</a>, 00143 name, 00144 context-><a class="code" href="structExpatParseContext.html#m3">error</a>)) 00145 { 00146 context-><a class="code" href="structExpatParseContext.html#m4">failed</a> = TRUE; 00147 <font class="keywordflow">return</font>; 00148 } 00149 } 00150 00151 <font class="comment">/* s is not 0 terminated. */</font> 00152 <font class="keyword">static</font> <font class="keywordtype">void</font> 00153 expat_CharacterDataHandler (<font class="keywordtype">void</font> *userData, 00154 <font class="keyword">const</font> XML_Char *s, 00155 <font class="keywordtype">int</font> len) 00156 { 00157 <a class="code" href="structExpatParseContext.html">ExpatParseContext</a> *context = userData; 00158 00159 <font class="keywordflow">if</font> (context-><a class="code" href="structExpatParseContext.html#m4">failed</a>) 00160 <font class="keywordflow">return</font>; 00161 00162 g_string_append_len (context-><a class="code" href="structExpatParseContext.html#m2">content</a>, 00163 s, len); 00164 } 00165 00166 NodeInfo* 00167 description_load_from_file (<font class="keyword">const</font> <font class="keywordtype">char</font> *filename, 00168 GError **error) 00169 { 00170 <font class="keywordtype">char</font> *contents; 00171 gsize len; 00172 NodeInfo *nodes; 00173 00174 contents = NULL; 00175 <font class="keywordflow">if</font> (!g_file_get_contents (filename, &contents, &len, error)) 00176 <font class="keywordflow">return</font> NULL; 00177 00178 nodes = description_load_from_string (contents, len, error); 00179 g_free (contents); 00180 00181 <font class="keywordflow">return</font> nodes; 00182 } 00183 00184 NodeInfo* 00185 description_load_from_string (<font class="keyword">const</font> <font class="keywordtype">char</font> *str, 00186 <font class="keywordtype">int</font> len, 00187 GError **error) 00188 { 00189 XML_Parser expat; 00190 <a class="code" href="structExpatParseContext.html">ExpatParseContext</a> context; 00191 NodeInfo *nodes; 00192 00193 g_return_val_if_fail (error == NULL || *error == NULL, NULL); 00194 00195 expat = NULL; 00196 context.<a class="code" href="structExpatParseContext.html#m0">parser</a> = NULL; 00197 context.<a class="code" href="structExpatParseContext.html#m3">error</a> = error; 00198 context.<a class="code" href="structExpatParseContext.html#m4">failed</a> = FALSE; 00199 00200 expat = XML_ParserCreate_MM (<font class="stringliteral">"UTF-8"</font>, &memsuite, NULL); 00201 <font class="keywordflow">if</font> (expat == NULL) 00202 g_error (<font class="stringliteral">"No memory to create XML parser\n"</font>); 00203 00204 context.<a class="code" href="structExpatParseContext.html#m0">parser</a> = parser_new (); 00205 context.<a class="code" href="structExpatParseContext.html#m2">content</a> = g_string_new (NULL); 00206 00207 XML_SetUserData (expat, &context); 00208 XML_SetElementHandler (expat, 00209 expat_StartElementHandler, 00210 expat_EndElementHandler); 00211 XML_SetCharacterDataHandler (expat, 00212 expat_CharacterDataHandler); 00213 00214 <font class="keywordflow">if</font> (!XML_Parse (expat, str, len, TRUE)) 00215 { 00216 <font class="keywordflow">if</font> (context.<a class="code" href="structExpatParseContext.html#m3">error</a> != NULL && 00217 *context.<a class="code" href="structExpatParseContext.html#m3">error</a> == NULL) 00218 { 00219 <font class="keyword">enum</font> XML_Error e; 00220 00221 e = XML_GetErrorCode (expat); 00222 <font class="keywordflow">if</font> (e == XML_ERROR_NO_MEMORY) 00223 g_error (<font class="stringliteral">"Not enough memory to parse XML document"</font>); 00224 <font class="keywordflow">else</font> 00225 g_set_error (error, 00226 G_MARKUP_ERROR, 00227 G_MARKUP_ERROR_PARSE, 00228 <font class="stringliteral">"Error in D-BUS description XML, line %d, column %d: %s\n"</font>, 00229 XML_GetCurrentLineNumber (expat), 00230 XML_GetCurrentColumnNumber (expat), 00231 XML_ErrorString (e)); 00232 } 00233 00234 <font class="keywordflow">goto</font> failed; 00235 } 00236 00237 <font class="keywordflow">if</font> (context.<a class="code" href="structExpatParseContext.html#m4">failed</a>) 00238 <font class="keywordflow">goto</font> failed; 00239 00240 <font class="keywordflow">if</font> (!parser_finished (context.<a class="code" href="structExpatParseContext.html#m0">parser</a>, error)) 00241 <font class="keywordflow">goto</font> failed; 00242 00243 XML_ParserFree (expat); 00244 g_string_free (context.<a class="code" href="structExpatParseContext.html#m2">content</a>, TRUE); 00245 00246 g_return_val_if_fail (error == NULL || *error == NULL, NULL); 00247 nodes = parser_get_nodes (context.<a class="code" href="structExpatParseContext.html#m0">parser</a>); 00248 node_info_ref (nodes); 00249 parser_unref (context.<a class="code" href="structExpatParseContext.html#m0">parser</a>); 00250 <font class="keywordflow">return</font> nodes; 00251 00252 failed: 00253 g_return_val_if_fail (error == NULL || *error != NULL, NULL); 00254 00255 g_string_free (context.<a class="code" href="structExpatParseContext.html#m2">content</a>, TRUE); 00256 <font class="keywordflow">if</font> (expat) 00257 XML_ParserFree (expat); 00258 <font class="keywordflow">if</font> (context.<a class="code" href="structExpatParseContext.html#m0">parser</a>) 00259 parser_unref (context.<a class="code" href="structExpatParseContext.html#m0">parser</a>); 00260 <font class="keywordflow">return</font> NULL; 00261 } 00262 </pre></div><hr><address align="right"><small>Generated on Wed Jun 9 05:01:25 2004 for D-BUS by <a href="http://www.doxygen.org/index.html"> <img src="doxygen.png" alt="doxygen" align="middle" border=0 width=110 height=53></a>1.2.15 </small></address> </body> </html>