Sophie

Sophie

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

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_csv.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_csv.cpp</h1><div class="fragment"><pre>00001 <font class="comment">/******************************************************************************</font>
00002 <font class="comment"> * $Id: cpl_csv_cpp-source.html,v 1.8 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:  CSV (comma separated value) file access.</font>
00006 <font class="comment"> * Author:   Frank Warmerdam, warmerda@home.com</font>
00007 <font class="comment"> *</font>
00008 <font class="comment"> ******************************************************************************</font>
00009 <font class="comment"> * Copyright (c) 1999, 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</font>
00022 <font class="comment"> * OR 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_csv_cpp-source.html,v $
00030 <font class="comment"> * Revision 1.8  2002/04/16 13:11:47  warmerda
00030 <font class="comment"> * updated
00030 <font class="comment"> *</font>
00031 <font class="comment"> * Revision 1.3  2001/07/18 04:00:49  warmerda</font>
00032 <font class="comment"> * added CPL_CVSID</font>
00033 <font class="comment"> *</font>
00034 <font class="comment"> * Revision 1.2  2001/01/19 21:16:41  warmerda</font>
00035 <font class="comment"> * expanded tabs</font>
00036 <font class="comment"> *</font>
00037 <font class="comment"> * Revision 1.1  2000/10/06 15:20:45  warmerda</font>
00038 <font class="comment"> * New</font>
00039 <font class="comment"> *</font>
00040 <font class="comment"> * Revision 1.2  2000/08/29 21:08:08  warmerda</font>
00041 <font class="comment"> * fallback to use CPLFindFile()</font>
00042 <font class="comment"> *</font>
00043 <font class="comment"> * Revision 1.1  2000/04/05 21:55:59  warmerda</font>
00044 <font class="comment"> * New</font>
00045 <font class="comment"> *</font>
00046 <font class="comment"> */</font>
00047 
00048 <font class="preprocessor">#include "cpl_csv.h"</font>
00049 <font class="preprocessor">#include "<a class="code" href="cpl_conv_h.html">cpl_conv.h</a>"</font>
00050 
00051 CPL_CVSID(<font class="stringliteral">"$Id: cpl_csv_cpp-source.html,v 1.8 2002/04/16 13:11:47 warmerda Exp $"</font>);
00052 
00053 <font class="comment">/* ==================================================================== */</font>
00054 <font class="comment">/*      The CSVTable is a persistant set of info about an open CSV      */</font>
00055 <font class="comment">/*      table.  While it doesn't currently maintain a record index,     */</font>
00056 <font class="comment">/*      or in-memory copy of the table, it could be changed to do so    */</font>
00057 <font class="comment">/*      in the future.                                                  */</font>
00058 <font class="comment">/* ==================================================================== */</font>
00059 <font class="keyword">typedef</font> <font class="keyword">struct </font>ctb {
00060     FILE        *fp;
00061 
00062     <font class="keyword">struct </font>ctb *psNext;
00063 
00064     <font class="keywordtype">char</font>        *pszFilename;
00065 
00066     <font class="keywordtype">char</font>        **papszFieldNames;
00067 
00068     <font class="keywordtype">char</font>        **papszRecFields;
00069 } CSVTable;
00070 
00071 <font class="keyword">static</font> CSVTable *psCSVTableList = NULL;
00072 
00073 <font class="comment">/************************************************************************/</font>
00074 <font class="comment">/*                             CSVAccess()                              */</font>
00075 <font class="comment">/*                                                                      */</font>
00076 <font class="comment">/*      This function will fetch a handle to the requested table.       */</font>
00077 <font class="comment">/*      If not found in the ``open table list'' the table will be       */</font>
00078 <font class="comment">/*      opened and added to the list.  Eventually this function may     */</font>
00079 <font class="comment">/*      become public with an abstracted return type so that            */</font>
00080 <font class="comment">/*      applications can set options about the table.  For now this     */</font>
00081 <font class="comment">/*      isn't done.                                                     */</font>
00082 <font class="comment">/************************************************************************/</font>
00083 
00084 <font class="keyword">static</font> CSVTable *CSVAccess( <font class="keyword">const</font> <font class="keywordtype">char</font> * pszFilename )<font class="keyword"></font>
00085 <font class="keyword"></font>
00086 <font class="keyword"></font>{
00087     CSVTable    *psTable;
00088     FILE        *fp;
00089 
00090 <font class="comment">/* -------------------------------------------------------------------- */</font>
00091 <font class="comment">/*      Is the table already in the list.                               */</font>
00092 <font class="comment">/* -------------------------------------------------------------------- */</font>
00093     <font class="keywordflow">for</font>( psTable = psCSVTableList; psTable != NULL; psTable = psTable-&gt;psNext )
00094     {
00095         <font class="keywordflow">if</font>( EQUAL(psTable-&gt;pszFilename,pszFilename) )
00096         {
00097             <font class="comment">/*</font>
00098 <font class="comment">             * Eventually we should consider promoting to the front of</font>
00099 <font class="comment">             * the list to accelerate frequently accessed tables.</font>
00100 <font class="comment">             */</font>
00101             
00102             <font class="keywordflow">return</font>( psTable );
00103         }
00104     }
00105 
00106 <font class="comment">/* -------------------------------------------------------------------- */</font>
00107 <font class="comment">/*      If not, try to open it.                                         */</font>
00108 <font class="comment">/* -------------------------------------------------------------------- */</font>
00109     fp = VSIFOpen( pszFilename, <font class="stringliteral">"r"</font> );
00110     <font class="keywordflow">if</font>( fp == NULL )
00111         <font class="keywordflow">return</font> NULL;
00112 
00113 <font class="comment">/* -------------------------------------------------------------------- */</font>
00114 <font class="comment">/*      Create an information structure about this table, and add to    */</font>
00115 <font class="comment">/*      the front of the list.                                          */</font>
00116 <font class="comment">/* -------------------------------------------------------------------- */</font>
00117     psTable = (CSVTable *) <a class="code" href="cpl_conv_h.html#a4">CPLCalloc</a>(<font class="keyword">sizeof</font>(CSVTable),1);
00118 
00119     psTable-&gt;fp = fp;
00120     psTable-&gt;pszFilename = <a class="code" href="cpl_conv_h.html#a6">CPLStrdup</a>( pszFilename );
00121     psTable-&gt;psNext = psCSVTableList;
00122     
00123     psCSVTableList = psTable;
00124 
00125 <font class="comment">/* -------------------------------------------------------------------- */</font>
00126 <font class="comment">/*      Read the table header record containing the field names.        */</font>
00127 <font class="comment">/* -------------------------------------------------------------------- */</font>
00128     psTable-&gt;papszFieldNames = CSVReadParseLine( fp );
00129 
00130     <font class="keywordflow">return</font>( psTable );
00131 }
00132 
00133 <font class="comment">/************************************************************************/</font>
00134 <font class="comment">/*                            CSVDeaccess()                             */</font>
00135 <font class="comment">/************************************************************************/</font>
00136 
00137 <font class="keywordtype">void</font> CSVDeaccess( <font class="keyword">const</font> <font class="keywordtype">char</font> * pszFilename )<font class="keyword"></font>
00138 <font class="keyword"></font>
00139 <font class="keyword"></font>{
00140     CSVTable    *psLast, *psTable;
00141     
00142 <font class="comment">/* -------------------------------------------------------------------- */</font>
00143 <font class="comment">/*      A NULL means deaccess all tables.                               */</font>
00144 <font class="comment">/* -------------------------------------------------------------------- */</font>
00145     <font class="keywordflow">if</font>( pszFilename == NULL )
00146     {
00147         <font class="keywordflow">while</font>( psCSVTableList != NULL )
00148             CSVDeaccess( psCSVTableList-&gt;pszFilename );
00149         
00150         <font class="keywordflow">return</font>;
00151     }
00152 
00153 <font class="comment">/* -------------------------------------------------------------------- */</font>
00154 <font class="comment">/*      Find this table.                                                */</font>
00155 <font class="comment">/* -------------------------------------------------------------------- */</font>
00156     psLast = NULL;
00157     <font class="keywordflow">for</font>( psTable = psCSVTableList;
00158          psTable != NULL &amp;&amp; !EQUAL(psTable-&gt;pszFilename,pszFilename);
00159          psTable = psTable-&gt;psNext )
00160     {
00161         psLast = psTable;
00162     }
00163 
00164     <font class="keywordflow">if</font>( psTable == NULL )
00165         <font class="keywordflow">return</font>;
00166 
00167 <font class="comment">/* -------------------------------------------------------------------- */</font>
00168 <font class="comment">/*      Remove the link from the list.                                  */</font>
00169 <font class="comment">/* -------------------------------------------------------------------- */</font>
00170     <font class="keywordflow">if</font>( psLast != NULL )
00171         psLast-&gt;psNext = psTable-&gt;psNext;
00172     <font class="keywordflow">else</font>
00173         psCSVTableList = psTable-&gt;psNext;
00174 
00175 <font class="comment">/* -------------------------------------------------------------------- */</font>
00176 <font class="comment">/*      Free the table.                                                 */</font>
00177 <font class="comment">/* -------------------------------------------------------------------- */</font>
00178     VSIFClose( psTable-&gt;fp );
00179 
00180     CSLDestroy( psTable-&gt;papszFieldNames );
00181     CSLDestroy( psTable-&gt;papszRecFields );
00182     CPLFree( psTable-&gt;pszFilename );
00183 
00184     CPLFree( psTable );
00185 }
00186 
00187 <font class="comment">/************************************************************************/</font>
00188 <font class="comment">/*                          CSVReadParseLine()                          */</font>
00189 <font class="comment">/*                                                                      */</font>
00190 <font class="comment">/*      Read one line, and return split into fields.  The return        */</font>
00191 <font class="comment">/*      result is a stringlist, in the sense of the CSL functions.      */</font>
00192 <font class="comment">/************************************************************************/</font>
00193 
00194 <font class="keywordtype">char</font> **CSVReadParseLine( FILE * fp )<font class="keyword"></font>
00195 <font class="keyword"></font>
00196 <font class="keyword"></font>{
00197     <font class="keyword">const</font> <font class="keywordtype">char</font>  *pszLine;
00198     <font class="keywordtype">char</font>        *pszWorkLine;
00199     <font class="keywordtype">char</font>        **papszReturn;
00200 
00201     CPLAssert( fp != NULL );
00202     <font class="keywordflow">if</font>( fp == NULL )
00203         <font class="keywordflow">return</font>( NULL );
00204     
00205     pszLine = <a class="code" href="cpl_conv_h.html#a7">CPLReadLine</a>( fp );
00206     <font class="keywordflow">if</font>( pszLine == NULL )
00207         <font class="keywordflow">return</font>( NULL );
00208 
00209 <font class="comment">/* -------------------------------------------------------------------- */</font>
00210 <font class="comment">/*      If there are no quotes, then this is the simple case.           */</font>
00211 <font class="comment">/*      Parse, and return tokens.                                       */</font>
00212 <font class="comment">/* -------------------------------------------------------------------- */</font>
00213     <font class="keywordflow">if</font>( strchr(pszLine,<font class="charliteral">'\"'</font>) == NULL )
00214         <font class="keywordflow">return</font> CSLTokenizeStringComplex( pszLine, <font class="stringliteral">","</font>, TRUE, TRUE );
00215 
00216 <font class="comment">/* -------------------------------------------------------------------- */</font>
00217 <font class="comment">/*      We must now count the quotes in our working string, and as      */</font>
00218 <font class="comment">/*      long as it is odd, keep adding new lines.                       */</font>
00219 <font class="comment">/* -------------------------------------------------------------------- */</font>
00220     pszWorkLine = <a class="code" href="cpl_conv_h.html#a6">CPLStrdup</a>( pszLine );
00221 
00222     <font class="keywordflow">while</font>( TRUE )
00223     {
00224         <font class="keywordtype">int</font>             i, nCount = 0;
00225 
00226         <font class="keywordflow">for</font>( i = 0; pszWorkLine[i] != <font class="charliteral">'\0'</font>; i++ )
00227         {
00228             <font class="keywordflow">if</font>( pszWorkLine[i] == <font class="charliteral">'\"'</font>
00229                 &amp;&amp; (i == 0 || pszWorkLine[i-1] != <font class="charliteral">'\\'</font>) )
00230                 nCount++;
00231         }
00232 
00233         <font class="keywordflow">if</font>( nCount % 2 == 0 )
00234             <font class="keywordflow">break</font>;
00235 
00236         pszLine = <a class="code" href="cpl_conv_h.html#a7">CPLReadLine</a>( fp );
00237         <font class="keywordflow">if</font>( pszLine == NULL )
00238             <font class="keywordflow">break</font>;
00239 
00240         pszWorkLine = (<font class="keywordtype">char</font> *)
00241             <a class="code" href="cpl_conv_h.html#a5">CPLRealloc</a>(pszWorkLine,
00242                        strlen(pszWorkLine) + strlen(pszLine) + 1);
00243         strcat( pszWorkLine, pszLine );
00244     }
00245     
00246     papszReturn = CSLTokenizeStringComplex( pszWorkLine, <font class="stringliteral">","</font>, TRUE, TRUE );
00247 
00248     CPLFree( pszWorkLine );
00249 
00250     <font class="keywordflow">return</font> papszReturn;
00251 }
00252 
00253 <font class="comment">/************************************************************************/</font>
00254 <font class="comment">/*                             CSVCompare()                             */</font>
00255 <font class="comment">/*                                                                      */</font>
00256 <font class="comment">/*      Compare a field to a search value using a particular            */</font>
00257 <font class="comment">/*      criteria.                                                       */</font>
00258 <font class="comment">/************************************************************************/</font>
00259 
00260 <font class="keyword">static</font> <font class="keywordtype">int</font> CSVCompare( <font class="keyword">const</font> <font class="keywordtype">char</font> * pszFieldValue, <font class="keyword">const</font> <font class="keywordtype">char</font> * pszTarget,
00261                        CSVCompareCriteria eCriteria )<font class="keyword"></font>
00262 <font class="keyword"></font>
00263 <font class="keyword"></font>{
00264     <font class="keywordflow">if</font>( eCriteria == CC_ExactString )
00265     {
00266         <font class="keywordflow">return</font>( strcmp( pszFieldValue, pszTarget ) == 0 );
00267     }
00268     <font class="keywordflow">else</font> <font class="keywordflow">if</font>( eCriteria == CC_ApproxString )
00269     {
00270         <font class="keywordflow">return</font>( EQUAL( pszFieldValue, pszTarget ) );
00271     }
00272     <font class="keywordflow">else</font> <font class="keywordflow">if</font>( eCriteria == CC_Integer )
00273     {
00274         <font class="keywordflow">return</font>( atoi(pszFieldValue) == atoi(pszTarget) );
00275     }
00276 
00277     <font class="keywordflow">return</font> FALSE;
00278 }
00279 
00280 <font class="comment">/************************************************************************/</font>
00281 <font class="comment">/*                            CSVScanLines()                            */</font>
00282 <font class="comment">/*                                                                      */</font>
00283 <font class="comment">/*      Read the file scanline for lines where the key field equals     */</font>
00284 <font class="comment">/*      the indicated value with the suggested comparison criteria.     */</font>
00285 <font class="comment">/*      Return the first matching line split into fields.               */</font>
00286 <font class="comment">/************************************************************************/</font>
00287 
00288 <font class="keywordtype">char</font> **CSVScanLines( FILE *fp, <font class="keywordtype">int</font> iKeyField, <font class="keyword">const</font> <font class="keywordtype">char</font> * pszValue,
00289                      CSVCompareCriteria eCriteria )<font class="keyword"></font>
00290 <font class="keyword"></font>
00291 <font class="keyword"></font>{
00292     <font class="keywordtype">char</font>        **papszFields = NULL;
00293     <font class="keywordtype">int</font>         bSelected = FALSE, nTestValue;
00294 
00295     CPLAssert( pszValue != NULL );
00296     CPLAssert( iKeyField &gt;= 0 );
00297     CPLAssert( fp != NULL );
00298     
00299     nTestValue = atoi(pszValue);
00300     
00301     <font class="keywordflow">while</font>( !bSelected ) {
00302         papszFields = CSVReadParseLine( fp );
00303         <font class="keywordflow">if</font>( papszFields == NULL )
00304             <font class="keywordflow">return</font>( NULL );
00305 
00306         <font class="keywordflow">if</font>( CSLCount( papszFields ) &lt; iKeyField+1 )
00307         {
00308             <font class="comment">/* not selected */</font>
00309         }
00310         <font class="keywordflow">else</font> <font class="keywordflow">if</font>( eCriteria == CC_Integer
00311                  &amp;&amp; atoi(papszFields[iKeyField]) == nTestValue )
00312         {
00313             bSelected = TRUE;
00314         }
00315         <font class="keywordflow">else</font>
00316         {
00317             bSelected = CSVCompare( papszFields[iKeyField], pszValue,
00318                                     eCriteria );
00319         }
00320 
00321         <font class="keywordflow">if</font>( !bSelected )
00322         {
00323             CSLDestroy( papszFields );
00324             papszFields = NULL;
00325         }
00326     }
00327     
00328     <font class="keywordflow">return</font>( papszFields );
00329 }
00330 
00331 <font class="comment">/************************************************************************/</font>
00332 <font class="comment">/*                            CSVScanFile()                             */</font>
00333 <font class="comment">/*                                                                      */</font>
00334 <font class="comment">/*      Scan a whole file using criteria similar to above, but also     */</font>
00335 <font class="comment">/*      taking care of file opening and closing.                        */</font>
00336 <font class="comment">/************************************************************************/</font>
00337 
00338 <font class="keywordtype">char</font> **CSVScanFile( <font class="keyword">const</font> <font class="keywordtype">char</font> * pszFilename, <font class="keywordtype">int</font> iKeyField,
00339                     <font class="keyword">const</font> <font class="keywordtype">char</font> * pszValue, CSVCompareCriteria eCriteria )<font class="keyword"></font>
00340 <font class="keyword"></font>
00341 <font class="keyword"></font>{
00342     CSVTable    *psTable;
00343 
00344 <font class="comment">/* -------------------------------------------------------------------- */</font>
00345 <font class="comment">/*      Get access to the table.                                        */</font>
00346 <font class="comment">/* -------------------------------------------------------------------- */</font>
00347     CPLAssert( pszFilename != NULL );
00348 
00349     <font class="keywordflow">if</font>( iKeyField &lt; 0 )
00350         <font class="keywordflow">return</font> NULL;
00351 
00352     psTable = CSVAccess( pszFilename );
00353     <font class="keywordflow">if</font>( psTable == NULL )
00354         <font class="keywordflow">return</font> NULL;
00355 
00356 <font class="comment">/* -------------------------------------------------------------------- */</font>
00357 <font class="comment">/*      Does the current record match the criteria?  If so, just        */</font>
00358 <font class="comment">/*      return it again.                                                */</font>
00359 <font class="comment">/* -------------------------------------------------------------------- */</font>
00360     <font class="keywordflow">if</font>( iKeyField &gt;= 0
00361         &amp;&amp; iKeyField &lt; CSLCount(psTable-&gt;papszRecFields)
00362         &amp;&amp; CSVCompare(pszValue,psTable-&gt;papszRecFields[iKeyField],eCriteria) )
00363     {
00364         <font class="keywordflow">return</font> psTable-&gt;papszRecFields;
00365     }
00366 
00367 <font class="comment">/* -------------------------------------------------------------------- */</font>
00368 <font class="comment">/*      Scan the file from the beginning, replacing the ``current       */</font>
00369 <font class="comment">/*      record'' in our structure with the one that is found.           */</font>
00370 <font class="comment">/* -------------------------------------------------------------------- */</font>
00371     VSIRewind( psTable-&gt;fp );
00372     <a class="code" href="cpl_conv_h.html#a7">CPLReadLine</a>( psTable-&gt;fp );         <font class="comment">/* throw away the header line */</font>
00373     
00374     CSLDestroy( psTable-&gt;papszRecFields );
00375     psTable-&gt;papszRecFields =
00376         CSVScanLines( psTable-&gt;fp, iKeyField, pszValue, eCriteria );
00377 
00378     <font class="keywordflow">return</font>( psTable-&gt;papszRecFields );
00379 }
00380 
00381 <font class="comment">/************************************************************************/</font>
00382 <font class="comment">/*                           CPLGetFieldId()                            */</font>
00383 <font class="comment">/*                                                                      */</font>
00384 <font class="comment">/*      Read the first record of a CSV file (rewinding to be sure),     */</font>
00385 <font class="comment">/*      and find the field with the indicated name.  Returns -1 if      */</font>
00386 <font class="comment">/*      it fails to find the field name.  Comparison is case            */</font>
00387 <font class="comment">/*      insensitive, but otherwise exact.  After this function has      */</font>
00388 <font class="comment">/*      been called the file pointer will be positioned just after      */</font>
00389 <font class="comment">/*      the first record.                                               */</font>
00390 <font class="comment">/************************************************************************/</font>
00391 
00392 <font class="keywordtype">int</font> CSVGetFieldId( FILE * fp, <font class="keyword">const</font> <font class="keywordtype">char</font> * pszFieldName )<font class="keyword"></font>
00393 <font class="keyword"></font>
00394 <font class="keyword"></font>{
00395     <font class="keywordtype">char</font>        **papszFields;
00396     <font class="keywordtype">int</font>         i;
00397     
00398     CPLAssert( fp != NULL &amp;&amp; pszFieldName != NULL );
00399 
00400     VSIRewind( fp );
00401 
00402     papszFields = CSVReadParseLine( fp );
00403     <font class="keywordflow">for</font>( i = 0; papszFields != NULL &amp;&amp; papszFields[i] != NULL; i++ )
00404     {
00405         <font class="keywordflow">if</font>( EQUAL(papszFields[i],pszFieldName) )
00406         {
00407             CSLDestroy( papszFields );
00408             <font class="keywordflow">return</font> i;
00409         }
00410     }
00411 
00412     CSLDestroy( papszFields );
00413 
00414     <font class="keywordflow">return</font> -1;
00415 }
00416 
00417 <font class="comment">/************************************************************************/</font>
00418 <font class="comment">/*                         CSVGetFileFieldId()                          */</font>
00419 <font class="comment">/*                                                                      */</font>
00420 <font class="comment">/*      Same as CPLGetFieldId(), except that we get the file based      */</font>
00421 <font class="comment">/*      on filename, rather than having an existing handle.             */</font>
00422 <font class="comment">/************************************************************************/</font>
00423 
00424 <font class="keywordtype">int</font> CSVGetFileFieldId( <font class="keyword">const</font> <font class="keywordtype">char</font> * pszFilename, <font class="keyword">const</font> <font class="keywordtype">char</font> * pszFieldName )<font class="keyword"></font>
00425 <font class="keyword"></font>
00426 <font class="keyword"></font>{
00427     CSVTable    *psTable;
00428     <font class="keywordtype">int</font>         i;
00429     
00430 <font class="comment">/* -------------------------------------------------------------------- */</font>
00431 <font class="comment">/*      Get access to the table.                                        */</font>
00432 <font class="comment">/* -------------------------------------------------------------------- */</font>
00433     CPLAssert( pszFilename != NULL );
00434 
00435     psTable = CSVAccess( pszFilename );
00436     <font class="keywordflow">if</font>( psTable == NULL )
00437         <font class="keywordflow">return</font> -1;
00438 
00439 <font class="comment">/* -------------------------------------------------------------------- */</font>
00440 <font class="comment">/*      Find the requested field.                                       */</font>
00441 <font class="comment">/* -------------------------------------------------------------------- */</font>
00442     <font class="keywordflow">for</font>( i = 0;
00443          psTable-&gt;papszFieldNames != NULL
00444              &amp;&amp; psTable-&gt;papszFieldNames[i] != NULL;
00445          i++ )
00446     {
00447         <font class="keywordflow">if</font>( EQUAL(psTable-&gt;papszFieldNames[i],pszFieldName) )
00448         {
00449             <font class="keywordflow">return</font> i;
00450         }
00451     }
00452 
00453     <font class="keywordflow">return</font> -1;
00454 }
00455 
00456 
00457 <font class="comment">/************************************************************************/</font>
00458 <font class="comment">/*                         CSVScanFileByName()                          */</font>
00459 <font class="comment">/*                                                                      */</font>
00460 <font class="comment">/*      Same as CSVScanFile(), but using a field name instead of a      */</font>
00461 <font class="comment">/*      field number.                                                   */</font>
00462 <font class="comment">/************************************************************************/</font>
00463 
00464 <font class="keywordtype">char</font> **CSVScanFileByName( <font class="keyword">const</font> <font class="keywordtype">char</font> * pszFilename,
00465                           <font class="keyword">const</font> <font class="keywordtype">char</font> * pszKeyFieldName,
00466                           <font class="keyword">const</font> <font class="keywordtype">char</font> * pszValue, CSVCompareCriteria eCriteria )<font class="keyword"></font>
00467 <font class="keyword"></font>
00468 <font class="keyword"></font>{
00469     <font class="keywordtype">int</font>         iKeyField;
00470 
00471     iKeyField = CSVGetFileFieldId( pszFilename, pszKeyFieldName );
00472     <font class="keywordflow">if</font>( iKeyField == -1 )
00473         <font class="keywordflow">return</font> NULL;
00474 
00475     <font class="keywordflow">return</font>( CSVScanFile( pszFilename, iKeyField, pszValue, eCriteria ) );
00476 }
00477 
00478 <font class="comment">/************************************************************************/</font>
00479 <font class="comment">/*                            CSVGetField()                             */</font>
00480 <font class="comment">/*                                                                      */</font>
00481 <font class="comment">/*      The all-in-one function to fetch a particular field value       */</font>
00482 <font class="comment">/*      from a CSV file.  Note this function will return an empty       */</font>
00483 <font class="comment">/*      string, rather than NULL if it fails to find the desired        */</font>
00484 <font class="comment">/*      value for some reason.  The caller can't establish that the     */</font>
00485 <font class="comment">/*      fetch failed.                                                   */</font>
00486 <font class="comment">/************************************************************************/</font>
00487 
00488 <font class="keyword">const</font> <font class="keywordtype">char</font> *CSVGetField( <font class="keyword">const</font> <font class="keywordtype">char</font> * pszFilename,
00489                          <font class="keyword">const</font> <font class="keywordtype">char</font> * pszKeyFieldName,
00490                          <font class="keyword">const</font> <font class="keywordtype">char</font> * pszKeyFieldValue,
00491                          CSVCompareCriteria eCriteria,
00492                          <font class="keyword">const</font> <font class="keywordtype">char</font> * pszTargetField )<font class="keyword"></font>
00493 <font class="keyword"></font>
00494 <font class="keyword"></font>{
00495     CSVTable    *psTable;
00496     <font class="keywordtype">char</font>        **papszRecord;
00497     <font class="keywordtype">int</font>         iTargetField;
00498     
00499 <font class="comment">/* -------------------------------------------------------------------- */</font>
00500 <font class="comment">/*      Find the table.                                                 */</font>
00501 <font class="comment">/* -------------------------------------------------------------------- */</font>
00502     psTable = CSVAccess( pszFilename );
00503     <font class="keywordflow">if</font>( psTable == NULL )
00504         <font class="keywordflow">return</font> <font class="stringliteral">""</font>;
00505 
00506 <font class="comment">/* -------------------------------------------------------------------- */</font>
00507 <font class="comment">/*      Find the correct record.                                        */</font>
00508 <font class="comment">/* -------------------------------------------------------------------- */</font>
00509     papszRecord = CSVScanFileByName( pszFilename, pszKeyFieldName,
00510                                      pszKeyFieldValue, eCriteria );
00511 
00512     <font class="keywordflow">if</font>( papszRecord == NULL )
00513         <font class="keywordflow">return</font> <font class="stringliteral">""</font>;
00514 
00515 <font class="comment">/* -------------------------------------------------------------------- */</font>
00516 <font class="comment">/*      Figure out which field we want out of this.                     */</font>
00517 <font class="comment">/* -------------------------------------------------------------------- */</font>
00518     iTargetField = CSVGetFileFieldId( pszFilename, pszTargetField );
00519     <font class="keywordflow">if</font>( iTargetField &lt; 0 )
00520         <font class="keywordflow">return</font> <font class="stringliteral">""</font>;
00521 
00522     <font class="keywordflow">if</font>( iTargetField &gt;= CSLCount( papszRecord ) )
00523         <font class="keywordflow">return</font> <font class="stringliteral">""</font>;
00524 
00525     <font class="keywordflow">return</font>( papszRecord[iTargetField] );
00526 }
00527 
00528 <font class="comment">/************************************************************************/</font>
00529 <font class="comment">/*                            CSVFilename()                             */</font>
00530 <font class="comment">/*                                                                      */</font>
00531 <font class="comment">/*      Return the full path to a particular CSV file.  This will       */</font>
00532 <font class="comment">/*      eventually be something the application can override.           */</font>
00533 <font class="comment">/************************************************************************/</font>
00534 
00535 <font class="keyword">static</font> <font class="keyword">const</font> <font class="keywordtype">char</font> *(*pfnCSVFilenameHook)(<font class="keyword">const</font> <font class="keywordtype">char</font> *) = NULL;
00536 
00537 <font class="keyword">const</font> <font class="keywordtype">char</font> * CSVFilename( <font class="keyword">const</font> <font class="keywordtype">char</font> *pszBasename )<font class="keyword"></font>
00538 <font class="keyword"></font>
00539 <font class="keyword"></font>{
00540     <font class="keyword">static</font> <font class="keywordtype">char</font>         szPath[512];
00541 
00542     <font class="keywordflow">if</font>( pfnCSVFilenameHook == NULL )
00543     {
00544         FILE    *fp = NULL;
00545         <font class="keyword">const</font> <font class="keywordtype">char</font> *pszResult = CPLFindFile( <font class="stringliteral">"epsg_csv"</font>, pszBasename );
00546 
00547         <font class="keywordflow">if</font>( pszResult != NULL )
00548             <font class="keywordflow">return</font> pszResult;
00549 
00550         <font class="keywordflow">if</font>( getenv(<font class="stringliteral">"GEOTIFF_CSV"</font>) != NULL )
00551         {
00552             sprintf( szPath, <font class="stringliteral">"%s/%s"</font>, getenv(<font class="stringliteral">"GEOTIFF_CSV"</font>), pszBasename );
00553         }
00554         <font class="keywordflow">else</font> <font class="keywordflow">if</font>( (fp = fopen( <font class="stringliteral">"csv/horiz_cs.csv"</font>, <font class="stringliteral">"rt"</font> )) != NULL )
00555         {
00556             sprintf( szPath, <font class="stringliteral">"csv/%s"</font>, pszBasename );
00557         }
00558         <font class="keywordflow">else</font>
00559         {
00560             sprintf( szPath, <font class="stringliteral">"/usr/local/share/epsg_csv/%s"</font>, pszBasename );
00561         }
00562 
00563         <font class="keywordflow">if</font>( fp != NULL )
00564             fclose( fp );
00565         
00566         <font class="keywordflow">return</font>( szPath );
00567     }
00568     <font class="keywordflow">else</font>
00569         <font class="keywordflow">return</font>( pfnCSVFilenameHook( pszBasename ) );
00570 }
00571 
00572 <font class="comment">/************************************************************************/</font>
00573 <font class="comment">/*                         SetCSVFilenameHook()                         */</font>
00574 <font class="comment">/*                                                                      */</font>
00575 <font class="comment">/*      Applications can use this to set a function that will           */</font>
00576 <font class="comment">/*      massage CSV filenames.                                          */</font>
00577 <font class="comment">/************************************************************************/</font>
00578 
00623 <font class="keywordtype">void</font> SetCSVFilenameHook( <font class="keyword">const</font> <font class="keywordtype">char</font> *(*pfnNewHook)( <font class="keyword">const</font> <font class="keywordtype">char</font> * ) )
00624 
00625 {
00626     pfnCSVFilenameHook = pfnNewHook;
00627 }
</div></pre><hr><address><small>Generated at Thu Mar 28 09:47:27 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>