LTP GCOV extension - code coverage report
Current view: directory - ogr - ogrutils.cpp
Test: gdal_filtered.info
Date: 2010-07-12 Instrumented lines: 486
Code covered: 70.2 % Executed lines: 341

       1                 : /******************************************************************************
       2                 :  * $Id: ogrutils.cpp 19722 2010-05-15 11:35:37Z rouault $
       3                 :  *
       4                 :  * Project:  OpenGIS Simple Features Reference Implementation
       5                 :  * Purpose:  Utility functions for OGR classes, including some related to
       6                 :  *           parsing well known text format vectors.
       7                 :  * Author:   Frank Warmerdam, warmerdam@pobox.com
       8                 :  *
       9                 :  ******************************************************************************
      10                 :  * Copyright (c) 1999, Frank Warmerdam
      11                 :  *
      12                 :  * Permission is hereby granted, free of charge, to any person obtaining a
      13                 :  * copy of this software and associated documentation files (the "Software"),
      14                 :  * to deal in the Software without restriction, including without limitation
      15                 :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      16                 :  * and/or sell copies of the Software, and to permit persons to whom the
      17                 :  * Software is furnished to do so, subject to the following conditions:
      18                 :  *
      19                 :  * The above copyright notice and this permission notice shall be included
      20                 :  * in all copies or substantial portions of the Software.
      21                 :  *
      22                 :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
      23                 :  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      24                 :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
      25                 :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      26                 :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      27                 :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      28                 :  * DEALINGS IN THE SOFTWARE.
      29                 :  ****************************************************************************/
      30                 : 
      31                 : #include <ctype.h>
      32                 : 
      33                 : #include "ogr_geometry.h"
      34                 : #include "ogr_p.h"
      35                 : 
      36                 : #ifdef OGR_ENABLED
      37                 : # include "ogrsf_frmts.h"
      38                 : #endif /* OGR_ENABLED */
      39                 : 
      40                 : CPL_CVSID("$Id: ogrutils.cpp 19722 2010-05-15 11:35:37Z rouault $");
      41                 : 
      42                 : /************************************************************************/
      43                 : /*                        OGRFormatDouble()                             */
      44                 : /************************************************************************/
      45                 : 
      46            9783 : void OGRFormatDouble( char *pszBuffer, int nBufferLen, double dfVal, char chDecimalSep, int nPrecision )
      47                 : {
      48                 :     int i;
      49            9783 :     int bHasTruncated = FALSE;
      50                 :     char szFormat[16];
      51            9783 :     sprintf(szFormat, "%%.%df", nPrecision);
      52                 : 
      53            9783 :     int ret = snprintf(pszBuffer, nBufferLen, szFormat, dfVal);
      54                 :     /* Windows CRT doesn't conform with C99 and return -1 when buffer is truncated */
      55            9783 :     if (ret >= nBufferLen || ret == -1)
      56               2 :         return;
      57                 : 
      58               2 :     while(TRUE)
      59                 :     {
      60            9783 :         i = 0;
      61          224716 :         while( pszBuffer[i] != '\0' )
      62                 :         {
      63          205150 :             if ((pszBuffer[i] == '.' || pszBuffer[i] == ',') && chDecimalSep != '\0')
      64            9783 :                 pszBuffer[i] = chDecimalSep;
      65          205150 :             i++;
      66                 :         }
      67                 : 
      68                 :     /* -------------------------------------------------------------------- */
      69                 :     /*      Trim trailing 00000x's as they are likely roundoff error.       */
      70                 :     /* -------------------------------------------------------------------- */
      71            9783 :         if( i > 10)
      72                 :         {
      73           17796 :             if (/* && pszBuffer[i-1] == '1' &&*/
      74                 :                 pszBuffer[i-2] == '0' 
      75                 :                 && pszBuffer[i-3] == '0' 
      76                 :                 && pszBuffer[i-4] == '0' 
      77                 :                 && pszBuffer[i-5] == '0' 
      78                 :                 && pszBuffer[i-6] == '0' )
      79                 :             {
      80            8389 :                 pszBuffer[--i] = '\0';
      81                 :             }
      82            1018 :             else if( /* pszBuffer[i-1] == '1' */
      83                 :                   /* && pszBuffer[i-2] == '0' && */
      84                 :                     pszBuffer[i-3] == '0' 
      85                 :                     && pszBuffer[i-4] == '0' 
      86                 :                     && pszBuffer[i-5] == '0' 
      87                 :                     && pszBuffer[i-6] == '0'
      88                 :                     && pszBuffer[i-7] == '0'
      89                 :                     && pszBuffer[i-8] == '0'
      90                 :                     && pszBuffer[i-9] == '0')
      91                 :             {
      92               0 :                 pszBuffer[--i] = '\0';
      93               0 :                 pszBuffer[--i] = '\0';
      94                 :             }
      95                 :         }
      96                 : 
      97                 :     /* -------------------------------------------------------------------- */
      98                 :     /*      Trim trailing zeros.                                            */
      99                 :     /* -------------------------------------------------------------------- */
     100          115309 :         while( i > 2 && pszBuffer[i-1] == '0' && pszBuffer[i-2] != '.' )
     101                 :         {
     102           95743 :             pszBuffer[--i] = '\0';
     103                 :         }
     104                 : 
     105                 :     /* -------------------------------------------------------------------- */
     106                 :     /*      Detect trailing 99999X's as they are likely roundoff error.     */
     107                 :     /* -------------------------------------------------------------------- */
     108            9783 :         if( !bHasTruncated &&
     109                 :             i > 10 &&
     110                 :             nPrecision >= 15)
     111                 :         {
     112            4072 :             if (/*pszBuffer[i-1] == '9' && */
     113                 :                  pszBuffer[i-2] == '9' 
     114                 :                 && pszBuffer[i-3] == '9' 
     115                 :                 && pszBuffer[i-4] == '9' 
     116                 :                 && pszBuffer[i-5] == '9' 
     117                 :                 && pszBuffer[i-6] == '9' )
     118                 :             {
     119               2 :                 snprintf(pszBuffer, nBufferLen, "%.10f", dfVal);
     120               2 :                 bHasTruncated = TRUE;
     121               2 :                 continue;
     122                 :             }
     123            4070 :             else if (/*pszBuffer[i-1] == '9' && */
     124                 :                      /*pszBuffer[i-2] == '9' && */
     125                 :                     pszBuffer[i-3] == '9' 
     126                 :                     && pszBuffer[i-4] == '9' 
     127                 :                     && pszBuffer[i-5] == '9' 
     128                 :                     && pszBuffer[i-6] == '9'
     129                 :                     && pszBuffer[i-7] == '9'
     130                 :                     && pszBuffer[i-8] == '9'
     131                 :                     && pszBuffer[i-9] == '9')
     132                 :             {
     133               0 :                 snprintf(pszBuffer, nBufferLen, "%.10f", dfVal);
     134               0 :                 bHasTruncated = TRUE;
     135               0 :                 continue;
     136                 :             }
     137                 :         }
     138                 : 
     139            9781 :         break;
     140                 :     }
     141                 : 
     142                 : }
     143                 : 
     144                 : /************************************************************************/
     145                 : /*                        OGRMakeWktCoordinate()                        */
     146                 : /*                                                                      */
     147                 : /*      Format a well known text coordinate, trying to keep the         */
     148                 : /*      ASCII representation compact, but accurate.  These rules        */
     149                 : /*      will have to tighten up in the future.                          */
     150                 : /*                                                                      */
     151                 : /*      Currently a new point should require no more than 64            */
     152                 : /*      characters barring the X or Y value being extremely large.      */
     153                 : /************************************************************************/
     154                 : 
     155                 : void OGRMakeWktCoordinate( char *pszTarget, double x, double y, double z, 
     156            5678 :                            int nDimension )
     157                 : 
     158                 : {
     159            5678 :     const size_t bufSize = 75;
     160            5678 :     const size_t maxTargetSize = 75; /* Assumed max length of the target buffer. */
     161                 : 
     162                 :     char szX[bufSize];
     163                 :     char szY[bufSize];
     164                 :     char szZ[bufSize];
     165                 : 
     166            5678 :     szZ[0] = '\0';
     167                 : 
     168                 :     int nLenX, nLenY;
     169                 : 
     170            6773 :     if( x == (int) x && y == (int) y )
     171                 :     {
     172            1095 :         snprintf( szX, bufSize, "%d", (int) x );
     173            1095 :         snprintf( szY, bufSize, "%d", (int) y );
     174                 :     }
     175                 :     else
     176                 :     {
     177            4583 :         OGRFormatDouble( szX, bufSize, x, '.' );
     178            4583 :         OGRFormatDouble( szY, bufSize, y, '.' );
     179                 :     }
     180                 : 
     181            5678 :     nLenX = strlen(szX);
     182            5678 :     nLenY = strlen(szY);
     183                 : 
     184            5678 :     if( nDimension == 3 )
     185                 :     {
     186             652 :         if( z == (int) z )
     187                 :         {
     188             645 :             snprintf( szZ, bufSize, "%d", (int) z );
     189                 :         }
     190                 :         else
     191                 :         {
     192               7 :             OGRFormatDouble( szZ, bufSize, z, '.' );
     193                 :         }
     194                 :     }
     195                 : 
     196            5678 :     if( nLenX + 1 + nLenY + ((nDimension == 3) ? (1 + strlen(szZ)) : 0) >= maxTargetSize )
     197                 :     {
     198                 : #ifdef DEBUG
     199                 :         CPLDebug( "OGR", 
     200                 :                   "Yow!  Got this big result in OGRMakeWktCoordinate()\n"
     201                 :                   "%s %s %s", 
     202               1 :                   szX, szY, szZ );
     203                 : #endif
     204               1 :         if( nDimension == 3 )
     205               1 :             strcpy( pszTarget, "0 0 0");
     206                 :         else
     207               0 :             strcpy( pszTarget, "0 0");
     208                 :     }
     209                 :     else
     210                 :     {
     211            5677 :         memcpy( pszTarget, szX, nLenX );
     212            5677 :         pszTarget[nLenX] = ' ';
     213            5677 :         memcpy( pszTarget + nLenX + 1, szY, nLenY );
     214            5677 :         if (nDimension == 3)
     215                 :         {
     216             651 :             pszTarget[nLenX + 1 + nLenY] = ' ';
     217             651 :             strcpy( pszTarget + nLenX + 1 + nLenY + 1, szZ );
     218                 :         }
     219                 :         else
     220                 :         {
     221            5026 :             pszTarget[nLenX + 1 + nLenY] = '\0';
     222                 :         }
     223                 :     }
     224            5678 : }
     225                 : 
     226                 : /************************************************************************/
     227                 : /*                          OGRWktReadToken()                           */
     228                 : /*                                                                      */
     229                 : /*      Read one token or delimeter and put into token buffer.  Pre     */
     230                 : /*      and post white space is swallowed.                              */
     231                 : /************************************************************************/
     232                 : 
     233          143412 : const char *OGRWktReadToken( const char * pszInput, char * pszToken )
     234                 : 
     235                 : {
     236          143412 :     if( pszInput == NULL )
     237               0 :         return NULL;
     238                 :     
     239                 : /* -------------------------------------------------------------------- */
     240                 : /*      Swallow pre-white space.                                        */
     241                 : /* -------------------------------------------------------------------- */
     242          286825 :     while( *pszInput == ' ' || *pszInput == '\t' )
     243               1 :         pszInput++;
     244                 : 
     245                 : /* -------------------------------------------------------------------- */
     246                 : /*      If this is a delimeter, read just one character.                */
     247                 : /* -------------------------------------------------------------------- */
     248          181857 :     if( *pszInput == '(' || *pszInput == ')' || *pszInput == ',' )
     249                 :     {
     250           38445 :         pszToken[0] = *pszInput;
     251           38445 :         pszToken[1] = '\0';
     252                 :         
     253           38445 :         pszInput++;
     254                 :     }
     255                 : 
     256                 : /* -------------------------------------------------------------------- */
     257                 : /*      Or if it alpha numeric read till we reach non-alpha numeric     */
     258                 : /*      text.                                                           */
     259                 : /* -------------------------------------------------------------------- */
     260                 :     else
     261                 :     {
     262          104967 :         int             iChar = 0;
     263                 :         
     264          940019 :         while( iChar < OGR_WKT_TOKEN_MAX-1
     265                 :                && ((*pszInput >= 'a' && *pszInput <= 'z')
     266                 :                    || (*pszInput >= 'A' && *pszInput <= 'Z')
     267                 :                    || (*pszInput >= '0' && *pszInput <= '9')
     268                 :                    || *pszInput == '.' 
     269                 :                    || *pszInput == '+' 
     270                 :                    || *pszInput == '-') )
     271                 :         {
     272          730085 :             pszToken[iChar++] = *(pszInput++);
     273                 :         }
     274                 : 
     275          104967 :         pszToken[iChar++] = '\0';
     276                 :     }
     277                 : 
     278                 : /* -------------------------------------------------------------------- */
     279                 : /*      Eat any trailing white space.                                   */
     280                 : /* -------------------------------------------------------------------- */
     281          340006 :     while( *pszInput == ' ' || *pszInput == '\t' )
     282           53182 :         pszInput++;
     283                 : 
     284          143412 :     return( pszInput );
     285                 : }
     286                 : 
     287                 : /************************************************************************/
     288                 : /*                          OGRWktReadPoints()                          */
     289                 : /*                                                                      */
     290                 : /*      Read a point string.  The point list must be contained in       */
     291                 : /*      brackets and each point pair separated by a comma.              */
     292                 : /************************************************************************/
     293                 : 
     294                 : const char * OGRWktReadPoints( const char * pszInput,
     295                 :                                OGRRawPoint ** ppaoPoints, double **ppadfZ,
     296                 :                                int * pnMaxPoints,
     297           15901 :                                int * pnPointsRead )
     298                 : 
     299                 : {
     300           15901 :     const char *pszOrigInput = pszInput;
     301           15901 :     *pnPointsRead = 0;
     302                 : 
     303           15901 :     if( pszInput == NULL )
     304               0 :         return NULL;
     305                 :     
     306                 : /* -------------------------------------------------------------------- */
     307                 : /*      Eat any leading white space.                                    */
     308                 : /* -------------------------------------------------------------------- */
     309           31802 :     while( *pszInput == ' ' || *pszInput == '\t' )
     310               0 :         pszInput++;
     311                 : 
     312                 : /* -------------------------------------------------------------------- */
     313                 : /*      If this isn't an opening bracket then we have a problem!        */
     314                 : /* -------------------------------------------------------------------- */
     315           15901 :     if( *pszInput != '(' )
     316                 :     {
     317                 :         CPLDebug( "OGR",
     318                 :                   "Expected '(', but got %s in OGRWktReadPoints().\n",
     319              39 :                   pszInput );
     320                 :                   
     321              39 :         return pszInput;
     322                 :     }
     323                 : 
     324           15862 :     pszInput++;
     325                 : 
     326                 : /* ==================================================================== */
     327                 : /*      This loop reads a single point.  It will continue till we       */
     328                 : /*      run out of well formed points, or a closing bracket is          */
     329                 : /*      encountered.                                                    */
     330                 : /* ==================================================================== */
     331                 :     char        szDelim[OGR_WKT_TOKEN_MAX];
     332                 :     
     333           19950 :     do {
     334                 : /* -------------------------------------------------------------------- */
     335                 : /*      Read the X and Y values, verify they are numeric.               */
     336                 : /* -------------------------------------------------------------------- */
     337                 :         char    szTokenX[OGR_WKT_TOKEN_MAX];
     338                 :         char    szTokenY[OGR_WKT_TOKEN_MAX];
     339                 : 
     340           19998 :         pszInput = OGRWktReadToken( pszInput, szTokenX );
     341           19998 :         pszInput = OGRWktReadToken( pszInput, szTokenY );
     342                 : 
     343           19998 :         if( (!isdigit(szTokenX[0]) && szTokenX[0] != '-' && szTokenX[0] != '.' )
     344                 :             || (!isdigit(szTokenY[0]) && szTokenY[0] != '-' && szTokenY[0] != '.') )
     345              38 :             return NULL;
     346                 : 
     347                 : /* -------------------------------------------------------------------- */
     348                 : /*      Do we need to grow the point list to hold this point?           */
     349                 : /* -------------------------------------------------------------------- */
     350           19960 :         if( *pnPointsRead == *pnMaxPoints )
     351                 :         {
     352           15682 :             *pnMaxPoints = *pnMaxPoints * 2 + 10;
     353                 :             *ppaoPoints = (OGRRawPoint *)
     354           15682 :                 CPLRealloc(*ppaoPoints, sizeof(OGRRawPoint) * *pnMaxPoints);
     355                 : 
     356           15682 :             if( *ppadfZ != NULL )
     357                 :             {
     358                 :                 *ppadfZ = (double *)
     359              53 :                     CPLRealloc(*ppadfZ, sizeof(double) * *pnMaxPoints);
     360                 :             }
     361                 :         }
     362                 : 
     363                 : /* -------------------------------------------------------------------- */
     364                 : /*      Add point to list.                                              */
     365                 : /* -------------------------------------------------------------------- */
     366           19960 :         (*ppaoPoints)[*pnPointsRead].x = CPLAtof(szTokenX);
     367           19960 :         (*ppaoPoints)[*pnPointsRead].y = CPLAtof(szTokenY);
     368                 : 
     369                 : /* -------------------------------------------------------------------- */
     370                 : /*      Do we have a Z coordinate?                                      */
     371                 : /* -------------------------------------------------------------------- */
     372           19960 :         pszInput = OGRWktReadToken( pszInput, szDelim );
     373                 : 
     374           19960 :         if( isdigit(szDelim[0]) || szDelim[0] == '-' || szDelim[0] == '.' )
     375                 :         {
     376           16421 :             if( *ppadfZ == NULL )
     377                 :             {
     378           14864 :                 *ppadfZ = (double *) CPLCalloc(sizeof(double),*pnMaxPoints);
     379                 :             }
     380                 : 
     381           16421 :             (*ppadfZ)[*pnPointsRead] = CPLAtof(szDelim);
     382                 :             
     383           16421 :             pszInput = OGRWktReadToken( pszInput, szDelim );
     384                 :         }
     385                 :         
     386           19960 :         (*pnPointsRead)++;
     387                 : 
     388                 : /* -------------------------------------------------------------------- */
     389                 : /*      Do we have a M coordinate?                                      */
     390                 : /*      If we do, just skip it.                                         */
     391                 : /* -------------------------------------------------------------------- */
     392           19960 :         if( isdigit(szDelim[0]) || szDelim[0] == '-' || szDelim[0] == '.' )
     393                 :         {
     394              54 :             pszInput = OGRWktReadToken( pszInput, szDelim );
     395                 :         }
     396                 :         
     397                 : /* -------------------------------------------------------------------- */
     398                 : /*      Read next delimeter ... it should be a comma if there are       */
     399                 : /*      more points.                                                    */
     400                 : /* -------------------------------------------------------------------- */
     401           19960 :         if( szDelim[0] != ')' && szDelim[0] != ',' )
     402                 :         {
     403                 :             CPLDebug( "OGR",
     404                 :                       "Corrupt input in OGRWktReadPoints()\n"
     405                 :                       "Got `%s' when expecting `,' or `)', near `%s' in %s.\n",
     406              10 :                       szDelim, pszInput, pszOrigInput );
     407              10 :             return NULL;
     408                 :         }
     409                 :         
     410                 :     } while( szDelim[0] == ',' );
     411                 : 
     412           15814 :     return pszInput;
     413                 : }
     414                 : 
     415                 : /************************************************************************/
     416                 : /*                             OGRMalloc()                              */
     417                 : /*                                                                      */
     418                 : /*      Cover for CPLMalloc()                                           */
     419                 : /************************************************************************/
     420                 : 
     421               0 : void *OGRMalloc( size_t size )
     422                 : 
     423                 : {
     424               0 :     return CPLMalloc( size );
     425                 : }
     426                 : 
     427                 : /************************************************************************/
     428                 : /*                             OGRCalloc()                              */
     429                 : /*                                                                      */
     430                 : /*      Cover for CPLCalloc()                                           */
     431                 : /************************************************************************/
     432                 : 
     433            5267 : void * OGRCalloc( size_t count, size_t size )
     434                 : 
     435                 : {
     436            5267 :     return CPLCalloc( count, size );
     437                 : }
     438                 : 
     439                 : /************************************************************************/
     440                 : /*                             OGRRealloc()                             */
     441                 : /*                                                                      */
     442                 : /*      Cover for CPLRealloc()                                          */
     443                 : /************************************************************************/
     444                 : 
     445           45982 : void *OGRRealloc( void * pOld, size_t size )
     446                 : 
     447                 : {
     448           45982 :     return CPLRealloc( pOld, size );
     449                 : }
     450                 : 
     451                 : /************************************************************************/
     452                 : /*                              OGRFree()                               */
     453                 : /*                                                                      */
     454                 : /*      Cover for CPLFree().                                            */
     455                 : /************************************************************************/
     456                 : 
     457           30857 : void OGRFree( void * pMemory )
     458                 : 
     459                 : {
     460           30857 :     CPLFree( pMemory );
     461           30857 : }
     462                 : 
     463                 : /**
     464                 :  * General utility option processing.
     465                 :  *
     466                 :  * This function is intended to provide a variety of generic commandline 
     467                 :  * options for all OGR commandline utilities.  It takes care of the following
     468                 :  * commandline options:
     469                 :  *  
     470                 :  *  --formats: report all format drivers configured.
     471                 :  *  --optfile filename: expand an option file into the argument list. 
     472                 :  *  --config key value: set system configuration option. 
     473                 :  *  --debug [on/off/value]: set debug level.
     474                 :  *  --help-general: report detailed help on general options. 
     475                 :  *
     476                 :  * The argument array is replaced "in place" and should be freed with 
     477                 :  * CSLDestroy() when no longer needed.  The typical usage looks something
     478                 :  * like the following.  Note that the formats should be registered so that
     479                 :  * the --formats option will work properly.
     480                 :  *
     481                 :  *  int main( int argc, char ** argv )
     482                 :  *  { 
     483                 :  *    OGRAllRegister();
     484                 :  *
     485                 :  *    argc = OGRGeneralCmdLineProcessor( argc, &argv, 0 );
     486                 :  *    if( argc < 1 )
     487                 :  *        exit( -argc );
     488                 :  *
     489                 :  * @param nArgc number of values in the argument list.
     490                 :  * @param Pointer to the argument list array (will be updated in place). 
     491                 :  *
     492                 :  * @return updated nArgc argument count.  Return of 0 requests terminate 
     493                 :  * without error, return of -1 requests exit with error code.
     494                 :  */
     495                 : 
     496              87 : int OGRGeneralCmdLineProcessor( int nArgc, char ***ppapszArgv, int nOptions )
     497                 : 
     498                 : {
     499              87 :     char **papszReturn = NULL;
     500                 :     int  iArg;
     501              87 :     char **papszArgv = *ppapszArgv;
     502                 : 
     503                 :     (void) nOptions;
     504                 :     
     505                 : /* -------------------------------------------------------------------- */
     506                 : /*      Preserve the program name.                                      */
     507                 : /* -------------------------------------------------------------------- */
     508              87 :     papszReturn = CSLAddString( papszReturn, papszArgv[0] );
     509                 : 
     510                 : /* ==================================================================== */
     511                 : /*      Loop over all arguments.                                        */
     512                 : /* ==================================================================== */
     513             448 :     for( iArg = 1; iArg < nArgc; iArg++ )
     514                 :     {
     515                 : /* -------------------------------------------------------------------- */
     516                 : /*      --version                                                       */
     517                 : /* -------------------------------------------------------------------- */
     518             361 :         if( EQUAL(papszArgv[iArg],"--version") )
     519                 :         {
     520               0 :             printf( "%s\n", GDALVersionInfo( "--version" ) );
     521               0 :             CSLDestroy( papszReturn );
     522               0 :             return 0;
     523                 :         }
     524                 : 
     525                 : /* -------------------------------------------------------------------- */
     526                 : /*      --license                                                       */
     527                 : /* -------------------------------------------------------------------- */
     528             361 :         else if( EQUAL(papszArgv[iArg],"--license") )
     529                 :         {
     530               0 :             printf( "%s\n", GDALVersionInfo( "LICENSE" ) );
     531               0 :             CSLDestroy( papszReturn );
     532               0 :             return 0;
     533                 :         }
     534                 : 
     535                 : /* -------------------------------------------------------------------- */
     536                 : /*      --config                                                        */
     537                 : /* -------------------------------------------------------------------- */
     538             361 :         else if( EQUAL(papszArgv[iArg],"--config") )
     539                 :         {
     540               0 :             if( iArg + 2 >= nArgc )
     541                 :             {
     542                 :                 CPLError( CE_Failure, CPLE_AppDefined, 
     543               0 :                           "--config option given without a key and value argument." );
     544               0 :                 CSLDestroy( papszReturn );
     545               0 :                 return -1;
     546                 :             }
     547                 : 
     548               0 :             CPLSetConfigOption( papszArgv[iArg+1], papszArgv[iArg+2] );
     549                 : 
     550               0 :             iArg += 2;
     551                 :         }
     552                 : 
     553                 : /* -------------------------------------------------------------------- */
     554                 : /*      --mempreload                                                    */
     555                 : /* -------------------------------------------------------------------- */
     556             361 :         else if( EQUAL(papszArgv[iArg],"--mempreload") )
     557                 :         {
     558                 :             int i;
     559                 : 
     560               0 :             if( iArg + 1 >= nArgc )
     561                 :             {
     562                 :                 CPLError( CE_Failure, CPLE_AppDefined, 
     563               0 :                           "--mempreload option given without directory path.");
     564               0 :                 CSLDestroy( papszReturn );
     565               0 :                 return -1;
     566                 :             }
     567                 :             
     568               0 :             char **papszFiles = CPLReadDir( papszArgv[iArg+1] );
     569               0 :             if( CSLCount(papszFiles) == 0 )
     570                 :             {
     571                 :                 CPLError( CE_Failure, CPLE_AppDefined, 
     572               0 :                           "--mempreload given invalid or empty directory.");
     573               0 :                 CSLDestroy( papszReturn );
     574               0 :                 return -1;
     575                 :             }
     576                 :                 
     577               0 :             for( i = 0; papszFiles[i] != NULL; i++ )
     578                 :             {
     579               0 :                 CPLString osOldPath, osNewPath;
     580                 :                 
     581               0 :                 if( EQUAL(papszFiles[i],".") || EQUAL(papszFiles[i],"..") )
     582               0 :                     continue;
     583                 : 
     584                 :                 osOldPath = CPLFormFilename( papszArgv[iArg+1], 
     585               0 :                                              papszFiles[i], NULL );
     586               0 :                 osNewPath.Printf( "/vsimem/%s", papszFiles[i] );
     587                 : 
     588                 :                 CPLDebug( "VSI", "Preloading %s to %s.", 
     589               0 :                           osOldPath.c_str(), osNewPath.c_str() );
     590                 : 
     591               0 :                 if( CPLCopyFile( osNewPath, osOldPath ) != 0 )
     592               0 :                     return -1;
     593                 :             }
     594                 :             
     595               0 :             CSLDestroy( papszFiles );
     596               0 :             iArg += 1;
     597                 :         }
     598                 : 
     599                 : /* -------------------------------------------------------------------- */
     600                 : /*      --debug                                                         */
     601                 : /* -------------------------------------------------------------------- */
     602             361 :         else if( EQUAL(papszArgv[iArg],"--debug") )
     603                 :         {
     604               0 :             if( iArg + 1 >= nArgc )
     605                 :             {
     606                 :                 CPLError( CE_Failure, CPLE_AppDefined, 
     607               0 :                           "--debug option given without debug level." );
     608               0 :                 CSLDestroy( papszReturn );
     609               0 :                 return -1;
     610                 :             }
     611                 : 
     612               0 :             CPLSetConfigOption( "CPL_DEBUG", papszArgv[iArg+1] );
     613               0 :             iArg += 1;
     614                 :         }
     615                 : 
     616                 : /* -------------------------------------------------------------------- */
     617                 : /*      --optfile                                                       */
     618                 : /*                                                                      */
     619                 : /*      Annoyingly the options inserted by --optfile will *not* be      */
     620                 : /*      processed properly if they are general options.                 */
     621                 : /* -------------------------------------------------------------------- */
     622             361 :         else if( EQUAL(papszArgv[iArg],"--optfile") )
     623                 :         {
     624                 :             const char *pszLine;
     625                 :             FILE *fpOptFile;
     626                 : 
     627               0 :             if( iArg + 1 >= nArgc )
     628                 :             {
     629                 :                 CPLError( CE_Failure, CPLE_AppDefined, 
     630               0 :                           "--optfile option given without filename." );
     631               0 :                 CSLDestroy( papszReturn );
     632               0 :                 return -1;
     633                 :             }
     634                 : 
     635               0 :             fpOptFile = VSIFOpen( papszArgv[iArg+1], "rb" );
     636                 : 
     637               0 :             if( fpOptFile == NULL )
     638                 :             {
     639                 :                 CPLError( CE_Failure, CPLE_AppDefined, 
     640                 :                           "Unable to open optfile '%s'.\n%s",
     641               0 :                           papszArgv[iArg+1], VSIStrerror( errno ) );
     642               0 :                 CSLDestroy( papszReturn );
     643               0 :                 return -1;
     644                 :             }
     645                 :             
     646               0 :             while( (pszLine = CPLReadLine( fpOptFile )) != NULL )
     647                 :             {
     648                 :                 char **papszTokens;
     649                 :                 int i;
     650                 : 
     651               0 :                 if( pszLine[0] == '#' || strlen(pszLine) == 0 )
     652               0 :                     continue;
     653                 : 
     654               0 :                 papszTokens = CSLTokenizeString( pszLine );
     655               0 :                 for( i = 0; papszTokens != NULL && papszTokens[i] != NULL; i++)
     656               0 :                     papszReturn = CSLAddString( papszReturn, papszTokens[i] );
     657               0 :                 CSLDestroy( papszTokens );
     658                 :             }
     659                 : 
     660               0 :             VSIFClose( fpOptFile );
     661                 :                 
     662               0 :             iArg += 1;
     663                 :         }
     664                 : 
     665                 : /* -------------------------------------------------------------------- */
     666                 : /*      --formats                                                       */
     667                 : /* -------------------------------------------------------------------- */
     668                 : #ifdef OGR_ENABLED
     669             361 :         else if( EQUAL(papszArgv[iArg], "--formats") )
     670                 :         {
     671                 :             int iDr;
     672                 : 
     673               0 :             printf( "Supported Formats:\n" );
     674                 : 
     675               0 :             OGRSFDriverRegistrar *poR = OGRSFDriverRegistrar::GetRegistrar();
     676                 :         
     677               0 :             for( iDr = 0; iDr < poR->GetDriverCount(); iDr++ )
     678                 :             {
     679               0 :                 OGRSFDriver *poDriver = poR->GetDriver(iDr);
     680                 : 
     681               0 :                 if( poDriver->TestCapability( ODrCCreateDataSource ) )
     682                 :                     printf( "  -> \"%s\" (read/write)\n", 
     683               0 :                             poDriver->GetName() );
     684                 :                 else
     685                 :                     printf( "  -> \"%s\" (readonly)\n", 
     686               0 :                             poDriver->GetName() );
     687                 :             }
     688                 : 
     689               0 :             CSLDestroy( papszReturn );
     690               0 :             return 0;
     691                 :         }
     692                 : #endif /* OGR_ENABLED */
     693                 : 
     694                 : /* -------------------------------------------------------------------- */
     695                 : /*      --locale                                                        */
     696                 : /* -------------------------------------------------------------------- */
     697             361 :         else if( EQUAL(papszArgv[iArg],"--locale") && iArg < nArgc-1 )
     698                 :         {
     699               0 :             setlocale( LC_ALL, papszArgv[++iArg] );
     700                 :         }
     701                 : 
     702                 : /* -------------------------------------------------------------------- */
     703                 : /*      --help-general                                                  */
     704                 : /* -------------------------------------------------------------------- */
     705             361 :         else if( EQUAL(papszArgv[iArg],"--help-general") )
     706                 :         {
     707               0 :             printf( "Generic GDAL/OGR utility command options:\n" );
     708               0 :             printf( "  --version: report version of GDAL/OGR in use.\n" );
     709               0 :             printf( "  --license: report GDAL/OGR license info.\n" );
     710                 : #ifdef OGR_ENABLED
     711               0 :             printf( "  --formats: report all configured format drivers.\n" );
     712                 : #endif /* OGR_ENABLED */
     713               0 :             printf( "  --optfile filename: expand an option file into the argument list.\n" );
     714               0 :             printf( "  --config key value: set system configuration option.\n" );
     715               0 :             printf( "  --debug [on/off/value]: set debug level.\n" );
     716               0 :             printf( "  --help-general: report detailed help on general options.\n" );
     717               0 :             CSLDestroy( papszReturn );
     718               0 :             return 0;
     719                 :         }
     720                 : 
     721                 : /* -------------------------------------------------------------------- */
     722                 : /*      carry through unrecognised options.                             */
     723                 : /* -------------------------------------------------------------------- */
     724                 :         else
     725                 :         {
     726             361 :             papszReturn = CSLAddString( papszReturn, papszArgv[iArg] );
     727                 :         }
     728                 :     }
     729                 : 
     730              87 :     *ppapszArgv = papszReturn;
     731                 : 
     732              87 :     return CSLCount( *ppapszArgv );
     733                 : }
     734                 : 
     735                 : /************************************************************************/
     736                 : /*                            OGRParseDate()                            */
     737                 : /*                                                                      */
     738                 : /*      Parse a variety of text date formats into an OGRField.          */
     739                 : /************************************************************************/
     740                 : 
     741                 : /**
     742                 :  * Parse date string.
     743                 :  *
     744                 :  * This function attempts to parse a date string in a variety of formats
     745                 :  * into the OGRField.Date format suitable for use with OGR.  Generally 
     746                 :  * speaking this function is expecting values like:
     747                 :  * 
     748                 :  *   YYYY-MM-DD HH:MM:SS+nn
     749                 :  *
     750                 :  * The seconds may also have a decimal portion (which is ignored).  And
     751                 :  * just dates (YYYY-MM-DD) or just times (HH:MM:SS) are also supported. 
     752                 :  * The date may also be in YYYY/MM/DD format.  If the year is less than 100
     753                 :  * and greater than 30 a "1900" century value will be set.  If it is less than
     754                 :  * 30 and greater than -1 then a "2000" century value will be set.  In 
     755                 :  * the future this function may be generalized, and additional control 
     756                 :  * provided through nOptions, but an nOptions value of "0" should always do
     757                 :  * a reasonable default form of processing.
     758                 :  *
     759                 :  * The value of psField will be indeterminate if the function fails (returns
     760                 :  * FALSE).  
     761                 :  *
     762                 :  * @param pszInput the input date string.
     763                 :  * @param psField the OGRField that will be updated with the parsed result.
     764                 :  * @param nOptions parsing options, for now always 0. 
     765                 :  *
     766                 :  * @return TRUE if apparently successful or FALSE on failure.
     767                 :  */
     768                 : 
     769             238 : int OGRParseDate( const char *pszInput, OGRField *psField, int nOptions )
     770                 : 
     771                 : {
     772             238 :     int bGotSomething = FALSE;
     773                 : 
     774             238 :     psField->Date.Year = 0;
     775             238 :     psField->Date.Month = 0;
     776             238 :     psField->Date.Day = 0;
     777             238 :     psField->Date.Hour = 0;
     778             238 :     psField->Date.Minute = 0;
     779             238 :     psField->Date.Second = 0;
     780             238 :     psField->Date.TZFlag = 0;
     781                 :     
     782                 : /* -------------------------------------------------------------------- */
     783                 : /*      Do we have a date?                                              */
     784                 : /* -------------------------------------------------------------------- */
     785             476 :     while( *pszInput == ' ' )
     786               0 :         pszInput++;
     787                 :     
     788             238 :     if( strstr(pszInput,"-") != NULL || strstr(pszInput,"/") != NULL )
     789                 :     {
     790             196 :         psField->Date.Year = (GInt16)atoi(pszInput);
     791             196 :         if( psField->Date.Year < 100 && psField->Date.Year >= 30 )
     792               0 :             psField->Date.Year += 1900;
     793             196 :         else if( psField->Date.Year < 30 && psField->Date.Year >= 0 )
     794               0 :             psField->Date.Year += 2000;
     795                 : 
     796            1176 :         while( *pszInput >= '0' && *pszInput <= '9' ) 
     797             784 :             pszInput++;
     798             196 :         if( *pszInput != '-' && *pszInput != '/' )
     799               0 :             return FALSE;
     800                 :         else 
     801             196 :             pszInput++;
     802                 : 
     803             196 :         psField->Date.Month = (GByte)atoi(pszInput);
     804             196 :         if( psField->Date.Month > 12 )
     805               0 :             return FALSE;
     806                 : 
     807             784 :         while( *pszInput >= '0' && *pszInput <= '9' ) 
     808             392 :             pszInput++;
     809             196 :         if( *pszInput != '-' && *pszInput != '/' )
     810               0 :             return FALSE;
     811                 :         else 
     812             196 :             pszInput++;
     813                 : 
     814             196 :         psField->Date.Day = (GByte)atoi(pszInput);
     815             196 :         if( psField->Date.Day > 31 )
     816               0 :             return FALSE;
     817                 : 
     818             784 :         while( *pszInput >= '0' && *pszInput <= '9' )
     819             392 :             pszInput++;
     820                 : 
     821             196 :         bGotSomething = TRUE;
     822                 :     }
     823                 : 
     824                 : /* -------------------------------------------------------------------- */
     825                 : /*      Do we have a time?                                              */
     826                 : /* -------------------------------------------------------------------- */
     827             636 :     while( *pszInput == ' ' )
     828             160 :         pszInput++;
     829                 :     
     830             238 :     if( strstr(pszInput,":") != NULL )
     831                 :     {
     832             197 :         psField->Date.Hour = (GByte)atoi(pszInput);
     833             197 :         if( psField->Date.Hour > 23 )
     834               0 :             return FALSE;
     835                 : 
     836             787 :         while( *pszInput >= '0' && *pszInput <= '9' ) 
     837             393 :             pszInput++;
     838             197 :         if( *pszInput != ':' )
     839               1 :             return FALSE;
     840                 :         else 
     841             196 :             pszInput++;
     842                 : 
     843             196 :         psField->Date.Minute = (GByte)atoi(pszInput);
     844             196 :         if( psField->Date.Minute > 59 )
     845               0 :             return FALSE;
     846                 : 
     847             784 :         while( *pszInput >= '0' && *pszInput <= '9' ) 
     848             392 :             pszInput++;
     849             196 :         if( *pszInput != ':' )
     850               0 :             return FALSE;
     851                 :         else 
     852             196 :             pszInput++;
     853                 : 
     854             196 :         psField->Date.Second = (GByte)atoi(pszInput);
     855             196 :         if( psField->Date.Second > 59 )
     856               0 :             return FALSE;
     857                 : 
     858             784 :         while( (*pszInput >= '0' && *pszInput <= '9')
     859                 :                || *pszInput == '.' )
     860             392 :             pszInput++;
     861                 : 
     862             196 :         bGotSomething = TRUE;
     863                 :     }
     864                 : 
     865                 :     // No date or time!
     866             237 :     if( !bGotSomething )
     867               0 :         return FALSE;
     868                 : 
     869                 : /* -------------------------------------------------------------------- */
     870                 : /*      Do we have a timezone?                                          */
     871                 : /* -------------------------------------------------------------------- */
     872             474 :     while( *pszInput == ' ' )
     873               0 :         pszInput++;
     874                 :     
     875             237 :     if( *pszInput == '-' || *pszInput == '+' )
     876                 :     {
     877                 :         // +HH integral offset
     878              46 :         if( strlen(pszInput) <= 3 )
     879              42 :             psField->Date.TZFlag = (GByte)(100 + atoi(pszInput) * 4);
     880                 : 
     881               8 :         else if( pszInput[3] == ':'  // +HH:MM offset
     882                 :                  && atoi(pszInput+4) % 15 == 0 )
     883                 :         {
     884                 :             psField->Date.TZFlag = (GByte)(100 
     885                 :                 + atoi(pszInput+1) * 4
     886               4 :                 + (atoi(pszInput+4) / 15));
     887                 : 
     888               4 :             if( pszInput[0] == '-' )
     889               4 :                 psField->Date.TZFlag = -1 * (psField->Date.TZFlag - 100) + 100;
     890                 :         }
     891               0 :         else if( isdigit(pszInput[3]) && isdigit(pszInput[4])  // +HHMM offset
     892                 :                  && atoi(pszInput+3) % 15 == 0 )
     893                 :         {
     894                 :             psField->Date.TZFlag = (GByte)(100 
     895                 :                 + static_cast<GByte>(CPLScanLong(pszInput+1,2)) * 4
     896               0 :                 + (atoi(pszInput+3) / 15));
     897                 : 
     898               0 :             if( pszInput[0] == '-' )
     899               0 :                 psField->Date.TZFlag = -1 * (psField->Date.TZFlag - 100) + 100;
     900                 :         }
     901               0 :         else if( isdigit(pszInput[3]) && pszInput[4] == '\0'  // +HMM offset
     902                 :                  && atoi(pszInput+2) % 15 == 0 )
     903                 :         {
     904                 :             psField->Date.TZFlag = (GByte)(100 
     905                 :                 + static_cast<GByte>(CPLScanLong(pszInput+1,1)) * 4
     906               0 :                 + (atoi(pszInput+2) / 15));
     907                 : 
     908               0 :             if( pszInput[0] == '-' )
     909               0 :                 psField->Date.TZFlag = -1 * (psField->Date.TZFlag - 100) + 100;
     910                 :         }
     911                 :         // otherwise ignore any timezone info.
     912                 :     }
     913                 : 
     914             237 :     return TRUE;
     915                 : }
     916                 : 
     917                 : 
     918                 : /************************************************************************/
     919                 : /*                           OGRParseXMLDateTime()                      */
     920                 : /************************************************************************/
     921                 : 
     922                 : int OGRParseXMLDateTime( const char* pszXMLDateTime,
     923                 :                                int *pnYear, int *pnMonth, int *pnDay,
     924              27 :                                int *pnHour, int *pnMinute, float* pfSecond, int *pnTZ)
     925                 : {
     926              27 :     int year = 0, month = 0, day = 0, hour = 0, minute = 0, TZHour, TZMinute;
     927              27 :     float second = 0;
     928                 :     char c;
     929              27 :     int TZ = 0;
     930              27 :     int bRet = FALSE;
     931                 : 
     932                 :     /* Date is expressed as a UTC date */
     933              27 :     if (sscanf(pszXMLDateTime, "%04d-%02d-%02dT%02d:%02d:%f%c",
     934                 :                 &year, &month, &day, &hour, &minute, &second, &c) == 7 && c == 'Z')
     935                 :     {
     936               4 :         TZ = 100;
     937               4 :         bRet = TRUE;
     938                 :     }
     939                 :     /* Date is expressed as a UTC date, with a timezone */
     940              23 :     else if (sscanf(pszXMLDateTime, "%04d-%02d-%02dT%02d:%02d:%f%c%02d:%02d",
     941                 :                 &year, &month, &day, &hour, &minute, &second, &c, &TZHour, &TZMinute) == 9 &&
     942                 :                 (c == '+' || c == '-'))
     943                 :     {
     944              23 :         TZ = 100 + ((c == '+') ? 1 : -1) * ((TZHour * 60 + TZMinute) / 15);
     945              23 :         bRet = TRUE;
     946                 :     }
     947                 :     /* Date is expressed into an unknown timezone */
     948               0 :     else if (sscanf(pszXMLDateTime, "%04d-%02d-%02dT%02d:%02d:%f",
     949                 :                     &year, &month, &day, &hour, &minute, &second) == 6)
     950                 :     {
     951               0 :         TZ = 0;
     952               0 :         bRet = TRUE;
     953                 :     }
     954              27 :     if (bRet)
     955                 :     {
     956              27 :         if (pnYear) *pnYear = year;
     957              27 :         if (pnMonth) *pnMonth = month;
     958              27 :         if (pnDay) *pnDay = day;
     959              27 :         if (pnHour) *pnHour = hour;
     960              27 :         if (pnMinute) *pnMinute = minute;
     961              27 :         if (pfSecond) *pfSecond = second;
     962              27 :         if (pnTZ) *pnTZ = TZ;
     963                 :     }
     964                 : 
     965              27 :     return bRet;
     966                 : }
     967                 : 
     968                 : /************************************************************************/
     969                 : /*                      OGRParseRFC822DateTime()                        */
     970                 : /************************************************************************/
     971                 : 
     972                 : static const char* aszMonthStr[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
     973                 :                                      "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
     974                 : 
     975                 : int OGRParseRFC822DateTime( const char* pszRFC822DateTime,
     976                 :                                   int *pnYear, int *pnMonth, int *pnDay,
     977              25 :                                   int *pnHour, int *pnMinute, int *pnSecond, int *pnTZ)
     978                 : {
     979                 :     /* Following http://asg.web.cmu.edu/rfc/rfc822.html#sec-5 : [Fri,] 28 Dec 2007 05:24[:17] GMT */
     980              25 :     char** papszTokens = CSLTokenizeStringComplex( pszRFC822DateTime, " ,:", TRUE, FALSE );
     981              25 :     char** papszVal = papszTokens;
     982              25 :     int bRet = FALSE;
     983              25 :     int nTokens = CSLCount(papszTokens);
     984              25 :     if (nTokens >= 6)
     985                 :     {
     986              21 :         if ( ! ((*papszVal)[0] >= '0' && (*papszVal)[0] <= '9') )
     987                 :         {
     988                 :             /* Ignore day of week */
     989              21 :             papszVal ++;
     990                 :         }
     991                 : 
     992              21 :         int day = atoi(*papszVal);
     993              21 :         papszVal ++;
     994                 : 
     995              21 :         int month = 0;
     996                 : 
     997             273 :         for(int i = 0; i < 12; i++)
     998                 :         {
     999             252 :             if (EQUAL(*papszVal, aszMonthStr[i]))
    1000              21 :                 month = i + 1;
    1001                 :         }
    1002              21 :         papszVal ++;
    1003                 : 
    1004              21 :         int year = atoi(*papszVal);
    1005              21 :         papszVal ++;
    1006              21 :         if( year < 100 && year >= 30 )
    1007               0 :             year += 1900;
    1008              21 :         else if( year < 30 && year >= 0 )
    1009               0 :             year += 2000;
    1010                 : 
    1011              21 :         int hour = atoi(*papszVal);
    1012              21 :         papszVal ++;
    1013                 : 
    1014              21 :         int minute = atoi(*papszVal);
    1015              21 :         papszVal ++;
    1016                 : 
    1017              21 :         int second = 0;
    1018              21 :         if (*papszVal != NULL && (*papszVal)[0] >= '0' && (*papszVal)[0] <= '9')
    1019                 :         {
    1020              21 :             second = atoi(*papszVal);
    1021              21 :             papszVal ++;
    1022                 :         }
    1023                 : 
    1024              21 :         if (month != 0)
    1025                 :         {
    1026              21 :             bRet = TRUE;
    1027              21 :             int TZ = 0;
    1028                 : 
    1029              21 :             if (*papszVal == NULL)
    1030                 :             {
    1031                 :             }
    1032              42 :             else if (strlen(*papszVal) == 5 &&
    1033                 :                      ((*papszVal)[0] == '+' || (*papszVal)[0] == '-'))
    1034                 :             {
    1035                 :                 char szBuf[3];
    1036              21 :                 szBuf[0] = (*papszVal)[1];
    1037              21 :                 szBuf[1] = (*papszVal)[2];
    1038              21 :                 szBuf[2] = 0;
    1039              21 :                 int TZHour = atoi(szBuf);
    1040              21 :                 szBuf[0] = (*papszVal)[3];
    1041              21 :                 szBuf[1] = (*papszVal)[4];
    1042              21 :                 szBuf[2] = 0;
    1043              21 :                 int TZMinute = atoi(szBuf);
    1044              21 :                 TZ = 100 + (((*papszVal)[0] == '+') ? 1 : -1) * ((TZHour * 60 + TZMinute) / 15);
    1045                 :             }
    1046                 :             else
    1047                 :             {
    1048               0 :                 const char* aszTZStr[] = { "GMT", "UT", "Z", "EST", "EDT", "CST", "CDT", "MST", "MDT", "PST", "PDT" };
    1049               0 :                 int anTZVal[] = { 0, 0, 0, -5, -4, -6, -5, -7, -6, -8, -7 };
    1050               0 :                 for(int i = 0; i < 11; i++)
    1051                 :                 {
    1052               0 :                     if (EQUAL(*papszVal, aszTZStr[i]))
    1053                 :                     {
    1054               0 :                         TZ =  100 + anTZVal[i] * 4;
    1055               0 :                         break;
    1056                 :                     }
    1057                 :                 }
    1058                 :             }
    1059                 : 
    1060              21 :             if (pnYear) *pnYear = year;
    1061              21 :             if (pnMonth) *pnMonth = month;
    1062              21 :             if (pnDay) *pnDay = day;
    1063              21 :             if (pnHour) *pnHour = hour;
    1064              21 :             if (pnMinute) *pnMinute = minute;
    1065              21 :             if (pnSecond) *pnSecond = second;
    1066              21 :             if (pnTZ) *pnTZ = TZ;
    1067                 :         }
    1068                 :     }
    1069              25 :     CSLDestroy(papszTokens);
    1070              25 :     return bRet;
    1071                 : }
    1072                 : 
    1073                 : 
    1074                 : /**
    1075                 :   * Returns the day of the week in Gregorian calendar
    1076                 :   *
    1077                 :   * @param day : day of the month, between 1 and 31
    1078                 :   * @param month : month of the year, between 1 (Jan) and 12 (Dec)
    1079                 :   * @param year : year
    1080                 : 
    1081                 :   * @return day of the week : 0 for Monday, ... 6 for Sunday
    1082                 :   */
    1083                 : 
    1084              12 : int OGRGetDayOfWeek(int day, int month, int year)
    1085                 : {
    1086                 :     /* Reference: Zeller's congruence */
    1087              12 :     int q = day;
    1088                 :     int m;
    1089              12 :     if (month >=3)
    1090              12 :         m = month;
    1091                 :     else
    1092                 :     {
    1093               0 :         m = month + 12;
    1094               0 :         year --;
    1095                 :     }
    1096              12 :     int K = year % 100;
    1097              12 :     int J = year / 100;
    1098              12 :     int h = ( q + (((m+1)*26)/10) + K + K/4 + J/4 + 5 * J) % 7;
    1099              12 :     return ( h + 5 ) % 7;
    1100                 : }
    1101                 : 
    1102                 : 
    1103                 : /************************************************************************/
    1104                 : /*                         OGRGetRFC822DateTime()                       */
    1105                 : /************************************************************************/
    1106                 : 
    1107              12 : char* OGRGetRFC822DateTime(int year, int month, int day, int hour, int minute, int second, int TZFlag)
    1108                 : {
    1109              12 :     char* pszTZ = NULL;
    1110              12 :     const char* aszDayOfWeek[] = { "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun" };
    1111                 : 
    1112              12 :     int dayofweek = OGRGetDayOfWeek(day, month, year);
    1113                 : 
    1114              12 :     if (month < 1 || month > 12)
    1115               0 :         month = 1;
    1116                 : 
    1117              12 :     if (TZFlag == 0 || TZFlag == 100)
    1118                 :     {
    1119               0 :         pszTZ = CPLStrdup("GMT");
    1120                 :     }
    1121                 :     else
    1122                 :     {
    1123              12 :         int TZOffset = ABS(TZFlag - 100) * 15;
    1124              12 :         int TZHour = TZOffset / 60;
    1125              12 :         int TZMinute = TZOffset - TZHour * 60;
    1126                 :         pszTZ = CPLStrdup(CPLSPrintf("%c%02d%02d", TZFlag > 100 ? '+' : '-',
    1127              12 :                                         TZHour, TZMinute));
    1128                 :     }
    1129                 :     char* pszRet = CPLStrdup(CPLSPrintf("%s, %02d %s %04d %02d:%02d:%02d %s",
    1130              12 :                      aszDayOfWeek[dayofweek], day, aszMonthStr[month - 1], year, hour, minute, second, pszTZ));
    1131              12 :     CPLFree(pszTZ);
    1132              12 :     return pszRet;
    1133                 : }
    1134                 : 
    1135                 : /************************************************************************/
    1136                 : /*                            OGRGetXMLDateTime()                       */
    1137                 : /************************************************************************/
    1138                 : 
    1139               4 : char* OGRGetXMLDateTime(int year, int month, int day, int hour, int minute, int second, int TZFlag)
    1140                 : {
    1141                 :     char* pszRet;
    1142               6 :     if (TZFlag == 0 || TZFlag == 100)
    1143                 :     {
    1144                 :         pszRet = CPLStrdup(CPLSPrintf("%04d-%02d-%02dT%02d:%02d:%02dZ",
    1145               2 :                            year, month, day, hour, minute, second));
    1146                 :     }
    1147                 :     else
    1148                 :     {
    1149               2 :         int TZOffset = ABS(TZFlag - 100) * 15;
    1150               2 :         int TZHour = TZOffset / 60;
    1151               2 :         int TZMinute = TZOffset - TZHour * 60;
    1152                 :         pszRet = CPLStrdup(CPLSPrintf("%04d-%02d-%02dT%02d:%02d:%02d%c%02d:%02d",
    1153                 :                            year, month, day, hour, minute, second,
    1154               2 :                            (TZFlag > 100) ? '+' : '-', TZHour, TZMinute));
    1155                 :     }
    1156               4 :     return pszRet;
    1157                 : }
    1158                 : 
    1159                 : /************************************************************************/
    1160                 : /*                 OGRGetXML_UTF8_EscapedString()                       */
    1161                 : /************************************************************************/
    1162                 : 
    1163             101 : char* OGRGetXML_UTF8_EscapedString(const char* pszString)
    1164                 : {
    1165                 :     char *pszEscaped;
    1166             101 :     if (!CPLIsUTF8(pszString, -1) &&
    1167                 :          CSLTestBoolean(CPLGetConfigOption("OGR_FORCE_ASCII", "YES")))
    1168                 :     {
    1169                 :         static int bFirstTime = TRUE;
    1170               1 :         if (bFirstTime)
    1171                 :         {
    1172               1 :             bFirstTime = FALSE;
    1173                 :             CPLError(CE_Warning, CPLE_AppDefined,
    1174                 :                     "%s is not a valid UTF-8 string. Forcing it to ASCII.\n"
    1175                 :                     "If you still want the original string and change the XML file encoding\n"
    1176                 :                     "afterwards, you can define OGR_FORCE_ASCII=NO as configuration option.\n"
    1177               1 :                     "This warning won't be issued anymore", pszString);
    1178                 :         }
    1179                 :         else
    1180                 :         {
    1181                 :             CPLDebug("OGR", "%s is not a valid UTF-8 string. Forcing it to ASCII",
    1182               0 :                     pszString);
    1183                 :         }
    1184               1 :         char* pszTemp = CPLForceToASCII(pszString, -1, '?');
    1185               1 :         pszEscaped = CPLEscapeString( pszTemp, -1, CPLES_XML );
    1186               1 :         CPLFree(pszTemp);
    1187                 :     }
    1188                 :     else
    1189             100 :         pszEscaped = CPLEscapeString( pszString, -1, CPLES_XML );
    1190             101 :     return pszEscaped;
    1191                 : }
    1192                 : 
    1193                 : /************************************************************************/
    1194                 : /*                        OGRCompareDate()                              */
    1195                 : /************************************************************************/
    1196                 : 
    1197                 : int OGRCompareDate(   OGRField *psFirstTuple,
    1198              52 :                       OGRField *psSecondTuple )
    1199                 : {
    1200                 :     /* FIXME? : We ignore TZFlag */
    1201                 : 
    1202              52 :     if (psFirstTuple->Date.Year < psSecondTuple->Date.Year)
    1203              13 :         return -1;
    1204              39 :     else if (psFirstTuple->Date.Year > psSecondTuple->Date.Year)
    1205               0 :         return 1;
    1206                 : 
    1207              39 :     if (psFirstTuple->Date.Month < psSecondTuple->Date.Month)
    1208               5 :         return -1;
    1209              34 :     else if (psFirstTuple->Date.Month > psSecondTuple->Date.Month)
    1210              21 :         return 1;
    1211                 : 
    1212              13 :     if (psFirstTuple->Date.Day < psSecondTuple->Date.Day)
    1213               3 :         return -1;
    1214              10 :     else if (psFirstTuple->Date.Day > psSecondTuple->Date.Day)
    1215               0 :         return 1;
    1216                 : 
    1217              10 :     if (psFirstTuple->Date.Hour < psSecondTuple->Date.Hour)
    1218               0 :         return -1;
    1219              10 :     else if (psFirstTuple->Date.Hour > psSecondTuple->Date.Hour)
    1220               4 :         return 1;
    1221                 : 
    1222               6 :     if (psFirstTuple->Date.Minute < psSecondTuple->Date.Minute)
    1223               0 :         return -1;
    1224               6 :     else if (psFirstTuple->Date.Minute > psSecondTuple->Date.Minute)
    1225               0 :         return 1;
    1226                 : 
    1227               6 :     if (psFirstTuple->Date.Second < psSecondTuple->Date.Second)
    1228               0 :         return -1;
    1229               6 :     else if (psFirstTuple->Date.Second > psSecondTuple->Date.Second)
    1230               0 :         return 1;
    1231                 : 
    1232               6 :     return 0;
    1233                 : }
    1234                 : 
    1235                 : /************************************************************************/
    1236                 : /*                        OGRFastAtof()                                 */
    1237                 : /************************************************************************/
    1238                 : 
    1239                 : /* On Windows, atof() is very slow if the number */
    1240                 : /* is followed by other long content. */
    1241                 : /* So we just extract the number into a short string */
    1242                 : /* before calling atof() on it */
    1243                 : static
    1244               0 : double OGRCallAtofOnShortString(const char* pszStr)
    1245                 : {
    1246                 :     char szTemp[128];
    1247               0 :     int nCounter = 0;
    1248               0 :     const char* p = pszStr;
    1249               0 :     while(*p == ' ' || *p == '\t')
    1250               0 :         p++;
    1251               0 :     while(*p == '+'  ||
    1252                 :           *p == '-'  ||
    1253                 :           (*p >= '0' && *p <= '9') ||
    1254                 :           (*p == 'e' || *p == 'E' || *p == 'd' || *p == 'D'))
    1255                 :     {
    1256               0 :         szTemp[nCounter++] = *(p++);
    1257               0 :         if (nCounter == 127)
    1258               0 :             return atof(pszStr);
    1259                 :     }
    1260               0 :     szTemp[nCounter] = '\0';
    1261               0 :     return atof(szTemp);
    1262                 : }
    1263                 : 
    1264                 : /** Same contract as CPLAtof, except than it doesn't always call the
    1265                 :  *  system atof() that may be slow on some platforms. For simple but
    1266                 :  *  common strings, it'll use a faster implementation (up to 20x faster
    1267                 :  *  than atof() on MS runtime libraries) that has no garanty to return
    1268                 :  *  exactly the same floating point number.
    1269                 :  */
    1270                 :  
    1271             806 : double OGRFastAtof(const char* pszStr)
    1272                 : {
    1273             806 :     double dfVal = 0;
    1274             806 :     double dfSign = 1.0;
    1275             806 :     const char* p = pszStr;
    1276                 :     
    1277                 :     static const double adfTenPower[] =
    1278                 :     {
    1279                 :         1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, 1e10,
    1280                 :         1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, 1e20,
    1281                 :         1e21, 1e22, 1e23, 1e24, 1e25, 1e26, 1e27, 1e28, 1e29, 1e30, 1e31
    1282                 :     };
    1283                 :         
    1284            1614 :     while(*p == ' ' || *p == '\t')
    1285               2 :         p++;
    1286                 : 
    1287             806 :     if (*p == '+')
    1288               9 :         p++;
    1289             797 :     else if (*p == '-')
    1290                 :     {
    1291              62 :         dfSign = -1.0;
    1292              62 :         p++;
    1293                 :     }
    1294                 :     
    1295            2542 :     while(TRUE)
    1296                 :     {
    1297            3348 :         if (*p >= '0' && *p <= '9')
    1298                 :         {
    1299            2542 :             dfVal = dfVal * 10.0 + (*p - '0');
    1300            2542 :             p++;
    1301                 :         }
    1302             806 :         else if (*p == '.')
    1303                 :         {
    1304             288 :             p++;
    1305                 :             break;
    1306                 :         }
    1307             518 :         else if (*p == 'e' || *p == 'E' || *p == 'd' || *p == 'D')
    1308               0 :             return OGRCallAtofOnShortString(pszStr);
    1309                 :         else
    1310             518 :             return dfSign * dfVal;
    1311                 :     }
    1312                 :     
    1313             288 :     unsigned int countFractionnal = 0;
    1314            3313 :     while(TRUE)
    1315                 :     {
    1316            3601 :         if (*p >= '0' && *p <= '9')
    1317                 :         {
    1318            3313 :             dfVal = dfVal * 10.0 + (*p - '0');
    1319            3313 :             countFractionnal ++;
    1320            3313 :             p++;
    1321                 :         }
    1322             288 :         else if (*p == 'e' || *p == 'E' || *p == 'd' || *p == 'D')
    1323               0 :             return OGRCallAtofOnShortString(pszStr);
    1324                 :         else
    1325                 :         {
    1326             288 :             if (countFractionnal < sizeof(adfTenPower) / sizeof(adfTenPower[0]))
    1327             288 :                 return dfSign * (dfVal / adfTenPower[countFractionnal]);
    1328                 :             else
    1329               0 :                 return OGRCallAtofOnShortString(pszStr);
    1330                 :         }
    1331                 :     }
    1332                 : }

Generated by: LTP GCOV extension version 1.5