Sophie

Sophie

distrib > Mandriva > 9.0 > i586 > by-pkgid > d67485fb8ce60f8952179bbde3b5d022 > files > 51

libgdal0-devel-1.1.7-2mdk.i586.rpm

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html><head><meta name="robots" content="noindex">
<meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
<title>cpl_minixml.cpp Source File</title>
<link href="doxygen.css" rel="stylesheet" type="text/css">
</head><body bgcolor="#ffffff">
<!-- Generated by Doxygen 1.2.3-20001105 on Thu Mar 28 09:47:27 2002 -->
<center>
<a class="qindex" href="index.html">Main Page</a> &nbsp; <a class="qindex" href="hierarchy.html">Class Hierarchy</a> &nbsp; <a class="qindex" href="annotated.html">Compound List</a> &nbsp; <a class="qindex" href="files.html">File List</a> &nbsp; <a class="qindex" href="functions.html">Compound Members</a> &nbsp; <a class="qindex" href="globals.html">File Members</a> &nbsp; <a class="qindex" href="pages.html">Related Pages</a> &nbsp; </center>
<hr><h1>cpl_minixml.cpp</h1><div class="fragment"><pre>00001 <font class="comment">/**********************************************************************</font>
00002 <font class="comment"> * $Id: cpl_minixml_cpp-source.html,v 1.2 2002/04/16 13:11:47 warmerda Exp $</font>
00003 <font class="comment"> *</font>
00004 <font class="comment"> * Project:  CPL - Common Portability Library</font>
00005 <font class="comment"> * Purpose:  Implementation of MiniXML Parser and handling.</font>
00006 <font class="comment"> * Author:   Frank Warmerdam, warmerdam@pobox.com</font>
00007 <font class="comment"> *</font>
00008 <font class="comment"> **********************************************************************</font>
00009 <font class="comment"> * Copyright (c) 2001, Frank Warmerdam</font>
00010 <font class="comment"> *</font>
00011 <font class="comment"> * Permission is hereby granted, free of charge, to any person obtaining a</font>
00012 <font class="comment"> * copy of this software and associated documentation files (the "Software"),</font>
00013 <font class="comment"> * to deal in the Software without restriction, including without limitation</font>
00014 <font class="comment"> * the rights to use, copy, modify, merge, publish, distribute, sublicense,</font>
00015 <font class="comment"> * and/or sell copies of the Software, and to permit persons to whom the</font>
00016 <font class="comment"> * Software is furnished to do so, subject to the following conditions:</font>
00017 <font class="comment"> * </font>
00018 <font class="comment"> * The above copyright notice and this permission notice shall be included</font>
00019 <font class="comment"> * in all copies or substantial portions of the Software.</font>
00020 <font class="comment"> * </font>
00021 <font class="comment"> * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR</font>
00022 <font class="comment"> * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,</font>
00023 <font class="comment"> * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL</font>
00024 <font class="comment"> * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER</font>
00025 <font class="comment"> * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING</font>
00026 <font class="comment"> * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER </font>
00027 <font class="comment"> * DEALINGS IN THE SOFTWARE.</font>
00028 <font class="comment"> **********************************************************************</font>
00029 <font class="comment"> *</font>
00030 <font class="comment"> * $Log: cpl_minixml_cpp-source.html,v $
00030 <font class="comment"> * Revision 1.2  2002/04/16 13:11:47  warmerda
00030 <font class="comment"> * updated
00030 <font class="comment"> *</font>
00031 <font class="comment"> * Revision 1.9  2002/03/07 22:19:20  warmerda</font>
00032 <font class="comment"> * don't do operations within CPLAssert(), in UnreadChar()</font>
00033 <font class="comment"> *</font>
00034 <font class="comment"> * Revision 1.8  2002/03/05 14:26:57  warmerda</font>
00035 <font class="comment"> * expanded tabs</font>
00036 <font class="comment"> *</font>
00037 <font class="comment"> * Revision 1.7  2002/01/23 20:45:05  warmerda</font>
00038 <font class="comment"> * handle &lt;?...?&gt; and comment elements</font>
00039 <font class="comment"> *</font>
00040 <font class="comment"> * Revision 1.6  2002/01/22 18:54:48  warmerda</font>
00041 <font class="comment"> * ensure text is property initialized when serializing</font>
00042 <font class="comment"> *</font>
00043 <font class="comment"> * Revision 1.5  2002/01/16 03:58:51  warmerda</font>
00044 <font class="comment"> * support single quotes as well as double quotes</font>
00045 <font class="comment"> *</font>
00046 <font class="comment"> * Revision 1.4  2001/12/06 18:13:49  warmerda</font>
00047 <font class="comment"> * added CPLAddXMLChild and CPLCreateElmentAndValue</font>
00048 <font class="comment"> *</font>
00049 <font class="comment"> * Revision 1.3  2001/11/16 21:20:16  warmerda</font>
00050 <font class="comment"> * fixed typo</font>
00051 <font class="comment"> *</font>
00052 <font class="comment"> * Revision 1.2  2001/11/16 20:29:58  warmerda</font>
00053 <font class="comment"> * fixed lost char in normal CString tokens</font>
00054 <font class="comment"> *</font>
00055 <font class="comment"> * Revision 1.1  2001/11/16 15:39:48  warmerda</font>
00056 <font class="comment"> * New</font>
00057 <font class="comment"> */</font>
00058 
00059 <font class="preprocessor">#include &lt;ctype.h&gt;</font>
00060 <font class="preprocessor">#include "cpl_minixml.h"</font>
00061 <font class="preprocessor">#include "<a class="code" href="cpl_error_h.html">cpl_error.h</a>"</font>
00062 <font class="preprocessor">#include "<a class="code" href="cpl_conv_h.html">cpl_conv.h</a>"</font>
00063 <font class="preprocessor">#include "cpl_string.h"</font>
00064 
00065 CPL_CVSID(<font class="stringliteral">"$Id: cpl_minixml_cpp-source.html,v 1.2 2002/04/16 13:11:47 warmerda Exp $"</font>);
00066 
00067 <font class="keyword">typedef</font> <font class="keyword">enum</font> {
00068     TNone,
00069     TString, 
00070     TOpen, 
00071     TClose,
00072     TEqual,
00073     TToken,
00074     TSlashClose,
00075     TQuestionClose,
00076     TComment
00077 } TokenType;
00078 
00079 <font class="keyword">typedef</font> <font class="keyword">struct </font>{
00080     <font class="keyword">const</font> <font class="keywordtype">char</font> *pszInput;
00081     <font class="keywordtype">int</font>        nInputOffset;
00082     <font class="keywordtype">int</font>        nInputLine;
00083 
00084     <font class="keywordtype">int</font>        bInElement;
00085     TokenType  eTokenType;
00086     <font class="keywordtype">char</font>       *pszToken;
00087     <font class="keywordtype">int</font>        nTokenMaxSize;
00088     <font class="keywordtype">int</font>        nTokenSize;
00089 
00090     <font class="keywordtype">int</font>        nStackMaxSize;
00091     <font class="keywordtype">int</font>        nStackSize;
00092     CPLXMLNode **papsStack;
00093 
00094     CPLXMLNode *psFirstNode;
00095 } ParseContext;
00096 
00097 <font class="comment">/************************************************************************/</font>
00098 <font class="comment">/*                              ReadChar()                              */</font>
00099 <font class="comment">/************************************************************************/</font>
00100 
00101 <font class="keyword">static</font> <font class="keywordtype">char</font> ReadChar( ParseContext *psContext )<font class="keyword"></font>
00102 <font class="keyword"></font>
00103 <font class="keyword"></font>{
00104     <font class="keywordtype">char</font>        chReturn;
00105 
00106     chReturn = psContext-&gt;pszInput[psContext-&gt;nInputOffset++];
00107 
00108     <font class="keywordflow">if</font>( chReturn == <font class="charliteral">'\0'</font> )
00109         psContext-&gt;nInputOffset--;
00110     <font class="keywordflow">else</font> <font class="keywordflow">if</font>( chReturn == 10 )
00111         psContext-&gt;nInputLine++;
00112     
00113     <font class="keywordflow">return</font> chReturn;
00114 }
00115 
00116 <font class="comment">/************************************************************************/</font>
00117 <font class="comment">/*                             UnreadChar()                             */</font>
00118 <font class="comment">/************************************************************************/</font>
00119 
00120 <font class="keyword">static</font> <font class="keywordtype">void</font> UnreadChar( ParseContext *psContext, <font class="keywordtype">char</font> chToUnread )<font class="keyword"></font>
00121 <font class="keyword"></font>
00122 <font class="keyword"></font>{
00123     <font class="keywordflow">if</font>( chToUnread == <font class="charliteral">'\0'</font> )
00124     {
00125         <font class="comment">/* do nothing */</font>
00126     }
00127     <font class="keywordflow">else</font>
00128     {
00129         CPLAssert( chToUnread 
00130                    == psContext-&gt;pszInput[psContext-&gt;nInputOffset-1] );
00131 
00132         psContext-&gt;nInputOffset--;
00133 
00134         <font class="keywordflow">if</font>( chToUnread == 10 )
00135             psContext-&gt;nInputLine--;
00136     }
00137 }
00138 
00139 <font class="comment">/************************************************************************/</font>
00140 <font class="comment">/*                             AddToToken()                             */</font>
00141 <font class="comment">/************************************************************************/</font>
00142 
00143 <font class="keyword">static</font> <font class="keywordtype">void</font> AddToToken( ParseContext *psContext, <font class="keywordtype">char</font> chNewChar )<font class="keyword"></font>
00144 <font class="keyword"></font>
00145 <font class="keyword"></font>{
00146     <font class="keywordflow">if</font>( psContext-&gt;pszToken == NULL )
00147     {
00148         psContext-&gt;nTokenMaxSize = 10;
00149         psContext-&gt;pszToken = (<font class="keywordtype">char</font> *) <a class="code" href="cpl_conv_h.html#a3">CPLMalloc</a>(psContext-&gt;nTokenMaxSize);
00150     }
00151     <font class="keywordflow">else</font> <font class="keywordflow">if</font>( psContext-&gt;nTokenSize &gt;= psContext-&gt;nTokenMaxSize - 2 )
00152     {
00153         psContext-&gt;nTokenMaxSize *= 2;
00154         psContext-&gt;pszToken = (<font class="keywordtype">char</font> *) 
00155             <a class="code" href="cpl_conv_h.html#a5">CPLRealloc</a>(psContext-&gt;pszToken,psContext-&gt;nTokenMaxSize);
00156     }
00157 
00158     psContext-&gt;pszToken[psContext-&gt;nTokenSize++] = chNewChar;
00159     psContext-&gt;pszToken[psContext-&gt;nTokenSize] = <font class="charliteral">'\0'</font>;
00160 }
00161 
00162 <font class="comment">/************************************************************************/</font>
00163 <font class="comment">/*                             ReadToken()                              */</font>
00164 <font class="comment">/************************************************************************/</font>
00165 
00166 <font class="keyword">static</font> TokenType ReadToken( ParseContext *psContext )<font class="keyword"></font>
00167 <font class="keyword"></font>
00168 <font class="keyword"></font>{
00169     <font class="keywordtype">char</font>        chNext;
00170 
00171     psContext-&gt;nTokenSize = 0;
00172     psContext-&gt;pszToken[0] = <font class="charliteral">'\0'</font>;
00173     
00174     chNext = ReadChar( psContext );
00175     <font class="keywordflow">while</font>( isspace(chNext) )
00176         chNext = ReadChar( psContext );
00177 
00178 <font class="comment">/* -------------------------------------------------------------------- */</font>
00179 <font class="comment">/*      Handle comments.                                                */</font>
00180 <font class="comment">/* -------------------------------------------------------------------- */</font>
00181     <font class="keywordflow">if</font>( chNext == <font class="charliteral">'&lt;'</font> 
00182         &amp;&amp; EQUALN(psContext-&gt;pszInput+psContext-&gt;nInputOffset,"!--",3) )
00183     {
00184         psContext-&gt;eTokenType = TComment;
00185 
00186         <font class="comment">// Skip "!--" characters</font>
00187         ReadChar(psContext);
00188         ReadChar(psContext);
00189         ReadChar(psContext);
00190 
00191         <font class="keywordflow">while</font>( !EQUALN(psContext-&gt;pszInput+psContext-&gt;nInputOffset,"--&gt;",3)
00192                &amp;&amp; (chNext = ReadChar(psContext)) != <font class="charliteral">'\0'</font> )
00193             AddToToken( psContext, chNext );
00194 
00195         <font class="comment">// Skip "--&gt;" characters</font>
00196         ReadChar(psContext);
00197         ReadChar(psContext);
00198         ReadChar(psContext);
00199     }
00200 <font class="comment">/* -------------------------------------------------------------------- */</font>
00201 <font class="comment">/*      Simple single tokens of interest.                               */</font>
00202 <font class="comment">/* -------------------------------------------------------------------- */</font>
00203     <font class="keywordflow">else</font> <font class="keywordflow">if</font>( chNext == <font class="charliteral">'&lt;'</font> &amp;&amp; !psContext-&gt;bInElement )
00204     {
00205         psContext-&gt;eTokenType = TOpen;
00206         psContext-&gt;bInElement = TRUE;
00207     }
00208     <font class="keywordflow">else</font> <font class="keywordflow">if</font>( chNext == <font class="charliteral">'&gt;'</font> &amp;&amp; psContext-&gt;bInElement )
00209     {
00210         psContext-&gt;eTokenType = TClose;
00211         psContext-&gt;bInElement = FALSE;
00212     }
00213     <font class="keywordflow">else</font> <font class="keywordflow">if</font>( chNext == <font class="charliteral">'='</font> &amp;&amp; psContext-&gt;bInElement )
00214     {
00215         psContext-&gt;eTokenType = TEqual;
00216     }
00217     <font class="keywordflow">else</font> <font class="keywordflow">if</font>( chNext == <font class="charliteral">'\0'</font> )
00218     {
00219         psContext-&gt;eTokenType = TNone;
00220     }
00221 <font class="comment">/* -------------------------------------------------------------------- */</font>
00222 <font class="comment">/*      Handle the /&gt; token terminator.                                 */</font>
00223 <font class="comment">/* -------------------------------------------------------------------- */</font>
00224     <font class="keywordflow">else</font> <font class="keywordflow">if</font>( chNext == <font class="charliteral">'/'</font> &amp;&amp; psContext-&gt;bInElement 
00225              &amp;&amp; psContext-&gt;pszInput[psContext-&gt;nInputOffset] == <font class="charliteral">'&gt;'</font> )
00226     {
00227         chNext = ReadChar( psContext );
00228         <font class="keywordflow">if</font>( chNext != <font class="charliteral">'&gt;'</font> )
00229         {
00230             psContext-&gt;eTokenType = TNone;
00231             <a class="code" href="cpl_error_h.html#a17">CPLError</a>( CE_Failure, CPLE_AppDefined, 
00232                       <font class="stringliteral">"Parse error at '/' on line %d, expected '&gt;'."</font>, 
00233                       psContext-&gt;nInputLine );
00234         }
00235         <font class="keywordflow">else</font>
00236         {
00237             psContext-&gt;eTokenType = TSlashClose;
00238             psContext-&gt;bInElement = FALSE;
00239         }
00240     }
00241 <font class="comment">/* -------------------------------------------------------------------- */</font>
00242 <font class="comment">/*      Handle the ?&gt; token terminator.                                 */</font>
00243 <font class="comment">/* -------------------------------------------------------------------- */</font>
00244     <font class="keywordflow">else</font> <font class="keywordflow">if</font>( chNext == <font class="charliteral">'?'</font> &amp;&amp; psContext-&gt;bInElement 
00245              &amp;&amp; psContext-&gt;pszInput[psContext-&gt;nInputOffset] == <font class="charliteral">'&gt;'</font> )
00246     {
00247         chNext = ReadChar( psContext );
00248         <font class="keywordflow">if</font>( chNext != <font class="charliteral">'&gt;'</font> )
00249         {
00250             psContext-&gt;eTokenType = TNone;
00251             <a class="code" href="cpl_error_h.html#a17">CPLError</a>( CE_Failure, CPLE_AppDefined, 
00252                       <font class="stringliteral">"Parse error at '?' on line %d, expected '&gt;'."</font>, 
00253                       psContext-&gt;nInputLine );
00254         }
00255         <font class="keywordflow">else</font>
00256         {
00257             psContext-&gt;eTokenType = TQuestionClose;
00258             psContext-&gt;bInElement = FALSE;
00259         }
00260     }
00261 
00262 <font class="comment">/* -------------------------------------------------------------------- */</font>
00263 <font class="comment">/*      Collect a quoted string.                                        */</font>
00264 <font class="comment">/* -------------------------------------------------------------------- */</font>
00265     <font class="keywordflow">else</font> <font class="keywordflow">if</font>( psContext-&gt;bInElement &amp;&amp; chNext == <font class="charliteral">'"'</font> )
00266     {
00267         psContext-&gt;eTokenType = TString;
00268 
00269         <font class="keywordflow">while</font>( (chNext = ReadChar(psContext)) != <font class="charliteral">'"'</font> 
00270                &amp;&amp; chNext != <font class="charliteral">'\0'</font> )
00271             AddToToken( psContext, chNext );
00272         
00273         <font class="keywordflow">if</font>( chNext != <font class="charliteral">'"'</font> )
00274         {
00275             psContext-&gt;eTokenType = TNone;
00276             <a class="code" href="cpl_error_h.html#a17">CPLError</a>( CE_Failure, CPLE_AppDefined, 
00277                   <font class="stringliteral">"Parse error on line %d, reached EOF before closing quote."</font>, 
00278                       psContext-&gt;nInputLine );
00279         }
00280     }
00281 
00282     <font class="keywordflow">else</font> <font class="keywordflow">if</font>( psContext-&gt;bInElement &amp;&amp; chNext == <font class="charliteral">'\''</font> )
00283     {
00284         psContext-&gt;eTokenType = TString;
00285 
00286         <font class="keywordflow">while</font>( (chNext = ReadChar(psContext)) != <font class="charliteral">'\''</font> 
00287                &amp;&amp; chNext != <font class="charliteral">'\0'</font> )
00288             AddToToken( psContext, chNext );
00289         
00290         <font class="keywordflow">if</font>( chNext != <font class="charliteral">'\''</font> )
00291         {
00292             psContext-&gt;eTokenType = TNone;
00293             <a class="code" href="cpl_error_h.html#a17">CPLError</a>( CE_Failure, CPLE_AppDefined, 
00294                   <font class="stringliteral">"Parse error on line %d, reached EOF before closing quote."</font>, 
00295                       psContext-&gt;nInputLine );
00296         }
00297     }
00298 
00299 <font class="comment">/* -------------------------------------------------------------------- */</font>
00300 <font class="comment">/*      Collect an unquoted string, terminated by a open angle          */</font>
00301 <font class="comment">/*      bracket.                                                        */</font>
00302 <font class="comment">/* -------------------------------------------------------------------- */</font>
00303     <font class="keywordflow">else</font> <font class="keywordflow">if</font>( !psContext-&gt;bInElement )
00304     {
00305         psContext-&gt;eTokenType = TString;
00306 
00307         AddToToken( psContext, chNext );
00308         <font class="keywordflow">while</font>( (chNext = ReadChar(psContext)) != <font class="charliteral">'&lt;'</font> 
00309                &amp;&amp; chNext != <font class="charliteral">'\0'</font> )
00310             AddToToken( psContext, chNext );
00311         UnreadChar( psContext, chNext );
00312     }
00313     
00314 <font class="comment">/* -------------------------------------------------------------------- */</font>
00315 <font class="comment">/*      Collect a regular token terminated by white space, or           */</font>
00316 <font class="comment">/*      special character(s) like an equal sign.                        */</font>
00317 <font class="comment">/* -------------------------------------------------------------------- */</font>
00318     <font class="keywordflow">else</font>
00319     {
00320         psContext-&gt;eTokenType = TToken;
00321 
00322         <font class="comment">/* add the first character to the token regardless of what it is */</font>
00323         AddToToken( psContext, chNext );
00324 
00325         <font class="keywordflow">for</font>( chNext = ReadChar(psContext); 
00326              (chNext &gt;= <font class="charliteral">'A'</font> &amp;&amp; chNext &lt;= <font class="charliteral">'Z'</font>)
00327                  || (chNext &gt;= <font class="charliteral">'a'</font> &amp;&amp; chNext &lt;= <font class="charliteral">'z'</font>)
00328                  || chNext == <font class="charliteral">'_'</font>
00329                  || chNext == <font class="charliteral">':'</font>
00330                  || (chNext &gt;= <font class="charliteral">'0'</font> &amp;&amp; chNext &lt;= <font class="charliteral">'9'</font>);
00331              chNext = ReadChar(psContext) ) 
00332         {
00333             AddToToken( psContext, chNext );
00334         }
00335 
00336         UnreadChar(psContext, chNext);
00337     }
00338     
00339     <font class="keywordflow">return</font> psContext-&gt;eTokenType;
00340 }
00341     
00342 <font class="comment">/************************************************************************/</font>
00343 <font class="comment">/*                              PushNode()                              */</font>
00344 <font class="comment">/************************************************************************/</font>
00345 
00346 <font class="keyword">static</font> <font class="keywordtype">void</font> PushNode( ParseContext *psContext, CPLXMLNode *psNode )<font class="keyword"></font>
00347 <font class="keyword"></font>
00348 <font class="keyword"></font>{
00349     <font class="keywordflow">if</font>( psContext-&gt;nStackMaxSize &lt;= psContext-&gt;nStackSize )
00350     {
00351         psContext-&gt;nStackMaxSize += 10;
00352         psContext-&gt;papsStack = (CPLXMLNode **)
00353             <a class="code" href="cpl_conv_h.html#a5">CPLRealloc</a>(psContext-&gt;papsStack, 
00354                        <font class="keyword">sizeof</font>(CPLXMLNode*) * psContext-&gt;nStackMaxSize);
00355     }
00356 
00357     psContext-&gt;papsStack[psContext-&gt;nStackSize++] = psNode;
00358 }
00359     
00360 <font class="comment">/************************************************************************/</font>
00361 <font class="comment">/*                             AttachNode()                             */</font>
00362 <font class="comment">/*                                                                      */</font>
00363 <font class="comment">/*      Attach the passed node as a child of the current node.          */</font>
00364 <font class="comment">/*      Special handling exists for adding siblings to psFirst if       */</font>
00365 <font class="comment">/*      there is nothing on the stack.                                  */</font>
00366 <font class="comment">/************************************************************************/</font>
00367 
00368 <font class="keyword">static</font> <font class="keywordtype">void</font> AttachNode( ParseContext *psContext, CPLXMLNode *psNode )<font class="keyword"></font>
00369 <font class="keyword"></font>
00370 <font class="keyword"></font>{
00371     <font class="keywordflow">if</font>( psContext-&gt;psFirstNode == NULL )
00372         psContext-&gt;psFirstNode = psNode;
00373     <font class="keywordflow">else</font> <font class="keywordflow">if</font>( psContext-&gt;nStackSize == 0 )
00374     {
00375         CPLXMLNode *psSibling;
00376 
00377         psSibling = psContext-&gt;psFirstNode;
00378         <font class="keywordflow">while</font>( psSibling-&gt;psNext != NULL )
00379             psSibling = psSibling-&gt;psNext;
00380         psSibling-&gt;psNext = psNode;
00381     }
00382     <font class="keywordflow">else</font> <font class="keywordflow">if</font>( psContext-&gt;papsStack[psContext-&gt;nStackSize-1]-&gt;psChild == NULL )
00383     {
00384         psContext-&gt;papsStack[psContext-&gt;nStackSize-1]-&gt;psChild = psNode;
00385     }
00386     <font class="keywordflow">else</font>
00387     {
00388         CPLXMLNode *psSibling;
00389 
00390         psSibling = psContext-&gt;papsStack[psContext-&gt;nStackSize-1]-&gt;psChild;
00391         <font class="keywordflow">while</font>( psSibling-&gt;psNext != NULL )
00392             psSibling = psSibling-&gt;psNext;
00393         psSibling-&gt;psNext = psNode;
00394     }
00395 }
00396 
00397 <font class="comment">/************************************************************************/</font>
00398 <font class="comment">/*                         CPLParseXMLString()                          */</font>
00399 <font class="comment">/************************************************************************/</font>
00400 
00401 CPLXMLNode *CPLParseXMLString( <font class="keyword">const</font> <font class="keywordtype">char</font> *pszString )<font class="keyword"></font>
00402 <font class="keyword"></font>
00403 <font class="keyword"></font>{
00404     ParseContext sContext;
00405 
00406     <a class="code" href="cpl_error_h.html#a19">CPLErrorReset</a>();
00407 
00408 <font class="comment">/* -------------------------------------------------------------------- */</font>
00409 <font class="comment">/*      Initialize parse context.                                       */</font>
00410 <font class="comment">/* -------------------------------------------------------------------- */</font>
00411     sContext.pszInput = pszString;
00412     sContext.nInputOffset = 0;
00413     sContext.nInputLine = 0;
00414     sContext.bInElement = FALSE;
00415     sContext.pszToken = NULL;
00416     sContext.nTokenMaxSize = 0;
00417     sContext.nTokenSize = 0;
00418     sContext.eTokenType = TNone;
00419     sContext.nStackMaxSize = 0;
00420     sContext.nStackSize = 0;
00421     sContext.papsStack = NULL;
00422     sContext.psFirstNode = NULL;
00423 
00424     <font class="comment">/* ensure token is initialized */</font>
00425     AddToToken( &amp;sContext, <font class="charliteral">' '</font> );
00426     
00427 <font class="comment">/* ==================================================================== */</font>
00428 <font class="comment">/*      Loop reading tokens.                                            */</font>
00429 <font class="comment">/* ==================================================================== */</font>
00430     <font class="keywordflow">while</font>( ReadToken( &amp;sContext ) != TNone )
00431     {
00432 <font class="comment">/* -------------------------------------------------------------------- */</font>
00433 <font class="comment">/*      Create a new element.                                           */</font>
00434 <font class="comment">/* -------------------------------------------------------------------- */</font>
00435         <font class="keywordflow">if</font>( sContext.eTokenType == TOpen )
00436         {
00437             CPLXMLNode *psElement;
00438 
00439             <font class="keywordflow">if</font>( ReadToken(&amp;sContext) != TToken )
00440             {
00441                 <a class="code" href="cpl_error_h.html#a17">CPLError</a>( CE_Failure, CPLE_AppDefined, 
00442                           <font class="stringliteral">"Line %d: Didn't find element token after open angle bracket."</font>,
00443                           sContext.nInputLine );
00444                 <font class="keywordflow">break</font>;
00445             }
00446 
00447             <font class="keywordflow">if</font>( sContext.pszToken[0] != <font class="charliteral">'/'</font> )
00448             {
00449                 psElement = CPLCreateXMLNode( NULL, CXT_Element,
00450                                               sContext.pszToken );
00451                 AttachNode( &amp;sContext, psElement );
00452                 PushNode( &amp;sContext, psElement );
00453             }
00454             <font class="keywordflow">else</font> 
00455             {
00456                 <font class="keywordflow">if</font>( sContext.nStackSize == 0
00457                     || !EQUAL(sContext.pszToken+1,
00458                          sContext.papsStack[sContext.nStackSize-1]-&gt;pszValue) )
00459                 {
00460                     <a class="code" href="cpl_error_h.html#a17">CPLError</a>( CE_Failure, CPLE_AppDefined, 
00461                               <font class="stringliteral">"Line %d: &lt;%s&gt; doesn't have matching &lt;%s&gt;."</font>,
00462                               sContext.nInputLine,
00463                               sContext.pszToken, sContext.pszToken+1 );
00464                     <font class="keywordflow">break</font>;
00465                 }
00466                 <font class="keywordflow">else</font>
00467                 {
00468                     <font class="keywordflow">if</font>( ReadToken(&amp;sContext) != TClose )
00469                     {
00470                         <a class="code" href="cpl_error_h.html#a17">CPLError</a>( CE_Failure, CPLE_AppDefined, 
00471                                   <font class="stringliteral">"Line %d: Missing close angle bracket after &lt;%s."</font>,
00472                                   sContext.nInputLine,
00473                                   sContext.pszToken );
00474                         <font class="keywordflow">break</font>;
00475                     }
00476 
00477                     <font class="comment">/* pop element off stack */</font>
00478                     sContext.nStackSize--;
00479                 }
00480             }
00481         }
00482 
00483 <font class="comment">/* -------------------------------------------------------------------- */</font>
00484 <font class="comment">/*      Add an attribute to a token.                                    */</font>
00485 <font class="comment">/* -------------------------------------------------------------------- */</font>
00486         <font class="keywordflow">else</font> <font class="keywordflow">if</font>( sContext.eTokenType == TToken )
00487         {
00488             CPLXMLNode *psAttr;
00489 
00490             psAttr = CPLCreateXMLNode(NULL, CXT_Attribute, sContext.pszToken);
00491             AttachNode( &amp;sContext, psAttr );
00492             
00493             <font class="keywordflow">if</font>( ReadToken(&amp;sContext) != TEqual )
00494             {
00495                 <a class="code" href="cpl_error_h.html#a17">CPLError</a>( CE_Failure, CPLE_AppDefined, 
00496                           <font class="stringliteral">"Line %d: Didn't find expected '=' for attribute value."</font>,
00497                           sContext.nInputLine );
00498                 <font class="keywordflow">break</font>;
00499             }
00500 
00501             <font class="keywordflow">if</font>( ReadToken(&amp;sContext) != TString 
00502                 &amp;&amp; sContext.eTokenType != TToken )
00503             {
00504                 <a class="code" href="cpl_error_h.html#a17">CPLError</a>( CE_Failure, CPLE_AppDefined, 
00505                           <font class="stringliteral">"Line %d: Didn't find expected attribute value."</font>,
00506                           sContext.nInputLine );
00507                 <font class="keywordflow">break</font>;
00508             }
00509 
00510             CPLCreateXMLNode( psAttr, CXT_Text, sContext.pszToken );
00511         }
00512 
00513 <font class="comment">/* -------------------------------------------------------------------- */</font>
00514 <font class="comment">/*      Close the start section of an element.                          */</font>
00515 <font class="comment">/* -------------------------------------------------------------------- */</font>
00516         <font class="keywordflow">else</font> <font class="keywordflow">if</font>( sContext.eTokenType == TClose )
00517         {
00518             <font class="keywordflow">if</font>( sContext.nStackSize == 0 )
00519             {
00520                 <a class="code" href="cpl_error_h.html#a17">CPLError</a>( CE_Failure, CPLE_AppDefined, 
00521                           <font class="stringliteral">"Line %d: Found unbalanced '&gt;'."</font>,
00522                           sContext.nInputLine );
00523                 <font class="keywordflow">break</font>;
00524             }
00525         }
00526 
00527 <font class="comment">/* -------------------------------------------------------------------- */</font>
00528 <font class="comment">/*      Close the start section of an element, and pop it               */</font>
00529 <font class="comment">/*      immediately.                                                    */</font>
00530 <font class="comment">/* -------------------------------------------------------------------- */</font>
00531         <font class="keywordflow">else</font> <font class="keywordflow">if</font>( sContext.eTokenType == TSlashClose )
00532         {
00533             <font class="keywordflow">if</font>( sContext.nStackSize == 0 )
00534             {
00535                 <a class="code" href="cpl_error_h.html#a17">CPLError</a>( CE_Failure, CPLE_AppDefined, 
00536                           <font class="stringliteral">"Line %d: Found unbalanced '/&gt;'."</font>,
00537                           sContext.nInputLine );
00538                 <font class="keywordflow">break</font>;
00539             }
00540 
00541             sContext.nStackSize--;
00542         }
00543 
00544 <font class="comment">/* -------------------------------------------------------------------- */</font>
00545 <font class="comment">/*      Close the start section of a &lt;?...?&gt; element, and pop it        */</font>
00546 <font class="comment">/*      immediately.                                                    */</font>
00547 <font class="comment">/* -------------------------------------------------------------------- */</font>
00548         <font class="keywordflow">else</font> <font class="keywordflow">if</font>( sContext.eTokenType == TQuestionClose )
00549         {
00550             <font class="keywordflow">if</font>( sContext.nStackSize == 0 )
00551             {
00552                 <a class="code" href="cpl_error_h.html#a17">CPLError</a>( CE_Failure, CPLE_AppDefined, 
00553                           <font class="stringliteral">"Line %d: Found unbalanced '?&gt;'."</font>,
00554                           sContext.nInputLine );
00555                 <font class="keywordflow">break</font>;
00556             }
00557             <font class="keywordflow">else</font> <font class="keywordflow">if</font>( sContext.papsStack[sContext.nStackSize-1]-&gt;pszValue[0] != <font class="charliteral">'?'</font> )
00558             {
00559                 <a class="code" href="cpl_error_h.html#a17">CPLError</a>( CE_Failure, CPLE_AppDefined, 
00560                           <font class="stringliteral">"Line %d: Found '?&gt;' without matching '&lt;?'."</font>,
00561                           sContext.nInputLine );
00562                 <font class="keywordflow">break</font>;
00563             }
00564 
00565             sContext.nStackSize--;
00566         }
00567 
00568 <font class="comment">/* -------------------------------------------------------------------- */</font>
00569 <font class="comment">/*      Handle comments.  They are returned as a whole token with the     */</font>
00570 <font class="comment">/*      prefix and postfix omitted.  No processing of white space       */</font>
00571 <font class="comment">/*      will be done.                                                   */</font>
00572 <font class="comment">/* -------------------------------------------------------------------- */</font>
00573         <font class="keywordflow">else</font> <font class="keywordflow">if</font>( sContext.eTokenType == TComment )
00574         {
00575             CPLXMLNode *psValue;
00576 
00577             psValue = CPLCreateXMLNode(NULL, CXT_Comment, sContext.pszToken);
00578             AttachNode( &amp;sContext, psValue );
00579         }
00580 
00581 <font class="comment">/* -------------------------------------------------------------------- */</font>
00582 <font class="comment">/*      Add a text value node as a child of the current element.        */</font>
00583 <font class="comment">/* -------------------------------------------------------------------- */</font>
00584         <font class="keywordflow">else</font> <font class="keywordflow">if</font>( sContext.eTokenType == TString &amp;&amp; !sContext.bInElement )
00585         {
00586             CPLXMLNode *psValue;
00587 
00588             psValue = CPLCreateXMLNode(NULL, CXT_Text, sContext.pszToken);
00589             AttachNode( &amp;sContext, psValue );
00590         }
00591 <font class="comment">/* -------------------------------------------------------------------- */</font>
00592 <font class="comment">/*      Anything else is an error.                                      */</font>
00593 <font class="comment">/* -------------------------------------------------------------------- */</font>
00594         <font class="keywordflow">else</font>
00595         {
00596             <a class="code" href="cpl_error_h.html#a17">CPLError</a>( CE_Failure, CPLE_AppDefined, 
00597                       <font class="stringliteral">"Parse error at line %d, unexpected token:%s\n"</font>, 
00598                       sContext.nInputLine, sContext.pszToken );
00599             <font class="keywordflow">break</font>;
00600         }
00601     }
00602 
00603 <font class="comment">/* -------------------------------------------------------------------- */</font>
00604 <font class="comment">/*      Did we pop all the way out of our stack?                        */</font>
00605 <font class="comment">/* -------------------------------------------------------------------- */</font>
00606     <font class="keywordflow">if</font>( <a class="code" href="cpl_error_h.html#a21">CPLGetLastErrorType</a>() == CE_None &amp;&amp; sContext.nStackSize != 0 )
00607     {
00608         <a class="code" href="cpl_error_h.html#a17">CPLError</a>( CE_Failure, CPLE_AppDefined, 
00609                   <font class="stringliteral">"Parse error at EOF, not all elements have been closed,\n"</font>
00610                   <font class="stringliteral">"starting with %s\n"</font>,
00611                   sContext.papsStack[sContext.nStackSize-1]-&gt;pszValue );
00612     }
00613 
00614 <font class="comment">/* -------------------------------------------------------------------- */</font>
00615 <font class="comment">/*      Cleanup                                                         */</font>
00616 <font class="comment">/* -------------------------------------------------------------------- */</font>
00617     CPLFree( sContext.pszToken );
00618     <font class="keywordflow">if</font>( sContext.papsStack != NULL )
00619         CPLFree( sContext.papsStack );
00620 
00621     <font class="keywordflow">if</font>( <a class="code" href="cpl_error_h.html#a21">CPLGetLastErrorType</a>() != CE_None )
00622     {
00623         CPLDestroyXMLNode( sContext.psFirstNode );
00624         sContext.psFirstNode = NULL;
00625     }
00626 
00627     <font class="keywordflow">return</font> sContext.psFirstNode;
00628 }
00629 
00630 <font class="comment">/************************************************************************/</font>
00631 <font class="comment">/*                            _GrowBuffer()                             */</font>
00632 <font class="comment">/************************************************************************/</font>
00633 
00634 <font class="keyword">static</font> <font class="keywordtype">void</font> _GrowBuffer( <font class="keywordtype">unsigned</font> <font class="keywordtype">int</font> nNeeded, 
00635                          <font class="keywordtype">char</font> **ppszText, <font class="keywordtype">unsigned</font> <font class="keywordtype">int</font> *pnMaxLength )<font class="keyword"></font>
00636 <font class="keyword"></font>
00637 <font class="keyword"></font>{
00638     <font class="keywordflow">if</font>( nNeeded+1 &gt;= *pnMaxLength )
00639     {
00640         *pnMaxLength = MAX(*pnMaxLength * 2,nNeeded+1);
00641         *ppszText = (<font class="keywordtype">char</font> *) <a class="code" href="cpl_conv_h.html#a5">CPLRealloc</a>(*ppszText, *pnMaxLength);
00642     }
00643 }
00644 
00645 <font class="comment">/************************************************************************/</font>
00646 <font class="comment">/*                        CPLSerializeXMLNode()                         */</font>
00647 <font class="comment">/************************************************************************/</font>
00648 
00649 <font class="keyword">static</font> <font class="keywordtype">void</font>
00650 CPLSerializeXMLNode( CPLXMLNode *psNode, <font class="keywordtype">int</font> nIndent, 
00651                      <font class="keywordtype">char</font> **ppszText, <font class="keywordtype">unsigned</font> <font class="keywordtype">int</font> *pnLength, 
00652                      <font class="keywordtype">unsigned</font> <font class="keywordtype">int</font> *pnMaxLength )<font class="keyword"></font>
00653 <font class="keyword"></font>
00654 <font class="keyword"></font>{
00655     <font class="keywordflow">if</font>( psNode == NULL )
00656         <font class="keywordflow">return</font>;
00657     
00658 <font class="comment">/* -------------------------------------------------------------------- */</font>
00659 <font class="comment">/*      Ensure the buffer is plenty large to hold this additional       */</font>
00660 <font class="comment">/*      string.                                                         */</font>
00661 <font class="comment">/* -------------------------------------------------------------------- */</font>
00662     *pnLength += strlen(*ppszText + *pnLength);
00663     <font class="keywordflow">if</font>(strlen(psNode-&gt;pszValue) + *pnLength + 40 + nIndent &gt; *pnMaxLength)
00664         _GrowBuffer( strlen(psNode-&gt;pszValue) + *pnLength + 40 + nIndent, 
00665                      ppszText, pnMaxLength );
00666     
00667 <font class="comment">/* -------------------------------------------------------------------- */</font>
00668 <font class="comment">/*      Text is just directly emitted.                                  */</font>
00669 <font class="comment">/* -------------------------------------------------------------------- */</font>
00670     <font class="keywordflow">if</font>( psNode-&gt;eType == CXT_Text )
00671     {
00672         CPLAssert( psNode-&gt;psChild == NULL );
00673 
00674         strcat( *ppszText + *pnLength, psNode-&gt;pszValue );
00675     }
00676 
00677 <font class="comment">/* -------------------------------------------------------------------- */</font>
00678 <font class="comment">/*      Attributes require a little formatting.                         */</font>
00679 <font class="comment">/* -------------------------------------------------------------------- */</font>
00680     <font class="keywordflow">else</font> <font class="keywordflow">if</font>( psNode-&gt;eType == CXT_Attribute )
00681     {
00682         CPLAssert( psNode-&gt;psChild != NULL 
00683                    &amp;&amp; psNode-&gt;psChild-&gt;eType == CXT_Text );
00684 
00685         sprintf( *ppszText + *pnLength, <font class="stringliteral">" %s=\""</font>, psNode-&gt;pszValue );
00686         CPLSerializeXMLNode( psNode-&gt;psChild, 0, ppszText, 
00687                              pnLength, pnMaxLength );
00688         strcat( *ppszText + *pnLength, <font class="stringliteral">"\""</font> );
00689     }
00690 
00691 <font class="comment">/* -------------------------------------------------------------------- */</font>
00692 <font class="comment">/*      Attributes require a little formatting.                         */</font>
00693 <font class="comment">/* -------------------------------------------------------------------- */</font>
00694     <font class="keywordflow">else</font> <font class="keywordflow">if</font>( psNode-&gt;eType == CXT_Comment )
00695     {
00696         <font class="keywordtype">int</font>     i;
00697 
00698         CPLAssert( psNode-&gt;psChild == NULL );
00699 
00700         <font class="keywordflow">for</font>( i = 0; i &lt; nIndent; i++ )
00701             (*ppszText)[(*pnLength)++] = <font class="charliteral">' '</font>;
00702 
00703         sprintf( *ppszText + *pnLength, <font class="stringliteral">"&lt;!--%s--&gt;\n"</font>, 
00704                  psNode-&gt;pszValue );
00705     }
00706 
00707 <font class="comment">/* -------------------------------------------------------------------- */</font>
00708 <font class="comment">/*      Elements actually have to deal with general children, and       */</font>
00709 <font class="comment">/*      various formatting issues.                                      */</font>
00710 <font class="comment">/* -------------------------------------------------------------------- */</font>
00711     <font class="keywordflow">else</font> <font class="keywordflow">if</font>( psNode-&gt;eType == CXT_Element )
00712     {
00713         CPLXMLNode      *psChild = psNode-&gt;psChild;
00714         <font class="keywordtype">char</font> *pszIndent;
00715         
00716         pszIndent =  (<font class="keywordtype">char</font> *) <a class="code" href="cpl_conv_h.html#a4">CPLCalloc</a>(nIndent + 1,1);
00717         memset(pszIndent, <font class="charliteral">' '</font>, nIndent );
00718 
00719         strcat( *ppszText + *pnLength, pszIndent );
00720         *pnLength += nIndent;
00721         sprintf( *ppszText + *pnLength, <font class="stringliteral">"&lt;%s"</font>, psNode-&gt;pszValue );
00722         
00723         <font class="keywordflow">while</font>( psChild != NULL &amp;&amp; psChild-&gt;eType == CXT_Attribute )
00724         {
00725             CPLSerializeXMLNode( psChild, 0, ppszText, pnLength, 
00726                                  pnMaxLength );
00727             psChild = psChild-&gt;psNext;
00728         }
00729         
00730         <font class="keywordflow">if</font>( psChild == NULL )
00731         {
00732             <font class="keywordflow">if</font>( psNode-&gt;pszValue[0] == <font class="charliteral">'?'</font> )
00733                 strcat( *ppszText + *pnLength, <font class="stringliteral">"?&gt;\n"</font> );
00734             <font class="keywordflow">else</font>
00735                 strcat( *ppszText + *pnLength, <font class="stringliteral">"/&gt;\n"</font> );
00736         }
00737         <font class="keywordflow">else</font>
00738         {
00739             <font class="keywordtype">int</font>         bJustText = TRUE;
00740 
00741             strcat( *ppszText + *pnLength, <font class="stringliteral">"&gt;"</font> );
00742 
00743             <font class="keywordflow">while</font>( psChild != NULL )
00744             {
00745                 <font class="keywordflow">if</font>( psChild-&gt;eType != CXT_Text &amp;&amp; bJustText )
00746                 {
00747                     bJustText = FALSE;
00748                     strcat( *ppszText + *pnLength, <font class="stringliteral">"\n"</font> );
00749                 }
00750 
00751                 CPLSerializeXMLNode( psChild, nIndent + 2, ppszText, pnLength, 
00752                                      pnMaxLength );
00753                 psChild = psChild-&gt;psNext;
00754             }
00755 
00756             <font class="keywordflow">if</font>( strlen(psNode-&gt;pszValue)+*pnLength+40+nIndent &gt; *pnMaxLength)
00757                 _GrowBuffer( strlen(psNode-&gt;pszValue)+*pnLength+40+nIndent, 
00758                              ppszText, pnMaxLength );
00759 
00760             <font class="keywordflow">if</font>( !bJustText )
00761                 strcat( *ppszText + *pnLength, pszIndent );
00762 
00763             *pnLength += strlen(*ppszText + *pnLength);
00764             sprintf( *ppszText + *pnLength, <font class="stringliteral">"&lt;/%s&gt;\n"</font>, psNode-&gt;pszValue );
00765         }
00766 
00767         CPLFree( pszIndent );
00768     }
00769 }
00770                                 
00771 <font class="comment">/************************************************************************/</font>
00772 <font class="comment">/*                        CPLSerializeXMLTree()                         */</font>
00773 <font class="comment">/************************************************************************/</font>
00774 
00775 <font class="keywordtype">char</font> *CPLSerializeXMLTree( CPLXMLNode *psNode )<font class="keyword"></font>
00776 <font class="keyword"></font>
00777 <font class="keyword"></font>{
00778     <font class="keywordtype">unsigned</font> <font class="keywordtype">int</font> nMaxLength = 10000, nLength = 0;
00779     <font class="keywordtype">char</font> *pszText = NULL;
00780     CPLXMLNode *psThis;
00781 
00782     pszText = (<font class="keywordtype">char</font> *) <a class="code" href="cpl_conv_h.html#a3">CPLMalloc</a>(nMaxLength);
00783     pszText[0] = <font class="charliteral">'\0'</font>;
00784 
00785     <font class="keywordflow">for</font>( psThis = psNode; psThis != NULL; psThis = psThis-&gt;psNext )
00786         CPLSerializeXMLNode( psThis, 0, &amp;pszText, &amp;nLength, &amp;nMaxLength );
00787 
00788     <font class="keywordflow">return</font> pszText;
00789 }
00790 
00791 <font class="comment">/************************************************************************/</font>
00792 <font class="comment">/*                          CPLCreateXMLNode()                          */</font>
00793 <font class="comment">/************************************************************************/</font>
00794 
00795 CPLXMLNode *CPLCreateXMLNode( CPLXMLNode *poParent, CPLXMLNodeType eType, 
00796                               <font class="keyword">const</font> <font class="keywordtype">char</font> *pszText )<font class="keyword"></font>
00797 <font class="keyword"></font>
00798 <font class="keyword"></font>{
00799     CPLXMLNode  *psNode;
00800 
00801 <font class="comment">/* -------------------------------------------------------------------- */</font>
00802 <font class="comment">/*      Create new node.                                                */</font>
00803 <font class="comment">/* -------------------------------------------------------------------- */</font>
00804     psNode = (CPLXMLNode *) <a class="code" href="cpl_conv_h.html#a4">CPLCalloc</a>(<font class="keyword">sizeof</font>(CPLXMLNode),1);
00805     
00806     psNode-&gt;eType = eType;
00807     psNode-&gt;pszValue = <a class="code" href="cpl_conv_h.html#a6">CPLStrdup</a>( pszText );
00808 
00809 <font class="comment">/* -------------------------------------------------------------------- */</font>
00810 <font class="comment">/*      Attach to parent, if provided.                                  */</font>
00811 <font class="comment">/* -------------------------------------------------------------------- */</font>
00812     <font class="keywordflow">if</font>( poParent != NULL )
00813     {
00814         <font class="keywordflow">if</font>( poParent-&gt;psChild == NULL )
00815             poParent-&gt;psChild = psNode;
00816         <font class="keywordflow">else</font>
00817         {
00818             CPLXMLNode  *psLink = poParent-&gt;psChild;
00819 
00820             <font class="keywordflow">while</font>( psLink-&gt;psNext != NULL )
00821                 psLink = psLink-&gt;psNext;
00822 
00823             psLink-&gt;psNext = psNode;
00824         }
00825     }
00826     
00827     <font class="keywordflow">return</font> psNode;
00828 }
00829 
00830 <font class="comment">/************************************************************************/</font>
00831 <font class="comment">/*                         CPLDestroyXMLNode()                          */</font>
00832 <font class="comment">/************************************************************************/</font>
00833 
00834 <font class="keywordtype">void</font> CPLDestroyXMLNode( CPLXMLNode *psNode )<font class="keyword"></font>
00835 <font class="keyword"></font>
00836 <font class="keyword"></font>{
00837     <font class="keywordflow">if</font>( psNode-&gt;psChild != NULL )
00838         CPLDestroyXMLNode( psNode-&gt;psChild );
00839     
00840     <font class="keywordflow">if</font>( psNode-&gt;psNext != NULL )
00841         CPLDestroyXMLNode( psNode-&gt;psNext );
00842 
00843     CPLFree( psNode-&gt;pszValue );
00844     CPLFree( psNode );
00845 }
00846 
00847 <font class="comment">/************************************************************************/</font>
00848 <font class="comment">/*                           CPLGetXMLNode()                            */</font>
00849 <font class="comment">/************************************************************************/</font>
00850 
00851 CPLXMLNode *CPLGetXMLNode( CPLXMLNode *poRoot, <font class="keyword">const</font> <font class="keywordtype">char</font> *pszPath )<font class="keyword"></font>
00852 <font class="keyword"></font>
00853 <font class="keyword"></font>{
00854     <font class="keywordtype">char</font>        **papszTokens;
00855     <font class="keywordtype">int</font>         iToken = 0;
00856 
00857     papszTokens = CSLTokenizeStringComplex( pszPath, <font class="stringliteral">"."</font>, FALSE, FALSE );
00858 
00859     <font class="keywordflow">while</font>( papszTokens[iToken] != NULL &amp;&amp; poRoot != NULL )
00860     {
00861         CPLXMLNode *psChild;
00862 
00863         <font class="keywordflow">for</font>( psChild = poRoot-&gt;psChild; psChild != NULL; 
00864              psChild = psChild-&gt;psNext ) 
00865         {
00866             <font class="keywordflow">if</font>( psChild-&gt;eType != CXT_Text 
00867                 &amp;&amp; EQUAL(papszTokens[iToken],psChild-&gt;pszValue) )
00868                 <font class="keywordflow">break</font>;
00869         }
00870 
00871         <font class="keywordflow">if</font>( psChild == NULL )
00872         {
00873             poRoot = NULL;
00874             <font class="keywordflow">break</font>;
00875         }
00876 
00877         poRoot = psChild;
00878         iToken++;
00879     }
00880 
00881     CSLDestroy( papszTokens );
00882     <font class="keywordflow">return</font> poRoot;
00883 }
00884 
00885 <font class="comment">/************************************************************************/</font>
00886 <font class="comment">/*                           CPLGetXMLValue()                           */</font>
00887 <font class="comment">/************************************************************************/</font>
00888 
00889 <font class="keyword">const</font> <font class="keywordtype">char</font> *CPLGetXMLValue( CPLXMLNode *poRoot, <font class="keyword">const</font> <font class="keywordtype">char</font> *pszPath, 
00890                             <font class="keyword">const</font> <font class="keywordtype">char</font> *pszDefault )<font class="keyword"></font>
00891 <font class="keyword"></font>
00892 <font class="keyword"></font>{
00893     CPLXMLNode  *psTarget;
00894 
00895     psTarget = CPLGetXMLNode( poRoot, pszPath );
00896     <font class="keywordflow">if</font>( psTarget == NULL )
00897         <font class="keywordflow">return</font> pszDefault;
00898 
00899     <font class="keywordflow">if</font>( psTarget-&gt;eType == CXT_Attribute )
00900     {
00901         CPLAssert( psTarget-&gt;psChild != NULL 
00902                    &amp;&amp; psTarget-&gt;psChild-&gt;eType == CXT_Text );
00903 
00904         <font class="keywordflow">return</font> psTarget-&gt;psChild-&gt;pszValue;
00905     }
00906 
00907     <font class="keywordflow">if</font>( psTarget-&gt;eType == CXT_Element 
00908         &amp;&amp; psTarget-&gt;psChild != NULL 
00909         &amp;&amp; psTarget-&gt;psChild-&gt;eType == CXT_Text
00910         &amp;&amp; psTarget-&gt;psChild-&gt;psNext == NULL )
00911     {
00912         <font class="keywordflow">return</font> psTarget-&gt;psChild-&gt;pszValue;
00913     }
00914         
00915     <font class="keywordflow">return</font> pszDefault;
00916 }
00917 
00918 <font class="comment">/************************************************************************/</font>
00919 <font class="comment">/*                           CPLAddXMLChild()                           */</font>
00920 <font class="comment">/*                                                                      */</font>
00921 <font class="comment">/*      Add a node as a child of another.                               */</font>
00922 <font class="comment">/************************************************************************/</font>
00923 
00924 <font class="keywordtype">void</font> CPLAddXMLChild( CPLXMLNode *psParent, CPLXMLNode *psChild )<font class="keyword"></font>
00925 <font class="keyword"></font>
00926 <font class="keyword"></font>{
00927     CPLXMLNode *psSib;
00928 
00929     CPLAssert( psChild-&gt;psNext == NULL );
00930     psChild-&gt;psNext = NULL;
00931 
00932     <font class="keywordflow">if</font>( psParent-&gt;psChild == NULL )
00933     {
00934         psParent-&gt;psChild = psChild;
00935         <font class="keywordflow">return</font>;
00936     }
00937 
00938     <font class="keywordflow">for</font>( psSib = psParent-&gt;psChild; 
00939          psSib-&gt;psNext != NULL; 
00940          psSib = psSib-&gt;psNext ) {}
00941 
00942     psSib-&gt;psNext = psChild;
00943 }
00944 
00945 <font class="comment">/************************************************************************/</font>
00946 <font class="comment">/*                    CPLCreateXMLElementAndValue()                     */</font>
00947 <font class="comment">/************************************************************************/</font>
00948 
00949 CPLXMLNode *CPLCreateXMLElementAndValue( CPLXMLNode *psParent, 
00950                                          <font class="keyword">const</font> <font class="keywordtype">char</font> *pszName, 
00951                                          <font class="keyword">const</font> <font class="keywordtype">char</font> *pszValue )<font class="keyword"></font>
00952 <font class="keyword"></font>
00953 <font class="keyword"></font>{
00954     <font class="keywordflow">return</font> CPLCreateXMLNode( 
00955         CPLCreateXMLNode( psParent, CXT_Element, pszName ),
00956         CXT_Text, pszValue );
00957 }
00958 
</div></pre><hr><address><small>Generated at Thu Mar 28 09:47:28 2002 for GDAL by
<a href="http://www.stack.nl/~dimitri/doxygen/index.html">
<img src="doxygen.gif" alt="doxygen" align="middle" border=0 
width=110 height=53></a>1.2.3-20001105 written by <a href="mailto:dimitri@stack.nl">Dimitri van Heesch</a>,
 &copy;&nbsp;1997-2000</small></address>
</body>
</html>