<!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_string.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:28 2002 --> <center> <a class="qindex" href="index.html">Main Page</a> <a class="qindex" href="hierarchy.html">Class Hierarchy</a> <a class="qindex" href="annotated.html">Compound List</a> <a class="qindex" href="files.html">File List</a> <a class="qindex" href="functions.html">Compound Members</a> <a class="qindex" href="globals.html">File Members</a> <a class="qindex" href="pages.html">Related Pages</a> </center> <hr><h1>cpl_string.cpp</h1><div class="fragment"><pre>00001 <font class="comment">/**********************************************************************</font> 00002 <font class="comment"> * $Id: cpl_string_cpp-source.html,v 1.10 2002/04/16 13:11:47 warmerda Exp $</font> 00003 <font class="comment"> *</font> 00004 <font class="comment"> * Name: cpl_string.cpp</font> 00005 <font class="comment"> * Project: CPL - Common Portability Library</font> 00006 <font class="comment"> * Purpose: String and Stringlist manipulation functions.</font> 00007 <font class="comment"> * Author: Daniel Morissette, danmo@videotron.ca</font> 00008 <font class="comment"> *</font> 00009 <font class="comment"> **********************************************************************</font> 00010 <font class="comment"> * Copyright (c) 1998, Daniel Morissette</font> 00011 <font class="comment"> *</font> 00012 <font class="comment"> * Permission is hereby granted, free of charge, to any person obtaining a</font> 00013 <font class="comment"> * copy of this software and associated documentation files (the "Software"),</font> 00014 <font class="comment"> * to deal in the Software without restriction, including without limitation</font> 00015 <font class="comment"> * the rights to use, copy, modify, merge, publish, distribute, sublicense,</font> 00016 <font class="comment"> * and/or sell copies of the Software, and to permit persons to whom the</font> 00017 <font class="comment"> * Software is furnished to do so, subject to the following conditions:</font> 00018 <font class="comment"> * </font> 00019 <font class="comment"> * The above copyright notice and this permission notice shall be included</font> 00020 <font class="comment"> * in all copies or substantial portions of the Software.</font> 00021 <font class="comment"> * </font> 00022 <font class="comment"> * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR</font> 00023 <font class="comment"> * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,</font> 00024 <font class="comment"> * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL</font> 00025 <font class="comment"> * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER</font> 00026 <font class="comment"> * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING</font> 00027 <font class="comment"> * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER </font> 00028 <font class="comment"> * DEALINGS IN THE SOFTWARE.</font> 00029 <font class="comment"> **********************************************************************</font> 00030 <font class="comment"> *</font> 00031 <font class="comment"> * $Log: cpl_string_cpp-source.html,v $ 00031 <font class="comment"> * Revision 1.10 2002/04/16 13:11:47 warmerda 00031 <font class="comment"> * updated 00031 <font class="comment"> *</font> 00032 <font class="comment"> * Revision 1.20 2002/03/05 14:26:57 warmerda</font> 00033 <font class="comment"> * expanded tabs</font> 00034 <font class="comment"> *</font> 00035 <font class="comment"> * Revision 1.19 2002/01/16 03:59:27 warmerda</font> 00036 <font class="comment"> * added CPLTokenizeString2</font> 00037 <font class="comment"> *</font> 00038 <font class="comment"> * Revision 1.18 2001/12/11 22:40:26 warmerda</font> 00039 <font class="comment"> * cleanup CPLReadLine buffer in CSLLoad()</font> 00040 <font class="comment"> *</font> 00041 <font class="comment"> * Revision 1.17 2001/11/07 14:31:16 warmerda</font> 00042 <font class="comment"> * doc fix</font> 00043 <font class="comment"> *</font> 00044 <font class="comment"> * Revision 1.16 2001/07/18 04:00:49 warmerda</font> 00045 <font class="comment"> * added CPL_CVSID</font> 00046 <font class="comment"> *</font> 00047 <font class="comment"> * Revision 1.15 2001/01/19 21:16:41 warmerda</font> 00048 <font class="comment"> * expanded tabs</font> 00049 <font class="comment"> *</font> 00050 <font class="comment"> * Revision 1.14 2000/10/06 15:19:03 warmerda</font> 00051 <font class="comment"> * added CPLSetNameValueSeparator</font> 00052 <font class="comment"> *</font> 00053 <font class="comment"> * Revision 1.13 2000/08/22 17:47:50 warmerda</font> 00054 <font class="comment"> * Fixed declaration of gnCPLSPrintfBuffer.</font> 00055 <font class="comment"> *</font> 00056 <font class="comment"> * Revision 1.12 2000/08/18 21:20:54 svillene</font> 00057 <font class="comment"> * *** empty log message ***</font> 00058 <font class="comment"> *</font> 00059 <font class="comment"> * Revision 1.11 2000/03/30 05:38:48 warmerda</font> 00060 <font class="comment"> * added CPLParseNameValue</font> 00061 <font class="comment"> *</font> 00062 <font class="comment"> * Revision 1.10 1999/06/26 14:05:10 warmerda</font> 00063 <font class="comment"> * Added CSLFindString().</font> 00064 <font class="comment"> *</font> 00065 <font class="comment"> * Revision 1.9 1999/04/28 02:33:02 danmo</font> 00066 <font class="comment"> * CSLInsertStrings(): make sure papszStrList is NULL-terminated properly</font> 00067 <font class="comment"> *</font> 00068 <font class="comment"> * Revision 1.8 1999/03/12 21:19:49 danmo</font> 00069 <font class="comment"> * Fixed TokenizeStringComplex() vs strings ending with empty token,</font> 00070 <font class="comment"> * and fixed a problem with CSLAdd/SetNameValue() vs empty string list.</font> 00071 <font class="comment"> *</font> 00072 <font class="comment"> * Revision 1.7 1999/03/09 21:29:57 warmerda</font> 00073 <font class="comment"> * Added backslash escaping within string constants for tokenize function.</font> 00074 <font class="comment"> *</font> 00075 <font class="comment"> * Revision 1.6 1999/02/25 04:40:46 danmo</font> 00076 <font class="comment"> * Modif. CSLLoad() to use CPLReadLine() (better handling of newlines)</font> 00077 <font class="comment"> *</font> 00078 <font class="comment"> * Revision 1.5 1999/02/17 01:41:58 warmerda</font> 00079 <font class="comment"> * Added CSLGetField</font> 00080 <font class="comment"> *</font> 00081 <font class="comment"> * Revision 1.4 1998/12/15 19:01:40 warmerda</font> 00082 <font class="comment"> * *** empty log message ***</font> 00083 <font class="comment"> *</font> 00084 <font class="comment"> * Revision 1.3 1998/12/05 23:04:21 warmerda</font> 00085 <font class="comment"> * Use EQUALN() instead of strincmp() which doesn't exist on Linux.</font> 00086 <font class="comment"> *</font> 00087 <font class="comment"> * Revision 1.2 1998/12/04 21:40:42 danmo</font> 00088 <font class="comment"> * Added more Name=Value manipulation fuctions</font> 00089 <font class="comment"> *</font> 00090 <font class="comment"> * Revision 1.1 1998/12/03 18:26:02 warmerda</font> 00091 <font class="comment"> * New</font> 00092 <font class="comment"> *</font> 00093 <font class="comment"> **********************************************************************/</font> 00094 00095 <font class="preprocessor">#include "cpl_string.h"</font> 00096 <font class="preprocessor">#include "<a class="code" href="cpl_vsi_h.html">cpl_vsi.h</a>"</font> 00097 00098 CPL_CVSID(<font class="stringliteral">"$Id: cpl_string_cpp-source.html,v 1.10 2002/04/16 13:11:47 warmerda Exp $"</font>); 00099 00100 <font class="comment">/*=====================================================================</font> 00101 <font class="comment"> StringList manipulation functions.</font> 00102 <font class="comment"> =====================================================================*/</font> 00103 00104 <font class="comment">/**********************************************************************</font> 00105 <font class="comment"> * CSLAddString()</font> 00106 <font class="comment"> *</font> 00107 <font class="comment"> * Append a string to a StringList and return a pointer to the modified</font> 00108 <font class="comment"> * StringList.</font> 00109 <font class="comment"> * If the input StringList is NULL, then a new StringList is created.</font> 00110 <font class="comment"> **********************************************************************/</font> 00111 <font class="keywordtype">char</font> **CSLAddString(<font class="keywordtype">char</font> **papszStrList, <font class="keyword">const</font> <font class="keywordtype">char</font> *pszNewString)<font class="keyword"></font> 00112 <font class="keyword"></font>{ 00113 <font class="keywordtype">int</font> nItems=0; 00114 00115 <font class="keywordflow">if</font> (pszNewString == NULL) 00116 <font class="keywordflow">return</font> papszStrList; <font class="comment">/* Nothing to do!*/</font> 00117 00118 <font class="comment">/* Allocate room for the new string */</font> 00119 <font class="keywordflow">if</font> (papszStrList == NULL) 00120 papszStrList = (<font class="keywordtype">char</font>**) <a class="code" href="cpl_conv_h.html#a4">CPLCalloc</a>(2,<font class="keyword">sizeof</font>(<font class="keywordtype">char</font>*)); 00121 <font class="keywordflow">else</font> 00122 { 00123 nItems = CSLCount(papszStrList); 00124 papszStrList = (<font class="keywordtype">char</font>**)<a class="code" href="cpl_conv_h.html#a5">CPLRealloc</a>(papszStrList, 00125 (nItems+2)*<font class="keyword">sizeof</font>(<font class="keywordtype">char</font>*)); 00126 } 00127 00128 <font class="comment">/* Copy the string in the list */</font> 00129 papszStrList[nItems] = <a class="code" href="cpl_conv_h.html#a6">CPLStrdup</a>(pszNewString); 00130 papszStrList[nItems+1] = NULL; 00131 00132 <font class="keywordflow">return</font> papszStrList; 00133 } 00134 00135 <font class="comment">/**********************************************************************</font> 00136 <font class="comment"> * CSLCount()</font> 00137 <font class="comment"> *</font> 00138 <font class="comment"> * Return the number of lines in a Stringlist.</font> 00139 <font class="comment"> **********************************************************************/</font> 00140 <font class="keywordtype">int</font> CSLCount(<font class="keywordtype">char</font> **papszStrList)<font class="keyword"></font> 00141 <font class="keyword"></font>{ 00142 <font class="keywordtype">int</font> nItems=0; 00143 00144 <font class="keywordflow">if</font> (papszStrList) 00145 { 00146 <font class="keywordflow">while</font>(*papszStrList != NULL) 00147 { 00148 nItems++; 00149 papszStrList++; 00150 } 00151 } 00152 00153 <font class="keywordflow">return</font> nItems; 00154 } 00155 00156 00157 <font class="comment">/************************************************************************/</font> 00158 <font class="comment">/* CSLGetField() */</font> 00159 <font class="comment">/* */</font> 00160 <font class="comment">/* Fetches the indicated field, being careful not to crash if */</font> 00161 <font class="comment">/* the field doesn't exist within this string list. The */</font> 00162 <font class="comment">/* returned pointer should not be freed, and doesn't */</font> 00163 <font class="comment">/* necessarily last long. */</font> 00164 <font class="comment">/************************************************************************/</font> 00165 00166 <font class="keyword">const</font> <font class="keywordtype">char</font> * CSLGetField( <font class="keywordtype">char</font> ** papszStrList, <font class="keywordtype">int</font> iField )<font class="keyword"></font> 00167 <font class="keyword"></font> 00168 <font class="keyword"></font>{ 00169 <font class="keywordtype">int</font> i; 00170 00171 <font class="keywordflow">if</font>( papszStrList == NULL || iField < 0 ) 00172 <font class="keywordflow">return</font>( <font class="stringliteral">""</font> ); 00173 00174 <font class="keywordflow">for</font>( i = 0; i < iField+1; i++ ) 00175 { 00176 <font class="keywordflow">if</font>( papszStrList[i] == NULL ) 00177 <font class="keywordflow">return</font> <font class="stringliteral">""</font>; 00178 } 00179 00180 <font class="keywordflow">return</font>( papszStrList[iField] ); 00181 } 00182 00183 <font class="comment">/**********************************************************************</font> 00184 <font class="comment"> * CSLDestroy()</font> 00185 <font class="comment"> *</font> 00186 <font class="comment"> * Free all memory used by a StringList.</font> 00187 <font class="comment"> **********************************************************************/</font> 00188 <font class="keywordtype">void</font> CSLDestroy(<font class="keywordtype">char</font> **papszStrList)<font class="keyword"></font> 00189 <font class="keyword"></font>{ 00190 <font class="keywordtype">char</font> **papszPtr; 00191 00192 <font class="keywordflow">if</font> (papszStrList) 00193 { 00194 papszPtr = papszStrList; 00195 <font class="keywordflow">while</font>(*papszPtr != NULL) 00196 { 00197 CPLFree(*papszPtr); 00198 papszPtr++; 00199 } 00200 00201 CPLFree(papszStrList); 00202 } 00203 } 00204 00205 00206 <font class="comment">/**********************************************************************</font> 00207 <font class="comment"> * CSLDuplicate()</font> 00208 <font class="comment"> *</font> 00209 <font class="comment"> * Allocate and return a copy of a StringList.</font> 00210 <font class="comment"> **********************************************************************/</font> 00211 <font class="keywordtype">char</font> **CSLDuplicate(<font class="keywordtype">char</font> **papszStrList)<font class="keyword"></font> 00212 <font class="keyword"></font>{ 00213 <font class="keywordtype">char</font> **papszNewList, **papszSrc, **papszDst; 00214 <font class="keywordtype">int</font> nLines; 00215 00216 nLines = CSLCount(papszStrList); 00217 00218 <font class="keywordflow">if</font> (nLines == 0) 00219 <font class="keywordflow">return</font> NULL; 00220 00221 papszNewList = (<font class="keywordtype">char</font> **)<a class="code" href="cpl_conv_h.html#a3">CPLMalloc</a>((nLines+1)*<font class="keyword">sizeof</font>(<font class="keywordtype">char</font>*)); 00222 papszSrc = papszStrList; 00223 papszDst = papszNewList; 00224 00225 <font class="keywordflow">while</font>(*papszSrc != NULL) 00226 { 00227 *papszDst = <a class="code" href="cpl_conv_h.html#a6">CPLStrdup</a>(*papszSrc); 00228 00229 papszSrc++; 00230 papszDst++; 00231 } 00232 *papszDst = NULL; 00233 00234 <font class="keywordflow">return</font> papszNewList; 00235 } 00236 00237 <font class="comment">/**********************************************************************</font> 00238 <font class="comment"> * CSLLoad()</font> 00239 <font class="comment"> *</font> 00240 <font class="comment"> * Load a test file into a stringlist.</font> 00241 <font class="comment"> *</font> 00242 <font class="comment"> * Lines are limited in length by the size fo the CPLReadLine() buffer.</font> 00243 <font class="comment"> **********************************************************************/</font> 00244 <font class="keywordtype">char</font> **CSLLoad(<font class="keyword">const</font> <font class="keywordtype">char</font> *pszFname)<font class="keyword"></font> 00245 <font class="keyword"></font>{ 00246 FILE *fp; 00247 <font class="keyword">const</font> <font class="keywordtype">char</font> *pszLine; 00248 <font class="keywordtype">char</font> **papszStrList=NULL; 00249 00250 fp = VSIFOpen(pszFname, <font class="stringliteral">"rt"</font>); 00251 00252 <font class="keywordflow">if</font> (fp) 00253 { 00254 <font class="keywordflow">while</font>(!VSIFEof(fp)) 00255 { 00256 <font class="keywordflow">if</font> ( (pszLine = <a class="code" href="cpl_conv_h.html#a7">CPLReadLine</a>(fp)) != NULL ) 00257 { 00258 papszStrList = CSLAddString(papszStrList, pszLine); 00259 } 00260 } 00261 00262 VSIFClose(fp); 00263 00264 <a class="code" href="cpl_conv_h.html#a7">CPLReadLine</a>( NULL ); 00265 } 00266 <font class="keywordflow">else</font> 00267 { 00268 <font class="comment">/* Unable to open file */</font> 00269 <a class="code" href="cpl_error_h.html#a17">CPLError</a>(CE_Failure, CPLE_OpenFailed, 00270 <font class="stringliteral">"CSLLoad(%s): %s"</font>, pszFname, strerror(errno)); 00271 } 00272 00273 <font class="keywordflow">return</font> papszStrList; 00274 } 00275 00276 <font class="comment">/**********************************************************************</font> 00277 <font class="comment"> * CSLSave()</font> 00278 <font class="comment"> *</font> 00279 <font class="comment"> * Write a stringlist to a text file.</font> 00280 <font class="comment"> *</font> 00281 <font class="comment"> * Returns the number of lines written, or 0 if the file could not </font> 00282 <font class="comment"> * be written.</font> 00283 <font class="comment"> **********************************************************************/</font> 00284 <font class="keywordtype">int</font> CSLSave(<font class="keywordtype">char</font> **papszStrList, <font class="keyword">const</font> <font class="keywordtype">char</font> *pszFname)<font class="keyword"></font> 00285 <font class="keyword"></font>{ 00286 FILE *fp; 00287 <font class="keywordtype">int</font> nLines=0; 00288 00289 <font class="keywordflow">if</font> (papszStrList) 00290 { 00291 <font class="keywordflow">if</font> ((fp = VSIFOpen(pszFname, <font class="stringliteral">"wt"</font>)) != NULL) 00292 { 00293 <font class="keywordflow">while</font>(*papszStrList != NULL) 00294 { 00295 <font class="keywordflow">if</font> (VSIFPuts(*papszStrList, fp) == EOF || 00296 VSIFPutc(<font class="charliteral">'\n'</font>, fp) == EOF) 00297 { 00298 <a class="code" href="cpl_error_h.html#a17">CPLError</a>(CE_Failure, CPLE_FileIO, 00299 <font class="stringliteral">"CSLSave(%s): %s"</font>, pszFname, 00300 strerror(errno)); 00301 <font class="keywordflow">break</font>; <font class="comment">/* A Problem happened... abort */</font> 00302 } 00303 00304 nLines++; 00305 papszStrList++; 00306 } 00307 00308 VSIFClose(fp); 00309 } 00310 <font class="keywordflow">else</font> 00311 { 00312 <font class="comment">/* Unable to open file */</font> 00313 <a class="code" href="cpl_error_h.html#a17">CPLError</a>(CE_Failure, CPLE_OpenFailed, 00314 <font class="stringliteral">"CSLSave(%s): %s"</font>, pszFname, strerror(errno)); 00315 } 00316 } 00317 00318 <font class="keywordflow">return</font> nLines; 00319 } 00320 00321 <font class="comment">/**********************************************************************</font> 00322 <font class="comment"> * CSLPrint()</font> 00323 <font class="comment"> *</font> 00324 <font class="comment"> * Print a StringList to fpOut. If fpOut==NULL, then output is sent</font> 00325 <font class="comment"> * to stdout.</font> 00326 <font class="comment"> *</font> 00327 <font class="comment"> * Returns the number of lines printed.</font> 00328 <font class="comment"> **********************************************************************/</font> 00329 <font class="keywordtype">int</font> CSLPrint(<font class="keywordtype">char</font> **papszStrList, FILE *fpOut)<font class="keyword"></font> 00330 <font class="keyword"></font>{ 00331 <font class="keywordtype">int</font> nLines=0; 00332 00333 <font class="keywordflow">if</font> (fpOut == NULL) 00334 fpOut = stdout; 00335 00336 <font class="keywordflow">if</font> (papszStrList) 00337 { 00338 <font class="keywordflow">while</font>(*papszStrList != NULL) 00339 { 00340 VSIFPrintf(fpOut, <font class="stringliteral">"%s\n"</font>, *papszStrList); 00341 nLines++; 00342 papszStrList++; 00343 } 00344 } 00345 00346 <font class="keywordflow">return</font> nLines; 00347 } 00348 00349 00350 <font class="comment">/**********************************************************************</font> 00351 <font class="comment"> * CSLInsertStrings()</font> 00352 <font class="comment"> *</font> 00353 <font class="comment"> * Copies the contents of a StringList inside another StringList </font> 00354 <font class="comment"> * before the specified line.</font> 00355 <font class="comment"> *</font> 00356 <font class="comment"> * nInsertAtLineNo is a 0-based line index before which the new strings</font> 00357 <font class="comment"> * should be inserted. If this value is -1 or is larger than the actual </font> 00358 <font class="comment"> * number of strings in the list then the strings are added at the end</font> 00359 <font class="comment"> * of the source StringList.</font> 00360 <font class="comment"> *</font> 00361 <font class="comment"> * Returns the modified StringList.</font> 00362 <font class="comment"> **********************************************************************/</font> 00363 <font class="keywordtype">char</font> **CSLInsertStrings(<font class="keywordtype">char</font> **papszStrList, <font class="keywordtype">int</font> nInsertAtLineNo, 00364 <font class="keywordtype">char</font> **papszNewLines)<font class="keyword"></font> 00365 <font class="keyword"></font>{ 00366 <font class="keywordtype">int</font> i, nSrcLines, nDstLines, nToInsert; 00367 <font class="keywordtype">char</font> **ppszSrc, **ppszDst; 00368 00369 <font class="keywordflow">if</font> (papszNewLines == NULL || 00370 ( nToInsert = CSLCount(papszNewLines) ) == 0) 00371 <font class="keywordflow">return</font> papszStrList; <font class="comment">/* Nothing to do!*/</font> 00372 00373 nSrcLines = CSLCount(papszStrList); 00374 nDstLines = nSrcLines + nToInsert; 00375 00376 <font class="comment">/* Allocate room for the new strings */</font> 00377 papszStrList = (<font class="keywordtype">char</font>**)<a class="code" href="cpl_conv_h.html#a5">CPLRealloc</a>(papszStrList, 00378 (nDstLines+1)*<font class="keyword">sizeof</font>(<font class="keywordtype">char</font>*)); 00379 00380 <font class="comment">/* Make sure the array is NULL-terminated... it may not be if</font> 00381 <font class="comment"> * papszStrList was NULL before Realloc()</font> 00382 <font class="comment"> */</font> 00383 papszStrList[nSrcLines] = NULL; 00384 00385 <font class="comment">/* Make some room in the original list at the specified location </font> 00386 <font class="comment"> * Note that we also have to move the NULL pointer at the end of</font> 00387 <font class="comment"> * the source StringList.</font> 00388 <font class="comment"> */</font> 00389 <font class="keywordflow">if</font> (nInsertAtLineNo == -1 || nInsertAtLineNo > nSrcLines) 00390 nInsertAtLineNo = nSrcLines; 00391 00392 ppszSrc = papszStrList + nSrcLines; 00393 ppszDst = papszStrList + nDstLines; 00394 00395 <font class="keywordflow">for</font> (i=nSrcLines; i>=nInsertAtLineNo; i--) 00396 { 00397 *ppszDst = *ppszSrc; 00398 ppszDst--; 00399 ppszSrc--; 00400 } 00401 00402 <font class="comment">/* Copy the strings to the list */</font> 00403 ppszSrc = papszNewLines; 00404 ppszDst = papszStrList + nInsertAtLineNo; 00405 00406 <font class="keywordflow">for</font> (; *ppszSrc != NULL; ppszSrc++, ppszDst++) 00407 { 00408 *ppszDst = <a class="code" href="cpl_conv_h.html#a6">CPLStrdup</a>(*ppszSrc); 00409 } 00410 00411 <font class="keywordflow">return</font> papszStrList; 00412 } 00413 00414 <font class="comment">/**********************************************************************</font> 00415 <font class="comment"> * CSLInsertString()</font> 00416 <font class="comment"> *</font> 00417 <font class="comment"> * Insert a string at a given line number inside a StringList </font> 00418 <font class="comment"> *</font> 00419 <font class="comment"> * nInsertAtLineNo is a 0-based line index before which the new string</font> 00420 <font class="comment"> * should be inserted. If this value is -1 or is larger than the actual </font> 00421 <font class="comment"> * number of strings in the list then the string is added at the end</font> 00422 <font class="comment"> * of the source StringList.</font> 00423 <font class="comment"> *</font> 00424 <font class="comment"> * Returns the modified StringList.</font> 00425 <font class="comment"> **********************************************************************/</font> 00426 <font class="keywordtype">char</font> **CSLInsertString(<font class="keywordtype">char</font> **papszStrList, <font class="keywordtype">int</font> nInsertAtLineNo, 00427 <font class="keywordtype">char</font> *pszNewLine)<font class="keyword"></font> 00428 <font class="keyword"></font>{ 00429 <font class="keywordtype">char</font> *apszList[2]; 00430 00431 <font class="comment">/* Create a temporary StringList and call CSLInsertStrings()</font> 00432 <font class="comment"> */</font> 00433 apszList[0] = pszNewLine; 00434 apszList[1] = NULL; 00435 00436 <font class="keywordflow">return</font> CSLInsertStrings(papszStrList, nInsertAtLineNo, apszList); 00437 } 00438 00439 00440 <font class="comment">/**********************************************************************</font> 00441 <font class="comment"> * CSLRemoveStrings()</font> 00442 <font class="comment"> *</font> 00443 <font class="comment"> * Remove strings inside a StringList </font> 00444 <font class="comment"> *</font> 00445 <font class="comment"> * nFirstLineToDelete is the 0-based line index of the first line to </font> 00446 <font class="comment"> * remove. If this value is -1 or is larger than the actual </font> 00447 <font class="comment"> * number of strings in list then the nNumToRemove last strings are</font> 00448 <font class="comment"> * removed.</font> 00449 <font class="comment"> *</font> 00450 <font class="comment"> * If ppapszRetStrings != NULL then the deleted strings won't be</font> 00451 <font class="comment"> * free'd, they will be stored in a new StringList and the pointer to</font> 00452 <font class="comment"> * this new list will be returned in *ppapszRetStrings.</font> 00453 <font class="comment"> *</font> 00454 <font class="comment"> * Returns the modified StringList.</font> 00455 <font class="comment"> **********************************************************************/</font> 00456 <font class="keywordtype">char</font> **CSLRemoveStrings(<font class="keywordtype">char</font> **papszStrList, <font class="keywordtype">int</font> nFirstLineToDelete, 00457 <font class="keywordtype">int</font> nNumToRemove, <font class="keywordtype">char</font> ***ppapszRetStrings)<font class="keyword"></font> 00458 <font class="keyword"></font>{ 00459 <font class="keywordtype">int</font> i, nSrcLines, nDstLines; 00460 <font class="keywordtype">char</font> **ppszSrc, **ppszDst; 00461 00462 nSrcLines = CSLCount(papszStrList); 00463 nDstLines = nSrcLines - nNumToRemove; 00464 00465 <font class="keywordflow">if</font> (nNumToRemove < 1 || nSrcLines == 0) 00466 <font class="keywordflow">return</font> papszStrList; <font class="comment">/* Nothing to do!*/</font> 00467 00468 <font class="comment">/* If operation will result in an empty StringList then don't waste</font> 00469 <font class="comment"> * time here!</font> 00470 <font class="comment"> */</font> 00471 <font class="keywordflow">if</font> (nDstLines < 1) 00472 { 00473 CSLDestroy(papszStrList); 00474 <font class="keywordflow">return</font> NULL; 00475 } 00476 00477 00478 <font class="comment">/* Remove lines from the source StringList...</font> 00479 <font class="comment"> * Either free() each line or store them to a new StringList depending on</font> 00480 <font class="comment"> * the caller's choice.</font> 00481 <font class="comment"> */</font> 00482 ppszDst = papszStrList + nFirstLineToDelete; 00483 00484 <font class="keywordflow">if</font> (ppapszRetStrings == NULL) 00485 { 00486 <font class="comment">/* free() all the strings that will be removed.</font> 00487 <font class="comment"> */</font> 00488 <font class="keywordflow">for</font> (i=0; i < nNumToRemove; i++) 00489 { 00490 CPLFree(*ppszDst); 00491 *ppszDst = NULL; 00492 } 00493 } 00494 <font class="keywordflow">else</font> 00495 { 00496 <font class="comment">/* Store the strings to remove in a new StringList</font> 00497 <font class="comment"> */</font> 00498 *ppapszRetStrings = (<font class="keywordtype">char</font> **)<a class="code" href="cpl_conv_h.html#a4">CPLCalloc</a>(nNumToRemove+1, <font class="keyword">sizeof</font>(<font class="keywordtype">char</font>*)); 00499 00500 <font class="keywordflow">for</font> (i=0; i < nNumToRemove; i++) 00501 { 00502 (*ppapszRetStrings)[i] = *ppszDst; 00503 *ppszDst = NULL; 00504 ppszDst++; 00505 } 00506 } 00507 00508 00509 <font class="comment">/* Shift down all the lines that follow the lines to remove.</font> 00510 <font class="comment"> */</font> 00511 <font class="keywordflow">if</font> (nFirstLineToDelete == -1 || nFirstLineToDelete > nSrcLines) 00512 nFirstLineToDelete = nDstLines; 00513 00514 ppszSrc = papszStrList + nFirstLineToDelete + nNumToRemove; 00515 ppszDst = papszStrList + nFirstLineToDelete; 00516 00517 <font class="keywordflow">for</font> ( ; *ppszSrc != NULL; ppszSrc++, ppszDst++) 00518 { 00519 *ppszDst = *ppszSrc; 00520 } 00521 <font class="comment">/* Move the NULL pointer at the end of the StringList */</font> 00522 *ppszDst = *ppszSrc; 00523 00524 <font class="comment">/* At this point, we could realloc() papszStrList to a smaller size, but</font> 00525 <font class="comment"> * since this array will likely grow again in further operations on the</font> 00526 <font class="comment"> * StringList we'll leave it as it is.</font> 00527 <font class="comment"> */</font> 00528 00529 <font class="keywordflow">return</font> papszStrList; 00530 } 00531 00532 <font class="comment">/************************************************************************/</font> 00533 <font class="comment">/* CSLFindString() */</font> 00534 <font class="comment">/* */</font> 00535 <font class="comment">/* Find a string within a string list. The string must match */</font> 00536 <font class="comment">/* the full length, but the comparison is case insensitive. */</font> 00537 <font class="comment">/* Return -1 on failure. */</font> 00538 <font class="comment">/************************************************************************/</font> 00539 00540 <font class="keywordtype">int</font> CSLFindString( <font class="keywordtype">char</font> ** papszList, <font class="keyword">const</font> <font class="keywordtype">char</font> * pszTarget )<font class="keyword"></font> 00541 <font class="keyword"></font> 00542 <font class="keyword"></font>{ 00543 <font class="keywordtype">int</font> i; 00544 00545 <font class="keywordflow">if</font>( papszList == NULL ) 00546 <font class="keywordflow">return</font> -1; 00547 00548 <font class="keywordflow">for</font>( i = 0; papszList[i] != NULL; i++ ) 00549 { 00550 <font class="keywordflow">if</font>( EQUAL(papszList[i],pszTarget) ) 00551 <font class="keywordflow">return</font> i; 00552 } 00553 00554 <font class="keywordflow">return</font> -1; 00555 } 00556 00557 <font class="comment">/**********************************************************************</font> 00558 <font class="comment"> * CSLTokenizeString()</font> 00559 <font class="comment"> *</font> 00560 <font class="comment"> * Tokenizes a string and returns a StringList with one string for</font> 00561 <font class="comment"> * each token.</font> 00562 <font class="comment"> **********************************************************************/</font> 00563 <font class="keywordtype">char</font> **CSLTokenizeString( <font class="keyword">const</font> <font class="keywordtype">char</font> *pszString )<font class="keyword"></font> 00564 <font class="keyword"></font>{ 00565 <font class="keywordflow">return</font> CSLTokenizeString2( pszString, <font class="stringliteral">" "</font>, CSLT_HONOURSTRINGS ); 00566 } 00567 00568 <font class="comment">/************************************************************************/</font> 00569 <font class="comment">/* CSLTokenizeStringComplex() */</font> 00570 <font class="comment">/* */</font> 00571 <font class="comment">/* Obsolete tokenizing api. */</font> 00572 <font class="comment">/************************************************************************/</font> 00573 00574 <font class="keywordtype">char</font> ** CSLTokenizeStringComplex( <font class="keyword">const</font> <font class="keywordtype">char</font> * pszString, 00575 <font class="keyword">const</font> <font class="keywordtype">char</font> * pszDelimiters, 00576 <font class="keywordtype">int</font> bHonourStrings, <font class="keywordtype">int</font> bAllowEmptyTokens )<font class="keyword"></font> 00577 <font class="keyword"></font> 00578 <font class="keyword"></font>{ 00579 <font class="keywordtype">int</font> nFlags = 0; 00580 00581 <font class="keywordflow">if</font>( bHonourStrings ) 00582 nFlags |= CSLT_HONOURSTRINGS; 00583 <font class="keywordflow">if</font>( bAllowEmptyTokens ) 00584 nFlags |= CSLT_ALLOWEMPTYTOKENS; 00585 00586 <font class="keywordflow">return</font> CSLTokenizeString2( pszString, pszDelimiters, nFlags ); 00587 } 00588 00589 <font class="comment">/************************************************************************/</font> 00590 <font class="comment">/* CSLTokenizeString2() */</font> 00591 <font class="comment">/* */</font> 00592 <font class="comment">/* The ultimate tokenizer? */</font> 00593 <font class="comment">/************************************************************************/</font> 00594 00595 <font class="keywordtype">char</font> ** CSLTokenizeString2( <font class="keyword">const</font> <font class="keywordtype">char</font> * pszString, 00596 <font class="keyword">const</font> <font class="keywordtype">char</font> * pszDelimiters, 00597 <font class="keywordtype">int</font> nCSLTFlags )<font class="keyword"></font> 00598 <font class="keyword"></font> 00599 <font class="keyword"></font>{ 00600 <font class="keywordtype">char</font> **papszRetList = NULL; 00601 <font class="keywordtype">char</font> *pszToken; 00602 <font class="keywordtype">int</font> nTokenMax, nTokenLen; 00603 <font class="keywordtype">int</font> bHonourStrings = (nCSLTFlags & CSLT_HONOURSTRINGS); 00604 <font class="keywordtype">int</font> bAllowEmptyTokens = (nCSLTFlags & CSLT_ALLOWEMPTYTOKENS); 00605 00606 pszToken = (<font class="keywordtype">char</font> *) <a class="code" href="cpl_conv_h.html#a4">CPLCalloc</a>(10,1); 00607 nTokenMax = 10; 00608 00609 <font class="keywordflow">while</font>( pszString != NULL && *pszString != <font class="charliteral">'\0'</font> ) 00610 { 00611 <font class="keywordtype">int</font> bInString = FALSE; 00612 00613 nTokenLen = 0; 00614 00615 <font class="comment">/* Try to find the next delimeter, marking end of token */</font> 00616 <font class="keywordflow">for</font>( ; *pszString != <font class="charliteral">'\0'</font>; pszString++ ) 00617 { 00618 00619 <font class="comment">/* End if this is a delimeter skip it and break. */</font> 00620 <font class="keywordflow">if</font>( !bInString && strchr(pszDelimiters, *pszString) != NULL ) 00621 { 00622 pszString++; 00623 <font class="keywordflow">break</font>; 00624 } 00625 00626 <font class="comment">/* If this is a quote, and we are honouring constant</font> 00627 <font class="comment"> strings, then process the constant strings, with out delim</font> 00628 <font class="comment"> but don't copy over the quotes */</font> 00629 <font class="keywordflow">if</font>( bHonourStrings && *pszString == <font class="charliteral">'"'</font> ) 00630 { 00631 <font class="keywordflow">if</font>( nCSLTFlags & CSLT_PRESERVEQUOTES ) 00632 { 00633 pszToken[nTokenLen] = *pszString; 00634 nTokenLen++; 00635 } 00636 00637 <font class="keywordflow">if</font>( bInString ) 00638 { 00639 bInString = FALSE; 00640 <font class="keywordflow">continue</font>; 00641 } 00642 <font class="keywordflow">else</font> 00643 { 00644 bInString = TRUE; 00645 <font class="keywordflow">continue</font>; 00646 } 00647 } 00648 00649 <font class="comment">/* Within string constants we allow for escaped quotes, but</font> 00650 <font class="comment"> in processing them we will unescape the quotes */</font> 00651 <font class="keywordflow">if</font>( bInString && pszString[0] == <font class="charliteral">'\\'</font> && pszString[1] == <font class="charliteral">'"'</font> ) 00652 { 00653 <font class="keywordflow">if</font>( nCSLTFlags & CSLT_PRESERVEESCAPES ) 00654 { 00655 pszToken[nTokenLen] = *pszString; 00656 nTokenLen++; 00657 } 00658 00659 pszString++; 00660 } 00661 00662 <font class="comment">/* Within string constants a \\ sequence reduces to \ */</font> 00663 <font class="keywordflow">else</font> <font class="keywordflow">if</font>( bInString 00664 && pszString[0] == <font class="charliteral">'\\'</font> && pszString[1] == <font class="charliteral">'\\'</font> ) 00665 { 00666 <font class="keywordflow">if</font>( nCSLTFlags & CSLT_PRESERVEESCAPES ) 00667 { 00668 pszToken[nTokenLen] = *pszString; 00669 nTokenLen++; 00670 } 00671 pszString++; 00672 } 00673 00674 <font class="keywordflow">if</font>( nTokenLen >= nTokenMax-2 ) 00675 { 00676 nTokenMax = nTokenMax * 2 + 10; 00677 pszToken = (<font class="keywordtype">char</font> *) <a class="code" href="cpl_conv_h.html#a5">CPLRealloc</a>( pszToken, nTokenMax ); 00678 } 00679 00680 pszToken[nTokenLen] = *pszString; 00681 nTokenLen++; 00682 } 00683 00684 pszToken[nTokenLen] = <font class="charliteral">'\0'</font>; 00685 00686 <font class="keywordflow">if</font>( pszToken[0] != <font class="charliteral">'\0'</font> || bAllowEmptyTokens ) 00687 { 00688 papszRetList = CSLAddString( papszRetList, pszToken ); 00689 } 00690 00691 <font class="comment">/* If the last token is an empty token, then we have to catch</font> 00692 <font class="comment"> * it now, otherwise we won't reenter the loop and it will be lost. </font> 00693 <font class="comment"> */</font> 00694 <font class="keywordflow">if</font> ( *pszString == <font class="charliteral">'\0'</font> && bAllowEmptyTokens && 00695 strchr(pszDelimiters, *(pszString-1)) ) 00696 { 00697 papszRetList = CSLAddString( papszRetList, <font class="stringliteral">""</font> ); 00698 } 00699 } 00700 00701 <font class="keywordflow">if</font>( papszRetList == NULL ) 00702 papszRetList = (<font class="keywordtype">char</font> **) <a class="code" href="cpl_conv_h.html#a4">CPLCalloc</a>(<font class="keyword">sizeof</font>(<font class="keywordtype">char</font> *),1); 00703 00704 CPLFree( pszToken ); 00705 00706 <font class="keywordflow">return</font> papszRetList; 00707 } 00708 00709 <font class="comment">/**********************************************************************</font> 00710 <font class="comment"> * CPLSPrintf()</font> 00711 <font class="comment"> *</font> 00712 <font class="comment"> * My own version of CPLSPrintf() that works with 10 static buffer.</font> 00713 <font class="comment"> *</font> 00714 <font class="comment"> * It returns a ref. to a static buffer that should not be freed and</font> 00715 <font class="comment"> * is valid only until the next call to CPLSPrintf().</font> 00716 <font class="comment"> *</font> 00717 <font class="comment"> * NOTE: This function should move to cpl_conv.cpp. </font> 00718 <font class="comment"> **********************************************************************/</font> 00719 <font class="comment">/* For now, assume that a 8000 chars buffer will be enough.</font> 00720 <font class="comment"> */</font> 00721 <font class="preprocessor">#define CPLSPrintf_BUF_SIZE 8000</font> 00722 <font class="preprocessor"></font><font class="preprocessor">#define CPLSPrintf_BUF_Count 10</font> 00723 <font class="preprocessor"></font><font class="keyword">static</font> <font class="keywordtype">char</font> gszCPLSPrintfBuffer[CPLSPrintf_BUF_Count][CPLSPrintf_BUF_SIZE]; 00724 <font class="keyword">static</font> <font class="keywordtype">int</font> gnCPLSPrintfBuffer = 0; 00725 00726 <font class="keyword">const</font> <font class="keywordtype">char</font> *CPLSPrintf(<font class="keywordtype">char</font> *fmt, ...)<font class="keyword"></font> 00727 <font class="keyword"></font>{ 00728 va_list args; 00729 00730 va_start(args, fmt); 00731 vsprintf(gszCPLSPrintfBuffer[gnCPLSPrintfBuffer], fmt, args); 00732 va_end(args); 00733 00734 <font class="keywordtype">int</font> nCurrent = gnCPLSPrintfBuffer; 00735 00736 <font class="keywordflow">if</font> (++gnCPLSPrintfBuffer == CPLSPrintf_BUF_Count) 00737 gnCPLSPrintfBuffer = 0; 00738 00739 <font class="keywordflow">return</font> gszCPLSPrintfBuffer[nCurrent]; 00740 } 00741 00742 <font class="comment">/**********************************************************************</font> 00743 <font class="comment"> * CSLAppendPrintf()</font> 00744 <font class="comment"> *</font> 00745 <font class="comment"> * Use CPLSPrintf() to append a new line at the end of a StringList.</font> 00746 <font class="comment"> *</font> 00747 <font class="comment"> * Returns the modified StringList.</font> 00748 <font class="comment"> **********************************************************************/</font> 00749 <font class="keywordtype">char</font> **CSLAppendPrintf(<font class="keywordtype">char</font> **papszStrList, <font class="keywordtype">char</font> *fmt, ...)<font class="keyword"></font> 00750 <font class="keyword"></font>{ 00751 va_list args; 00752 00753 va_start(args, fmt); 00754 vsprintf(gszCPLSPrintfBuffer[gnCPLSPrintfBuffer], fmt, args); 00755 va_end(args); 00756 00757 <font class="keywordtype">int</font> nCurrent = gnCPLSPrintfBuffer; 00758 00759 <font class="keywordflow">if</font> (++gnCPLSPrintfBuffer == CPLSPrintf_BUF_Count) 00760 gnCPLSPrintfBuffer = 0; 00761 00762 <font class="keywordflow">return</font> CSLAddString(papszStrList, gszCPLSPrintfBuffer[nCurrent]); 00763 } 00764 00765 00766 <font class="comment">/**********************************************************************</font> 00767 <font class="comment"> * CSLFetchNameValue()</font> 00768 <font class="comment"> *</font> 00769 <font class="comment"> * In a StringList of "Name=Value" pairs, look for the</font> 00770 <font class="comment"> * first value associated with the specified name. The search is not</font> 00771 <font class="comment"> * case sensitive.</font> 00772 <font class="comment"> * ("Name:Value" pairs are also supported for backward compatibility</font> 00773 <font class="comment"> * with older stuff.)</font> 00774 <font class="comment"> * </font> 00775 <font class="comment"> * Returns a reference to the value in the StringList that the caller</font> 00776 <font class="comment"> * should not attempt to free.</font> 00777 <font class="comment"> *</font> 00778 <font class="comment"> * Returns NULL if the name is not found.</font> 00779 <font class="comment"> **********************************************************************/</font> 00780 <font class="keyword">const</font> <font class="keywordtype">char</font> *CSLFetchNameValue(<font class="keywordtype">char</font> **papszStrList, <font class="keyword">const</font> <font class="keywordtype">char</font> *pszName)<font class="keyword"></font> 00781 <font class="keyword"></font>{ 00782 <font class="keywordtype">int</font> nLen; 00783 00784 <font class="keywordflow">if</font> (papszStrList == NULL || pszName == NULL) 00785 <font class="keywordflow">return</font> NULL; 00786 00787 nLen = strlen(pszName); 00788 <font class="keywordflow">while</font>(*papszStrList != NULL) 00789 { 00790 <font class="keywordflow">if</font> (EQUALN(*papszStrList, pszName, nLen) 00791 && ( (*papszStrList)[nLen] == <font class="charliteral">'='</font> || 00792 (*papszStrList)[nLen] == <font class="charliteral">':'</font> ) ) 00793 { 00794 <font class="keywordflow">return</font> (*papszStrList)+nLen+1; 00795 } 00796 papszStrList++; 00797 } 00798 <font class="keywordflow">return</font> NULL; 00799 } 00800 00801 <font class="comment">/**********************************************************************</font> 00802 <font class="comment"> * CPLParseNameValue()</font> 00803 <font class="comment"> **********************************************************************/</font> 00804 00825 <font class="keyword">const</font> <font class="keywordtype">char</font> *CPLParseNameValue(<font class="keyword">const</font> <font class="keywordtype">char</font> *pszNameValue, <font class="keywordtype">char</font> **ppszKey )<font class="keyword"></font> 00826 <font class="keyword"></font> 00827 <font class="keyword"></font>{ 00828 <font class="keywordtype">int</font> i; 00829 <font class="keyword">const</font> <font class="keywordtype">char</font> *pszValue; 00830 00831 <font class="keywordflow">for</font>( i = 0; pszNameValue[i] != <font class="charliteral">'\0'</font>; i++ ) 00832 { 00833 <font class="keywordflow">if</font>( pszNameValue[i] == <font class="charliteral">'='</font> || pszNameValue[i] == <font class="charliteral">':'</font> ) 00834 { 00835 pszValue = pszNameValue + i + 1; 00836 <font class="keywordflow">while</font>( *pszValue == <font class="charliteral">' '</font> || *pszValue == <font class="charliteral">'\t'</font> ) 00837 pszValue++; 00838 00839 <font class="keywordflow">if</font>( ppszKey != NULL ) 00840 { 00841 *ppszKey = (<font class="keywordtype">char</font> *) <a class="code" href="cpl_conv_h.html#a3">CPLMalloc</a>(i+1); 00842 strncpy( *ppszKey, pszNameValue, i ); 00843 (*ppszKey)[i] = <font class="charliteral">'\0'</font>; 00844 <font class="keywordflow">while</font>( i > 0 && 00845 ( (*ppszKey)[i] == <font class="charliteral">' '</font> || (*ppszKey)[i] == <font class="charliteral">'\t'</font>) ) 00846 { 00847 (*ppszKey)[i] = <font class="charliteral">'\0'</font>; 00848 i--; 00849 } 00850 } 00851 00852 <font class="keywordflow">return</font> pszValue; 00853 } 00854 00855 } 00856 00857 <font class="keywordflow">return</font> NULL; 00858 } 00859 00860 <font class="comment">/**********************************************************************</font> 00861 <font class="comment"> * CSLFetchNameValueMultiple()</font> 00862 <font class="comment"> *</font> 00863 <font class="comment"> * In a StringList of "Name=Value" pairs, look for all the</font> 00864 <font class="comment"> * values with the specified name. The search is not case</font> 00865 <font class="comment"> * sensitive.</font> 00866 <font class="comment"> * ("Name:Value" pairs are also supported for backward compatibility</font> 00867 <font class="comment"> * with older stuff.)</font> 00868 <font class="comment"> * </font> 00869 <font class="comment"> * Returns stringlist with one entry for each occurence of the</font> 00870 <font class="comment"> * specified name. The stringlist should eventually be destroyed</font> 00871 <font class="comment"> * by calling CSLDestroy().</font> 00872 <font class="comment"> *</font> 00873 <font class="comment"> * Returns NULL if the name is not found.</font> 00874 <font class="comment"> **********************************************************************/</font> 00875 <font class="keywordtype">char</font> **CSLFetchNameValueMultiple(<font class="keywordtype">char</font> **papszStrList, <font class="keyword">const</font> <font class="keywordtype">char</font> *pszName)<font class="keyword"></font> 00876 <font class="keyword"></font>{ 00877 <font class="keywordtype">int</font> nLen; 00878 <font class="keywordtype">char</font> **papszValues = NULL; 00879 00880 <font class="keywordflow">if</font> (papszStrList == NULL || pszName == NULL) 00881 <font class="keywordflow">return</font> NULL; 00882 00883 nLen = strlen(pszName); 00884 <font class="keywordflow">while</font>(*papszStrList != NULL) 00885 { 00886 <font class="keywordflow">if</font> (EQUALN(*papszStrList, pszName, nLen) 00887 && ( (*papszStrList)[nLen] == <font class="charliteral">'='</font> || 00888 (*papszStrList)[nLen] == <font class="charliteral">':'</font> ) ) 00889 { 00890 papszValues = CSLAddString(papszValues, 00891 (*papszStrList)+nLen+1); 00892 } 00893 papszStrList++; 00894 } 00895 00896 <font class="keywordflow">return</font> papszValues; 00897 } 00898 00899 00900 <font class="comment">/**********************************************************************</font> 00901 <font class="comment"> * CSLAddNameValue()</font> 00902 <font class="comment"> *</font> 00903 <font class="comment"> * Add a new entry to a StringList of "Name=Value" pairs,</font> 00904 <font class="comment"> * ("Name:Value" pairs are also supported for backward compatibility</font> 00905 <font class="comment"> * with older stuff.)</font> 00906 <font class="comment"> * </font> 00907 <font class="comment"> * This function does not check if a "Name=Value" pair already exists</font> 00908 <font class="comment"> * for that name and can generate multiple entryes for the same name.</font> 00909 <font class="comment"> * Use CSLSetNameValue() if you want each name to have only one value.</font> 00910 <font class="comment"> *</font> 00911 <font class="comment"> * Returns the modified stringlist.</font> 00912 <font class="comment"> **********************************************************************/</font> 00913 <font class="keywordtype">char</font> **CSLAddNameValue(<font class="keywordtype">char</font> **papszStrList, 00914 <font class="keyword">const</font> <font class="keywordtype">char</font> *pszName, <font class="keyword">const</font> <font class="keywordtype">char</font> *pszValue)<font class="keyword"></font> 00915 <font class="keyword"></font>{ 00916 <font class="keyword">const</font> <font class="keywordtype">char</font> *pszLine; 00917 00918 <font class="keywordflow">if</font> (pszName == NULL || pszValue==NULL) 00919 <font class="keywordflow">return</font> papszStrList; 00920 00921 pszLine = CPLSPrintf(<font class="stringliteral">"%s=%s"</font>, pszName, pszValue); 00922 00923 <font class="keywordflow">return</font> CSLAddString(papszStrList, pszLine); 00924 } 00925 00926 <font class="comment">/**********************************************************************</font> 00927 <font class="comment"> * CSLSetNameValue()</font> 00928 <font class="comment"> *</font> 00929 <font class="comment"> * Set the value for a given name in a StringList of "Name=Value" pairs</font> 00930 <font class="comment"> * ("Name:Value" pairs are also supported for backward compatibility</font> 00931 <font class="comment"> * with older stuff.)</font> 00932 <font class="comment"> * </font> 00933 <font class="comment"> * If there is already a value for that name in the list then the value</font> 00934 <font class="comment"> * is changed, otherwise a new "Name=Value" pair is added.</font> 00935 <font class="comment"> *</font> 00936 <font class="comment"> * Returns the modified stringlist.</font> 00937 <font class="comment"> **********************************************************************/</font> 00938 <font class="keywordtype">char</font> **CSLSetNameValue(<font class="keywordtype">char</font> **papszList, 00939 <font class="keyword">const</font> <font class="keywordtype">char</font> *pszName, <font class="keyword">const</font> <font class="keywordtype">char</font> *pszValue)<font class="keyword"></font> 00940 <font class="keyword"></font>{ 00941 <font class="keywordtype">char</font> **papszPtr; 00942 <font class="keywordtype">int</font> nLen; 00943 00944 <font class="keywordflow">if</font> (pszName == NULL || pszValue==NULL) 00945 <font class="keywordflow">return</font> papszList; 00946 00947 nLen = strlen(pszName); 00948 papszPtr = papszList; 00949 <font class="keywordflow">while</font>(papszPtr && *papszPtr != NULL) 00950 { 00951 <font class="keywordflow">if</font> (EQUALN(*papszPtr, pszName, nLen) 00952 && ( (*papszPtr)[nLen] == <font class="charliteral">'='</font> || 00953 (*papszPtr)[nLen] == <font class="charliteral">':'</font> ) ) 00954 { 00955 <font class="comment">/* Found it! </font> 00956 <font class="comment"> * Change the value... make sure to keep the ':' or '='</font> 00957 <font class="comment"> */</font> 00958 <font class="keywordtype">char</font> cSep; 00959 cSep = (*papszPtr)[nLen]; 00960 00961 free(*papszPtr); 00962 *papszPtr = <a class="code" href="cpl_conv_h.html#a6">CPLStrdup</a>(CPLSPrintf(<font class="stringliteral">"%s%c%s"</font>, pszName, 00963 cSep, pszValue)); 00964 00965 <font class="keywordflow">return</font> papszList; 00966 } 00967 papszPtr++; 00968 } 00969 00970 <font class="comment">/* The name does not exist yet... create a new entry</font> 00971 <font class="comment"> */</font> 00972 <font class="keywordflow">return</font> CSLAddString(papszList, 00973 CPLSPrintf(<font class="stringliteral">"%s=%s"</font>, pszName, pszValue)); 00974 } 00975 00976 <font class="comment">/************************************************************************/</font> 00977 <font class="comment">/* CSLSetNameValueSeparator() */</font> 00978 <font class="comment">/************************************************************************/</font> 00979 01000 <font class="keywordtype">void</font> CSLSetNameValueSeparator( <font class="keywordtype">char</font> ** papszList, <font class="keyword">const</font> <font class="keywordtype">char</font> *pszSeparator )<font class="keyword"></font> 01001 <font class="keyword"></font> 01002 <font class="keyword"></font>{ 01003 <font class="keywordtype">int</font> nLines = CSLCount(papszList), iLine; 01004 01005 <font class="keywordflow">for</font>( iLine = 0; iLine < nLines; iLine++ ) 01006 { 01007 <font class="keywordtype">char</font> *pszKey = NULL; 01008 <font class="keyword">const</font> <font class="keywordtype">char</font> *pszValue; 01009 <font class="keywordtype">char</font> *pszNewLine; 01010 01011 pszValue = CPLParseNameValue( papszList[iLine], &pszKey ); 01012 01013 pszNewLine = (<font class="keywordtype">char</font> *) <a class="code" href="cpl_conv_h.html#a3">CPLMalloc</a>(strlen(pszValue)+strlen(pszKey) 01014 +strlen(pszSeparator)+1); 01015 strcpy( pszNewLine, pszKey ); 01016 strcat( pszNewLine, pszSeparator ); 01017 strcat( pszNewLine, pszValue ); 01018 CPLFree( papszList[iLine] ); 01019 papszList[iLine] = pszNewLine; 01020 } 01021 } </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>, © 1997-2000</small></address> </body> </html>