LCOV - code coverage report
Current view: directory - port - cpl_conv.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 600 460 76.7 %
Date: 2012-12-26 Functions: 47 41 87.2 %

       1                 : /******************************************************************************
       2                 :  * $Id: cpl_conv.cpp 25331 2012-12-19 10:49:50Z rouault $
       3                 :  *
       4                 :  * Project:  CPL - Common Portability Library
       5                 :  * Purpose:  Convenience functions.
       6                 :  * Author:   Frank Warmerdam, warmerdam@pobox.com
       7                 :  *
       8                 :  ******************************************************************************
       9                 :  * Copyright (c) 1998, Frank Warmerdam
      10                 :  *
      11                 :  * Permission is hereby granted, free of charge, to any person obtaining a
      12                 :  * copy of this software and associated documentation files (the "Software"),
      13                 :  * to deal in the Software without restriction, including without limitation
      14                 :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      15                 :  * and/or sell copies of the Software, and to permit persons to whom the
      16                 :  * Software is furnished to do so, subject to the following conditions:
      17                 :  *
      18                 :  * The above copyright notice and this permission notice shall be included
      19                 :  * in all copies or substantial portions of the Software.
      20                 :  *
      21                 :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
      22                 :  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      23                 :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
      24                 :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      25                 :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      26                 :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      27                 :  * DEALINGS IN THE SOFTWARE.
      28                 :  ****************************************************************************/
      29                 : #ifdef MSVC_USE_VLD
      30                 : #include <vld.h>
      31                 : #endif
      32                 : #include "cpl_conv.h"
      33                 : #include "cpl_string.h"
      34                 : #include "cpl_vsi.h"
      35                 : #include "cpl_multiproc.h"
      36                 : 
      37                 : CPL_CVSID("$Id: cpl_conv.cpp 25331 2012-12-19 10:49:50Z rouault $");
      38                 : 
      39                 : #if defined(WIN32CE)
      40                 : #  include "cpl_wince.h"
      41                 : #endif
      42                 : 
      43                 : static void *hConfigMutex = NULL;
      44                 : static volatile char **papszConfigOptions = NULL;
      45                 : 
      46                 : /* Used by CPLOpenShared() and friends */
      47                 : static void *hSharedFileMutex = NULL;
      48                 : static volatile int nSharedFileCount = 0;
      49                 : static volatile CPLSharedFileInfo *pasSharedFileList = NULL;
      50                 : 
      51                 : /* Note: ideally this should be added in CPLSharedFileInfo* */
      52                 : /* but CPLSharedFileInfo is exposed in the API, hence that trick */
      53                 : /* to hide this detail */
      54                 : typedef struct
      55                 : {
      56                 :     GIntBig             nPID; // pid of opening thread
      57                 : } CPLSharedFileInfoExtra;
      58                 : 
      59                 : static volatile CPLSharedFileInfoExtra *pasSharedFileListExtra = NULL;
      60                 : 
      61                 : /************************************************************************/
      62                 : /*                             CPLCalloc()                              */
      63                 : /************************************************************************/
      64                 : 
      65                 : /**
      66                 :  * Safe version of calloc().
      67                 :  *
      68                 :  * This function is like the C library calloc(), but raises a CE_Fatal
      69                 :  * error with CPLError() if it fails to allocate the desired memory.  It
      70                 :  * should be used for small memory allocations that are unlikely to fail
      71                 :  * and for which the application is unwilling to test for out of memory
      72                 :  * conditions.  It uses VSICalloc() to get the memory, so any hooking of
      73                 :  * VSICalloc() will apply to CPLCalloc() as well.  CPLFree() or VSIFree()
      74                 :  * can be used free memory allocated by CPLCalloc().
      75                 :  *
      76                 :  * @param nCount number of objects to allocate.
      77                 :  * @param nSize size (in bytes) of object to allocate.
      78                 :  * @return pointer to newly allocated memory, only NULL if nSize * nCount is
      79                 :  * NULL.
      80                 :  */
      81                 : 
      82         9314711 : void *CPLCalloc( size_t nCount, size_t nSize )
      83                 : 
      84                 : {
      85                 :     void        *pReturn;
      86                 : 
      87         9314711 :     if( nSize * nCount == 0 )
      88              46 :         return NULL;
      89                 :     
      90         9314665 :     pReturn = CPLMalloc( nCount * nSize );
      91         9314665 :     memset( pReturn, 0, nCount * nSize );
      92         9314665 :     return pReturn;
      93                 : }
      94                 : 
      95                 : /************************************************************************/
      96                 : /*                             CPLMalloc()                              */
      97                 : /************************************************************************/
      98                 : 
      99                 : /**
     100                 :  * Safe version of malloc().
     101                 :  *
     102                 :  * This function is like the C library malloc(), but raises a CE_Fatal
     103                 :  * error with CPLError() if it fails to allocate the desired memory.  It
     104                 :  * should be used for small memory allocations that are unlikely to fail
     105                 :  * and for which the application is unwilling to test for out of memory
     106                 :  * conditions.  It uses VSIMalloc() to get the memory, so any hooking of
     107                 :  * VSIMalloc() will apply to CPLMalloc() as well.  CPLFree() or VSIFree()
     108                 :  * can be used free memory allocated by CPLMalloc().
     109                 :  *
     110                 :  * @param nSize size (in bytes) of memory block to allocate.
     111                 :  * @return pointer to newly allocated memory, only NULL if nSize is zero.
     112                 :  */
     113                 : 
     114        42402646 : void *CPLMalloc( size_t nSize )
     115                 : 
     116                 : {
     117                 :     void        *pReturn;
     118                 : 
     119        42402646 :     CPLVerifyConfiguration();
     120                 : 
     121        42402647 :     if( nSize == 0 )
     122           34976 :         return NULL;
     123                 : 
     124        42367671 :     if( long(nSize) < 0 )
     125                 :     {
     126                 :         CPLError( CE_Failure, CPLE_AppDefined,
     127                 :                   "CPLMalloc(%ld): Silly size requested.\n",
     128               0 :                   (long) nSize );
     129               0 :         return NULL;
     130                 :     }
     131                 :     
     132        42367671 :     pReturn = VSIMalloc( nSize );
     133        42367670 :     if( pReturn == NULL )
     134                 :     {
     135               0 :         if( nSize > 0 && nSize < 2000 )
     136                 :         {
     137                 :             char szSmallMsg[60];
     138                 : 
     139                 :             sprintf( szSmallMsg, 
     140                 :                      "CPLMalloc(): Out of memory allocating %ld bytes.", 
     141               0 :                      (long) nSize );
     142               0 :             CPLEmergencyError( szSmallMsg ); 
     143                 :         }
     144                 :         else
     145                 :             CPLError( CE_Fatal, CPLE_OutOfMemory,
     146                 :                       "CPLMalloc(): Out of memory allocating %ld bytes.\n",
     147               0 :                       (long) nSize );
     148                 :     }
     149                 : 
     150        42367670 :     return pReturn;
     151                 : }
     152                 : 
     153                 : /************************************************************************/
     154                 : /*                             CPLRealloc()                             */
     155                 : /************************************************************************/
     156                 : 
     157                 : /**
     158                 :  * Safe version of realloc().
     159                 :  *
     160                 :  * This function is like the C library realloc(), but raises a CE_Fatal
     161                 :  * error with CPLError() if it fails to allocate the desired memory.  It
     162                 :  * should be used for small memory allocations that are unlikely to fail
     163                 :  * and for which the application is unwilling to test for out of memory
     164                 :  * conditions.  It uses VSIRealloc() to get the memory, so any hooking of
     165                 :  * VSIRealloc() will apply to CPLRealloc() as well.  CPLFree() or VSIFree()
     166                 :  * can be used free memory allocated by CPLRealloc().
     167                 :  *
     168                 :  * It is also safe to pass NULL in as the existing memory block for
     169                 :  * CPLRealloc(), in which case it uses VSIMalloc() to allocate a new block.
     170                 :  *
     171                 :  * @param pData existing memory block which should be copied to the new block.
     172                 :  * @param nNewSize new size (in bytes) of memory block to allocate.
     173                 :  * @return pointer to allocated memory, only NULL if nNewSize is zero.
     174                 :  */
     175                 : 
     176                 : 
     177        13770725 : void * CPLRealloc( void * pData, size_t nNewSize )
     178                 : 
     179                 : {
     180                 :     void        *pReturn;
     181                 : 
     182        13770725 :     if ( nNewSize == 0 )
     183                 :     {
     184               0 :         VSIFree(pData);
     185               0 :         return NULL;
     186                 :     }
     187                 : 
     188        13770725 :     if( long(nNewSize) < 0 )
     189                 :     {
     190                 :         CPLError( CE_Failure, CPLE_AppDefined,
     191                 :                   "CPLRealloc(%ld): Silly size requested.\n",
     192               0 :                   (long) nNewSize );
     193               0 :         return NULL;
     194                 :     }
     195                 :     
     196        13770725 :     if( pData == NULL )
     197         1739619 :         pReturn = VSIMalloc( nNewSize );
     198                 :     else
     199        12031106 :         pReturn = VSIRealloc( pData, nNewSize );
     200                 :     
     201        13771356 :     if( pReturn == NULL )
     202                 :     {
     203               0 :         if( nNewSize > 0 && nNewSize < 2000 )
     204                 :         {
     205                 :             char szSmallMsg[60];
     206                 : 
     207                 :             sprintf( szSmallMsg, 
     208                 :                      "CPLRealloc(): Out of memory allocating %ld bytes.", 
     209               0 :                      (long) nNewSize );
     210               0 :             CPLEmergencyError( szSmallMsg ); 
     211                 :         }
     212                 :         else
     213                 :             CPLError( CE_Fatal, CPLE_OutOfMemory,
     214                 :                       "CPLRealloc(): Out of memory allocating %ld bytes.\n",
     215               0 :                       (long) nNewSize );
     216                 :     }
     217                 : 
     218        13771361 :     return pReturn;
     219                 : }
     220                 : 
     221                 : /************************************************************************/
     222                 : /*                             CPLStrdup()                              */
     223                 : /************************************************************************/
     224                 : 
     225                 : /**
     226                 :  * Safe version of strdup() function.
     227                 :  *
     228                 :  * This function is similar to the C library strdup() function, but if
     229                 :  * the memory allocation fails it will issue a CE_Fatal error with
     230                 :  * CPLError() instead of returning NULL.  It uses VSIStrdup(), so any
     231                 :  * hooking of that function will apply to CPLStrdup() as well.  Memory
     232                 :  * allocated with CPLStrdup() can be freed with CPLFree() or VSIFree().
     233                 :  *
     234                 :  * It is also safe to pass a NULL string into CPLStrdup().  CPLStrdup()
     235                 :  * will allocate and return a zero length string (as opposed to a NULL
     236                 :  * string).
     237                 :  *
     238                 :  * @param pszString input string to be duplicated.  May be NULL.
     239                 :  * @return pointer to a newly allocated copy of the string.  Free with
     240                 :  * CPLFree() or VSIFree().
     241                 :  */
     242                 : 
     243        25921280 : char *CPLStrdup( const char * pszString )
     244                 : 
     245                 : {
     246                 :     char        *pszReturn;
     247                 : 
     248        25921280 :     if( pszString == NULL )
     249          791220 :         pszString = "";
     250                 : 
     251        25921280 :     pszReturn = (char *) CPLMalloc(strlen(pszString)+1);
     252        25921280 :     if( pszReturn == NULL )
     253                 :     {
     254                 :         CPLError( CE_Fatal, CPLE_OutOfMemory,
     255                 :                   "CPLStrdup(): Out of memory allocating %ld bytes.\n",
     256               0 :                   (long) strlen(pszString) );
     257                 :         
     258                 :     }
     259                 : 
     260        25921280 :     strcpy( pszReturn, pszString );
     261        25921280 :     return( pszReturn );
     262                 : }
     263                 : 
     264                 : /************************************************************************/
     265                 : /*                             CPLStrlwr()                              */
     266                 : /************************************************************************/
     267                 : 
     268                 : /**
     269                 :  * Convert each characters of the string to lower case.
     270                 :  *
     271                 :  * For example, "ABcdE" will be converted to "abcde".
     272                 :  * This function is locale dependent.
     273                 :  *
     274                 :  * @param pszString input string to be converted.
     275                 :  * @return pointer to the same string, pszString.
     276                 :  */
     277                 : 
     278              10 : char *CPLStrlwr( char *pszString )
     279                 : 
     280                 : {
     281              10 :     if (pszString)
     282                 :     {
     283              10 :         char *pszTemp = pszString;
     284                 : 
     285              62 :         while (*pszTemp)
     286                 :         {
     287              42 :             *pszTemp = (char) tolower (*pszTemp);
     288              42 :             pszTemp++;
     289                 :         }
     290                 :     }
     291                 : 
     292              10 :     return pszString;
     293                 : }
     294                 : 
     295                 : /************************************************************************/
     296                 : /*                              CPLFGets()                              */
     297                 : /*                                                                      */
     298                 : /*      Note: CR = \r = ASCII 13                                        */
     299                 : /*            LF = \n = ASCII 10                                        */
     300                 : /************************************************************************/
     301                 : 
     302                 : /**
     303                 :  * Reads in at most one less than nBufferSize characters from the fp
     304                 :  * stream and stores them into the buffer pointed to by pszBuffer.
     305                 :  * Reading stops after an EOF or a newline. If a newline is read, it
     306                 :  * is _not_ stored into the buffer. A '\\0' is stored after the last
     307                 :  * character in the buffer. All three types of newline terminators
     308                 :  * recognized by the CPLFGets(): single '\\r' and '\\n' and '\\r\\n'
     309                 :  * combination.
     310                 :  *
     311                 :  * @param pszBuffer pointer to the targeting character buffer.
     312                 :  * @param nBufferSize maximum size of the string to read (not including
     313                 :  * termonating '\\0').
     314                 :  * @param fp file pointer to read from.
     315                 :  * @return pointer to the pszBuffer containing a string read
     316                 :  * from the file or NULL if the error or end of file was encountered.
     317                 :  */
     318                 : 
     319         1468526 : char *CPLFGets( char *pszBuffer, int nBufferSize, FILE * fp )
     320                 : 
     321                 : {
     322                 :     int nActuallyRead, nOriginalOffset;
     323                 : 
     324         1468526 :     if ( nBufferSize == 0 || pszBuffer == NULL || fp == NULL )
     325               0 :         return NULL;
     326                 : 
     327                 : /* -------------------------------------------------------------------- */
     328                 : /*      Let the OS level call read what it things is one line.  This    */
     329                 : /*      will include the newline.  On windows, if the file happens      */
     330                 : /*      to be in text mode, the CRLF will have been converted to        */
     331                 : /*      just the newline (LF).  If it is in binary mode it may well     */
     332                 : /*      have both.                                                      */
     333                 : /* -------------------------------------------------------------------- */
     334         1468526 :     nOriginalOffset = VSIFTell( fp );
     335         1468526 :     if( VSIFGets( pszBuffer, nBufferSize, fp ) == NULL )
     336            1499 :         return NULL;
     337                 :     
     338         1467027 :     nActuallyRead = strlen(pszBuffer);
     339         1467027 :     if ( nActuallyRead == 0 )
     340               0 :         return NULL;
     341                 : 
     342                 : /* -------------------------------------------------------------------- */
     343                 : /*      If we found \r and out buffer is full, it is possible there     */
     344                 : /*      is also a pending \n.  Check for it.                            */
     345                 : /* -------------------------------------------------------------------- */
     346         2438093 :     if( nBufferSize == nActuallyRead+1
     347          971066 :         && pszBuffer[nActuallyRead-1] == 13 )
     348                 :     {
     349                 :         int chCheck;
     350              16 :         chCheck = fgetc( fp );
     351              16 :         if( chCheck != 10 )
     352                 :         {
     353                 :             // unget the character.
     354               0 :             VSIFSeek( fp, nOriginalOffset+nActuallyRead, SEEK_SET );
     355                 :         }
     356                 :     }
     357                 : 
     358                 : /* -------------------------------------------------------------------- */
     359                 : /*      Trim off \n, \r or \r\n if it appears at the end.  We don't     */
     360                 : /*      need to do any "seeking" since we want the newline eaten.       */
     361                 : /* -------------------------------------------------------------------- */
     362         3500280 :     if( nActuallyRead > 1 
     363         1462084 :         && pszBuffer[nActuallyRead-1] == 10 
     364          493017 :         && pszBuffer[nActuallyRead-2] == 13 )
     365                 :     {
     366           78152 :         pszBuffer[nActuallyRead-2] = '\0';
     367                 :     }
     368         2357942 :     else if( pszBuffer[nActuallyRead-1] == 10 
     369          969067 :              || pszBuffer[nActuallyRead-1] == 13 )
     370                 :     {
     371          419824 :         pszBuffer[nActuallyRead-1] = '\0';
     372                 :     }
     373                 : 
     374                 : /* -------------------------------------------------------------------- */
     375                 : /*      Search within the string for a \r (MacOS convention             */
     376                 : /*      apparently), and if we find it we need to trim the string,      */
     377                 : /*      and seek back.                                                  */
     378                 : /* -------------------------------------------------------------------- */
     379         1467027 :     char *pszExtraNewline = strchr( pszBuffer, 13 );
     380                 :     
     381         1467027 :     if( pszExtraNewline != NULL )
     382                 :     {
     383                 :         int chCheck;
     384                 : 
     385               0 :         nActuallyRead = pszExtraNewline - pszBuffer + 1;
     386                 :         
     387               0 :         *pszExtraNewline = '\0';
     388               0 :         VSIFSeek( fp, nOriginalOffset + nActuallyRead - 1, SEEK_SET );
     389                 : 
     390                 :         /* 
     391                 :          * This hackery is necessary to try and find our correct
     392                 :          * spot on win32 systems with text mode line translation going 
     393                 :          * on.  Sometimes the fseek back overshoots, but it doesn't
     394                 :          * "realize it" till a character has been read. Try to read till
     395                 :          * we get to the right spot and get our CR. 
     396                 :          */ 
     397               0 :         chCheck = fgetc( fp );
     398               0 :         while( (chCheck != 13 && chCheck != EOF)
     399                 :                || VSIFTell(fp) < nOriginalOffset + nActuallyRead )
     400                 :         {
     401                 :             static volatile int bWarned = FALSE;
     402                 : 
     403               0 :             if( !bWarned )
     404                 :             {
     405               0 :                 bWarned = TRUE;
     406               0 :                 CPLDebug( "CPL", "CPLFGets() correcting for DOS text mode translation seek problem." );
     407                 :             }
     408               0 :             chCheck = fgetc( fp );
     409                 :         }
     410                 :     }
     411                 : 
     412         1467027 :     return pszBuffer;
     413                 : }
     414                 : 
     415                 : /************************************************************************/
     416                 : /*                         CPLReadLineBuffer()                          */
     417                 : /*                                                                      */
     418                 : /*      Fetch readline buffer, and ensure it is the desired size,       */
     419                 : /*      reallocating if needed.  Manages TLS (thread local storage)     */
     420                 : /*      issues for the buffer.                                          */
     421                 : /*      We use a special trick to track the actual size of the buffer   */
     422                 : /*      The first 4 bytes are reserved to store it as a int, hence the  */
     423                 : /*      -4 / +4 hacks with the size and pointer.                        */
     424                 : /************************************************************************/
     425         2287495 : static char *CPLReadLineBuffer( int nRequiredSize )
     426                 : 
     427                 : {
     428                 :     
     429                 : /* -------------------------------------------------------------------- */
     430                 : /*      A required size of -1 means the buffer should be freed.         */
     431                 : /* -------------------------------------------------------------------- */
     432         2287495 :     if( nRequiredSize == -1 )
     433                 :     {
     434             925 :         if( CPLGetTLS( CTLS_RLBUFFERINFO ) != NULL )
     435                 :         {
     436             925 :             CPLFree( CPLGetTLS( CTLS_RLBUFFERINFO ) );
     437             925 :             CPLSetTLS( CTLS_RLBUFFERINFO, NULL, FALSE );
     438                 :         }
     439             925 :         return NULL;
     440                 :     }
     441                 : 
     442                 : /* -------------------------------------------------------------------- */
     443                 : /*      If the buffer doesn't exist yet, create it.                     */
     444                 : /* -------------------------------------------------------------------- */
     445         2286570 :     GUInt32 *pnAlloc = (GUInt32 *) CPLGetTLS( CTLS_RLBUFFERINFO );
     446                 : 
     447         2286570 :     if( pnAlloc == NULL )
     448                 :     {
     449            1044 :         pnAlloc = (GUInt32 *) CPLMalloc(200);
     450            1044 :         *pnAlloc = 196;
     451            1044 :         CPLSetTLS( CTLS_RLBUFFERINFO, pnAlloc, TRUE );
     452                 :     }
     453                 : 
     454                 : /* -------------------------------------------------------------------- */
     455                 : /*      If it is too small, grow it bigger.                             */
     456                 : /* -------------------------------------------------------------------- */
     457         2286570 :     if( ((int) *pnAlloc) -1 < nRequiredSize )
     458                 :     {
     459             530 :         int nNewSize = nRequiredSize + 4 + 500;
     460             530 :         if (nNewSize <= 0)
     461                 :         {
     462               0 :             VSIFree( pnAlloc );
     463               0 :             CPLSetTLS( CTLS_RLBUFFERINFO, NULL, FALSE );
     464                 :             CPLError( CE_Failure, CPLE_OutOfMemory,
     465               0 :                       "CPLReadLineBuffer(): Trying to allocate more than 2 GB." );
     466               0 :             return NULL;
     467                 :         }
     468                 : 
     469             530 :         GUInt32* pnAllocNew = (GUInt32 *) VSIRealloc(pnAlloc,nNewSize);
     470             530 :         if( pnAllocNew == NULL )
     471                 :         {
     472               0 :             VSIFree( pnAlloc );
     473               0 :             CPLSetTLS( CTLS_RLBUFFERINFO, NULL, FALSE );
     474                 :             CPLError( CE_Failure, CPLE_OutOfMemory,
     475                 :                       "CPLReadLineBuffer(): Out of memory allocating %ld bytes.",
     476               0 :                       (long) nNewSize );
     477               0 :             return NULL;
     478                 :         }
     479             530 :         pnAlloc = pnAllocNew;
     480                 :             
     481             530 :         *pnAlloc = nNewSize - 4;
     482             530 :         CPLSetTLS( CTLS_RLBUFFERINFO, pnAlloc, TRUE );
     483                 :     }
     484                 : 
     485         2286570 :     return (char *) (pnAlloc+1);
     486                 : }
     487                 : 
     488                 : /************************************************************************/
     489                 : /*                            CPLReadLine()                             */
     490                 : /************************************************************************/
     491                 : 
     492                 : /**
     493                 :  * Simplified line reading from text file.
     494                 :  * 
     495                 :  * Read a line of text from the given file handle, taking care
     496                 :  * to capture CR and/or LF and strip off ... equivelent of
     497                 :  * DKReadLine().  Pointer to an internal buffer is returned.
     498                 :  * The application shouldn't free it, or depend on it's value
     499                 :  * past the next call to CPLReadLine().
     500                 :  * 
     501                 :  * Note that CPLReadLine() uses VSIFGets(), so any hooking of VSI file
     502                 :  * services should apply to CPLReadLine() as well.
     503                 :  *
     504                 :  * CPLReadLine() maintains an internal buffer, which will appear as a 
     505                 :  * single block memory leak in some circumstances.  CPLReadLine() may 
     506                 :  * be called with a NULL FILE * at any time to free this working buffer.
     507                 :  *
     508                 :  * @param fp file pointer opened with VSIFOpen().
     509                 :  *
     510                 :  * @return pointer to an internal buffer containing a line of text read
     511                 :  * from the file or NULL if the end of file was encountered.
     512                 :  */
     513                 : 
     514          499823 : const char *CPLReadLine( FILE * fp )
     515                 : 
     516                 : {
     517          499823 :     char *pszRLBuffer = CPLReadLineBuffer(1);
     518          499823 :     int         nReadSoFar = 0;
     519                 : 
     520                 : /* -------------------------------------------------------------------- */
     521                 : /*      Cleanup case.                                                   */
     522                 : /* -------------------------------------------------------------------- */
     523          499823 :     if( fp == NULL )
     524                 :     {
     525             342 :         CPLReadLineBuffer( -1 );
     526             342 :         return NULL;
     527                 :     }
     528                 : 
     529                 : /* -------------------------------------------------------------------- */
     530                 : /*      Loop reading chunks of the line till we get to the end of       */
     531                 : /*      the line.                                                       */
     532                 : /* -------------------------------------------------------------------- */
     533                 :     int nBytesReadThisTime;
     534                 : 
     535         3405117 :     do {
     536                 : /* -------------------------------------------------------------------- */
     537                 : /*      Grow the working buffer if we have it nearly full.  Fail out    */
     538                 : /*      of read line if we can't reallocate it big enough (for          */
     539                 : /*      instance for a _very large_ file with no newlines).             */
     540                 : /* -------------------------------------------------------------------- */
     541         1468526 :         if( nReadSoFar > 100 * 1024 * 1024 )
     542               0 :             return NULL; /* it is dubious that we need to read a line longer than 100 MB ! */
     543         1468526 :         pszRLBuffer = CPLReadLineBuffer( nReadSoFar + 129 );
     544         1468526 :         if( pszRLBuffer == NULL )
     545               0 :             return NULL;
     546                 : 
     547                 : /* -------------------------------------------------------------------- */
     548                 : /*      Do the actual read.                                             */
     549                 : /* -------------------------------------------------------------------- */
     550         1468526 :         if( CPLFGets( pszRLBuffer+nReadSoFar, 128, fp ) == NULL 
     551                 :             && nReadSoFar == 0 )
     552            1499 :             return NULL;
     553                 : 
     554         1467027 :         nBytesReadThisTime = strlen(pszRLBuffer+nReadSoFar);
     555         1467027 :         nReadSoFar += nBytesReadThisTime;
     556                 : 
     557                 :     } while( nBytesReadThisTime >= 127
     558          969045 :              && pszRLBuffer[nReadSoFar-1] != 13
     559          969045 :              && pszRLBuffer[nReadSoFar-1] != 10 );
     560                 : 
     561          497982 :     return( pszRLBuffer );
     562                 : }
     563                 : 
     564                 : /************************************************************************/
     565                 : /*                            CPLReadLineL()                            */
     566                 : /************************************************************************/
     567                 : 
     568                 : /**
     569                 :  * Simplified line reading from text file.
     570                 :  * 
     571                 :  * Similar to CPLReadLine(), but reading from a large file API handle.
     572                 :  *
     573                 :  * @param fp file pointer opened with VSIFOpenL().
     574                 :  *
     575                 :  * @return pointer to an internal buffer containing a line of text read
     576                 :  * from the file or NULL if the end of file was encountered.
     577                 :  */
     578                 : 
     579           41007 : const char *CPLReadLineL( VSILFILE * fp )
     580                 : {
     581           41007 :     return CPLReadLine2L( fp, -1, NULL );
     582                 : }
     583                 : 
     584                 : /************************************************************************/
     585                 : /*                           CPLReadLine2L()                            */
     586                 : /************************************************************************/
     587                 : 
     588                 : /**
     589                 :  * Simplified line reading from text file.
     590                 :  * 
     591                 :  * Similar to CPLReadLine(), but reading from a large file API handle.
     592                 :  *
     593                 :  * @param fp file pointer opened with VSIFOpenL().
     594                 :  * @param nMaxCars  maximum number of characters allowed, or -1 for no limit.
     595                 :  * @param papszOptions NULL-terminated array of options. Unused for now.
     596                 : 
     597                 :  * @return pointer to an internal buffer containing a line of text read
     598                 :  * from the file or NULL if the end of file was encountered or the maximum
     599                 :  * number of characters allowed readched.
     600                 :  *
     601                 :  * @since GDAL 1.7.0
     602                 :  */
     603                 : 
     604          301976 : const char *CPLReadLine2L( VSILFILE * fp, int nMaxCars, char** papszOptions )
     605                 : 
     606                 : {
     607                 :     (void) papszOptions;
     608                 : 
     609                 : /* -------------------------------------------------------------------- */
     610                 : /*      Cleanup case.                                                   */
     611                 : /* -------------------------------------------------------------------- */
     612          301976 :     if( fp == NULL )
     613                 :     {
     614             583 :         CPLReadLineBuffer( -1 );
     615             583 :         return NULL;
     616                 :     }
     617                 : 
     618                 : /* -------------------------------------------------------------------- */
     619                 : /*      Loop reading chunks of the line till we get to the end of       */
     620                 : /*      the line.                                                       */
     621                 : /* -------------------------------------------------------------------- */
     622                 :     char *pszRLBuffer;
     623          301393 :     const size_t nChunkSize = 40;
     624                 :     char szChunk[nChunkSize];
     625          301393 :     size_t nChunkBytesRead = 0;
     626          301393 :     int nBufLength = 0;
     627          301393 :     size_t nChunkBytesConsumed = 0;
     628                 : 
     629           16828 :     while( TRUE )
     630                 :     {
     631                 : /* -------------------------------------------------------------------- */
     632                 : /*      Read a chunk from the input file.                               */
     633                 : /* -------------------------------------------------------------------- */
     634          318221 :         if ( nBufLength > INT_MAX - nChunkSize - 1 )
     635                 :         {
     636                 :             CPLError( CE_Failure, CPLE_AppDefined,
     637               0 :                       "Too big line : more than 2 billion characters!." );
     638               0 :             CPLReadLineBuffer( -1 );
     639               0 :             return NULL;
     640                 :         }
     641                 : 
     642          318221 :         pszRLBuffer = CPLReadLineBuffer( nBufLength + nChunkSize + 1 );
     643          318221 :         if( pszRLBuffer == NULL )
     644               0 :             return NULL;
     645                 : 
     646          318221 :         if( nChunkBytesRead == nChunkBytesConsumed + 1 )
     647                 :         {
     648                 : 
     649                 :             // case where one character is left over from last read.
     650           16828 :             szChunk[0] = szChunk[nChunkBytesConsumed];
     651                 : 
     652           16828 :             nChunkBytesConsumed = 0;
     653           16828 :             nChunkBytesRead = VSIFReadL( szChunk+1, 1, nChunkSize-1, fp ) + 1;
     654                 :         }
     655                 :         else
     656                 :         {
     657          301393 :             nChunkBytesConsumed = 0;
     658                 : 
     659                 :             // fresh read.
     660          301393 :             nChunkBytesRead = VSIFReadL( szChunk, 1, nChunkSize, fp );
     661          301393 :             if( nChunkBytesRead == 0 )
     662                 :             {
     663             532 :                 if( nBufLength == 0 )
     664             532 :                     return NULL;
     665                 :                 else
     666               0 :                     break;
     667                 :             }
     668                 :         }
     669                 :         
     670                 : /* -------------------------------------------------------------------- */
     671                 : /*      copy over characters watching for end-of-line.                  */
     672                 : /* -------------------------------------------------------------------- */
     673          317689 :         int bBreak = FALSE;
     674         8929871 :         while( nChunkBytesConsumed < nChunkBytesRead-1 && !bBreak )
     675                 :         {
     676        16888726 :             if( (szChunk[nChunkBytesConsumed] == 13
     677          113082 :                  && szChunk[nChunkBytesConsumed+1] == 10)
     678         8181442 :                 || (szChunk[nChunkBytesConsumed] == 10
     679          186598 :                     && szChunk[nChunkBytesConsumed+1] == 13) )
     680                 :             {
     681          113081 :                 nChunkBytesConsumed += 2;
     682          113081 :                 bBreak = TRUE;
     683                 :             }
     684        16362885 :             else if( szChunk[nChunkBytesConsumed] == 10
     685         7994844 :                      || szChunk[nChunkBytesConsumed] == 13 )
     686                 :             {
     687          186599 :                 nChunkBytesConsumed += 1;
     688          186599 :                 bBreak = TRUE;
     689                 :             }
     690                 :             else
     691                 :             {
     692         7994843 :                 pszRLBuffer[nBufLength++] = szChunk[nChunkBytesConsumed++];
     693         7994843 :                 if (nMaxCars >= 0 && nBufLength == nMaxCars)
     694                 :                 {
     695                 :                     CPLError( CE_Failure, CPLE_AppDefined,
     696              30 :                              "Maximum number of characters allowed reached.");
     697              30 :                     return NULL;
     698                 :                 }
     699                 :             }
     700                 :         }
     701                 : 
     702          317659 :         if( bBreak )
     703          299680 :             break;
     704                 : 
     705                 : /* -------------------------------------------------------------------- */
     706                 : /*      If there is a remaining character and it is not a newline       */
     707                 : /*      consume it.  If it is a newline, but we are clearly at the      */
     708                 : /*      end of the file then consume it.                                */
     709                 : /* -------------------------------------------------------------------- */
     710           17979 :         if( nChunkBytesConsumed == nChunkBytesRead-1 
     711                 :             && nChunkBytesRead < nChunkSize )
     712                 :         {
     713            1570 :             if( szChunk[nChunkBytesConsumed] == 10
     714             419 :                 || szChunk[nChunkBytesConsumed] == 13 )
     715                 :             {
     716             732 :                 nChunkBytesConsumed++;
     717             732 :                 break;
     718                 :             }
     719                 : 
     720             419 :             pszRLBuffer[nBufLength++] = szChunk[nChunkBytesConsumed++];
     721             419 :             break;
     722                 :         }
     723                 :     }
     724                 : 
     725                 : /* -------------------------------------------------------------------- */
     726                 : /*      If we have left over bytes after breaking out, seek back to     */
     727                 : /*      ensure they remain to be read next time.                        */
     728                 : /* -------------------------------------------------------------------- */
     729          300831 :     if( nChunkBytesConsumed < nChunkBytesRead )
     730                 :     {
     731          297519 :         size_t nBytesToPush = nChunkBytesRead - nChunkBytesConsumed;
     732                 :         
     733          297519 :         VSIFSeekL( fp, VSIFTellL( fp ) - nBytesToPush, SEEK_SET );
     734                 :     }
     735                 : 
     736          300831 :     pszRLBuffer[nBufLength] = '\0';
     737                 : 
     738          300831 :     return( pszRLBuffer );
     739                 : }
     740                 : 
     741                 : /************************************************************************/
     742                 : /*                            CPLScanString()                           */
     743                 : /************************************************************************/
     744                 : 
     745                 : /**
     746                 :  * Scan up to a maximum number of characters from a given string,
     747                 :  * allocate a buffer for a new string and fill it with scanned characters.
     748                 :  *
     749                 :  * @param pszString String containing characters to be scanned. It may be
     750                 :  * terminated with a null character.
     751                 :  *
     752                 :  * @param nMaxLength The maximum number of character to read. Less
     753                 :  * characters will be read if a null character is encountered.
     754                 :  *
     755                 :  * @param bTrimSpaces If TRUE, trim ending spaces from the input string.
     756                 :  * Character considered as empty using isspace(3) function.
     757                 :  *
     758                 :  * @param bNormalize If TRUE, replace ':' symbol with the '_'. It is needed if
     759                 :  * resulting string will be used in CPL dictionaries.
     760                 :  * 
     761                 :  * @return Pointer to the resulting string buffer. Caller responsible to free
     762                 :  * this buffer with CPLFree().
     763                 :  */
     764                 : 
     765            4470 : char *CPLScanString( const char *pszString, int nMaxLength,
     766                 :                      int bTrimSpaces, int bNormalize )
     767                 : {
     768                 :     char    *pszBuffer;
     769                 : 
     770            4470 :     if ( !pszString )
     771               0 :         return NULL;
     772                 : 
     773            4470 :     if ( !nMaxLength )
     774               2 :         return CPLStrdup( "" );
     775                 : 
     776            4468 :     pszBuffer = (char *)CPLMalloc( nMaxLength + 1 );
     777            4468 :     if ( !pszBuffer )
     778               0 :         return NULL;
     779                 : 
     780            4468 :     strncpy( pszBuffer, pszString,  nMaxLength );
     781            4468 :     pszBuffer[nMaxLength] = '\0';
     782                 : 
     783            4468 :     if ( bTrimSpaces )
     784                 :     {
     785            4466 :         size_t  i = strlen( pszBuffer );
     786            9499 :         while ( i-- > 0 && isspace((unsigned char)pszBuffer[i]) )
     787             567 :             pszBuffer[i] = '\0';
     788                 :     }
     789                 : 
     790            4468 :     if ( bNormalize )
     791                 :     {
     792            4405 :         size_t  i = strlen( pszBuffer );
     793           38433 :         while ( i-- > 0 )
     794                 :         {
     795           29623 :             if ( pszBuffer[i] == ':' )
     796               0 :                 pszBuffer[i] = '_';
     797                 :         }
     798                 :     }
     799                 : 
     800            4468 :     return pszBuffer;
     801                 : }
     802                 : 
     803                 : /************************************************************************/
     804                 : /*                             CPLScanLong()                            */
     805                 : /************************************************************************/
     806                 : 
     807                 : /**
     808                 :  * Scan up to a maximum number of characters from a string and convert
     809                 :  * the result to a long.
     810                 :  *
     811                 :  * @param pszString String containing characters to be scanned. It may be
     812                 :  * terminated with a null character.
     813                 :  *
     814                 :  * @param nMaxLength The maximum number of character to consider as part
     815                 :  * of the number. Less characters will be considered if a null character
     816                 :  * is encountered.
     817                 :  * 
     818                 :  * @return Long value, converted from its ASCII form.
     819                 :  */
     820                 : 
     821              15 : long CPLScanLong( const char *pszString, int nMaxLength )
     822                 : {
     823                 :     long    iValue;
     824              15 :     char    *pszValue = (char *)CPLMalloc( nMaxLength + 1);
     825                 : 
     826                 : /* -------------------------------------------------------------------- */
     827                 : /*      Compute string into local buffer, and terminate it.             */
     828                 : /* -------------------------------------------------------------------- */
     829              15 :     strncpy( pszValue, pszString, nMaxLength );
     830              15 :     pszValue[nMaxLength] = '\0';
     831                 : 
     832                 : /* -------------------------------------------------------------------- */
     833                 : /*      Use atol() to fetch out the result                              */
     834                 : /* -------------------------------------------------------------------- */
     835              15 :     iValue = atol( pszValue );
     836                 : 
     837              15 :     CPLFree( pszValue );
     838              15 :     return iValue;
     839                 : }
     840                 : 
     841                 : 
     842                 : /************************************************************************/
     843                 : /*                            CPLScanULong()                            */
     844                 : /************************************************************************/
     845                 : 
     846                 : /**
     847                 :  * Scan up to a maximum number of characters from a string and convert
     848                 :  * the result to a unsigned long.
     849                 :  *
     850                 :  * @param pszString String containing characters to be scanned. It may be
     851                 :  * terminated with a null character.
     852                 :  *
     853                 :  * @param nMaxLength The maximum number of character to consider as part
     854                 :  * of the number. Less characters will be considered if a null character
     855                 :  * is encountered.
     856                 :  * 
     857                 :  * @return Unsigned long value, converted from its ASCII form.
     858                 :  */
     859                 : 
     860               0 : unsigned long CPLScanULong( const char *pszString, int nMaxLength )
     861                 : {
     862                 :     unsigned long    uValue;
     863               0 :     char    *pszValue = (char *)CPLMalloc( nMaxLength + 1);
     864                 : 
     865                 : /* -------------------------------------------------------------------- */
     866                 : /*      Compute string into local buffer, and terminate it.             */
     867                 : /* -------------------------------------------------------------------- */
     868               0 :     strncpy( pszValue, pszString, nMaxLength );
     869               0 :     pszValue[nMaxLength] = '\0';
     870                 : 
     871                 : /* -------------------------------------------------------------------- */
     872                 : /*      Use strtoul() to fetch out the result                           */
     873                 : /* -------------------------------------------------------------------- */
     874               0 :     uValue = strtoul( pszValue, NULL, 10 );
     875                 : 
     876               0 :     CPLFree( pszValue );
     877               0 :     return uValue;
     878                 : }
     879                 : 
     880                 : /************************************************************************/
     881                 : /*                           CPLScanUIntBig()                           */
     882                 : /************************************************************************/
     883                 : 
     884                 : /**
     885                 :  * Extract big integer from string.
     886                 :  *
     887                 :  * Scan up to a maximum number of characters from a string and convert
     888                 :  * the result to a GUIntBig. 
     889                 :  *
     890                 :  * @param pszString String containing characters to be scanned. It may be
     891                 :  * terminated with a null character.
     892                 :  *
     893                 :  * @param nMaxLength The maximum number of character to consider as part
     894                 :  * of the number. Less characters will be considered if a null character
     895                 :  * is encountered.
     896                 :  * 
     897                 :  * @return GUIntBig value, converted from its ASCII form.
     898                 :  */
     899                 : 
     900            7760 : GUIntBig CPLScanUIntBig( const char *pszString, int nMaxLength )
     901                 : {
     902                 :     GUIntBig    iValue;
     903            7760 :     char        *pszValue = (char *)CPLMalloc( nMaxLength + 1);
     904                 : 
     905                 : /* -------------------------------------------------------------------- */
     906                 : /*      Compute string into local buffer, and terminate it.             */
     907                 : /* -------------------------------------------------------------------- */
     908            7760 :     strncpy( pszValue, pszString, nMaxLength );
     909            7760 :     pszValue[nMaxLength] = '\0';
     910                 : 
     911                 : /* -------------------------------------------------------------------- */
     912                 : /*      Fetch out the result                                            */
     913                 : /* -------------------------------------------------------------------- */
     914                 : #if defined(__MSVCRT__) || (defined(WIN32) && defined(_MSC_VER))
     915                 :     iValue = (GUIntBig)_atoi64( pszValue );
     916                 : # elif HAVE_ATOLL
     917            7760 :     iValue = atoll( pszValue );
     918                 : #else
     919                 :     iValue = atol( pszValue );
     920                 : #endif
     921                 : 
     922            7760 :     CPLFree( pszValue );
     923            7760 :     return iValue;
     924                 : }
     925                 : 
     926                 : /************************************************************************/
     927                 : /*                           CPLScanPointer()                           */
     928                 : /************************************************************************/
     929                 : 
     930                 : /**
     931                 :  * Extract pointer from string.
     932                 :  *
     933                 :  * Scan up to a maximum number of characters from a string and convert
     934                 :  * the result to a pointer. 
     935                 :  *
     936                 :  * @param pszString String containing characters to be scanned. It may be
     937                 :  * terminated with a null character.
     938                 :  *
     939                 :  * @param nMaxLength The maximum number of character to consider as part
     940                 :  * of the number. Less characters will be considered if a null character
     941                 :  * is encountered.
     942                 :  * 
     943                 :  * @return pointer value, converted from its ASCII form.
     944                 :  */
     945                 : 
     946             273 : void *CPLScanPointer( const char *pszString, int nMaxLength )
     947                 : {
     948                 :     void  *pResult;
     949                 :     char  szTemp[128];
     950                 : 
     951                 : /* -------------------------------------------------------------------- */
     952                 : /*      Compute string into local buffer, and terminate it.             */
     953                 : /* -------------------------------------------------------------------- */
     954             273 :     if( nMaxLength > (int) sizeof(szTemp)-1 )
     955               0 :         nMaxLength = sizeof(szTemp)-1;
     956                 : 
     957             273 :     strncpy( szTemp, pszString, nMaxLength );
     958             273 :     szTemp[nMaxLength] = '\0';
     959                 : 
     960                 : /* -------------------------------------------------------------------- */
     961                 : /*      On MSVC we have to scanf pointer values without the 0x          */
     962                 : /*      prefix.                                                         */
     963                 : /* -------------------------------------------------------------------- */
     964             273 :     if( EQUALN(szTemp,"0x",2) )
     965                 :     {
     966             273 :         pResult = NULL;
     967                 : 
     968                 : #if defined(__MSVCRT__) || (defined(WIN32) && defined(_MSC_VER))
     969                 :         sscanf( szTemp+2, "%p", &pResult );
     970                 : #else
     971             273 :         sscanf( szTemp, "%p", &pResult );
     972                 : 
     973                 :         /* Solaris actually behaves like MSVCRT... */
     974             273 :         if (pResult == NULL)
     975                 :         {
     976               0 :             sscanf( szTemp+2, "%p", &pResult );
     977                 :         }
     978                 : #endif
     979                 :     }
     980                 :     
     981                 :     else
     982                 :     {
     983                 : #if SIZEOF_VOIDP == 8
     984               0 :         pResult = (void *) CPLScanUIntBig( szTemp, nMaxLength );
     985                 : #else
     986                 :         pResult = (void *) CPLScanULong( szTemp, nMaxLength );
     987                 : #endif
     988                 :     }
     989                 : 
     990             273 :     return pResult;
     991                 : }
     992                 : 
     993                 : /************************************************************************/
     994                 : /*                             CPLScanDouble()                          */
     995                 : /************************************************************************/
     996                 : 
     997                 : /**
     998                 :  * Extract double from string.
     999                 :  *
    1000                 :  * Scan up to a maximum number of characters from a string and convert the
    1001                 :  * result to a double. This function uses CPLAtof() to convert string to
    1002                 :  * double value, so it uses a comma as a decimal delimiter.
    1003                 :  *
    1004                 :  * @param pszString String containing characters to be scanned. It may be
    1005                 :  * terminated with a null character.
    1006                 :  *
    1007                 :  * @param nMaxLength The maximum number of character to consider as part
    1008                 :  * of the number. Less characters will be considered if a null character
    1009                 :  * is encountered.
    1010                 :  * 
    1011                 :  * @return Double value, converted from its ASCII form.
    1012                 :  */
    1013                 : 
    1014             161 : double CPLScanDouble( const char *pszString, int nMaxLength )
    1015                 : {
    1016                 :     int     i;
    1017                 :     double  dfValue;
    1018             161 :     char    *pszValue = (char *)CPLMalloc( nMaxLength + 1);
    1019                 : 
    1020                 : /* -------------------------------------------------------------------- */
    1021                 : /*      Compute string into local buffer, and terminate it.             */
    1022                 : /* -------------------------------------------------------------------- */
    1023             161 :     strncpy( pszValue, pszString, nMaxLength );
    1024             161 :     pszValue[nMaxLength] = '\0';
    1025                 : 
    1026                 : /* -------------------------------------------------------------------- */
    1027                 : /*      Make a pass through converting 'D's to 'E's.                    */
    1028                 : /* -------------------------------------------------------------------- */
    1029            3409 :     for( i = 0; i < nMaxLength; i++ )
    1030            3248 :         if ( pszValue[i] == 'd' || pszValue[i] == 'D' )
    1031              30 :             pszValue[i] = 'E';
    1032                 : 
    1033                 : /* -------------------------------------------------------------------- */
    1034                 : /*      The conversion itself.                                          */
    1035                 : /* -------------------------------------------------------------------- */
    1036             161 :     dfValue = CPLAtof( pszValue );
    1037                 : 
    1038             161 :     CPLFree( pszValue );
    1039             161 :     return dfValue;
    1040                 : }
    1041                 : 
    1042                 : /************************************************************************/
    1043                 : /*                      CPLPrintString()                                */
    1044                 : /************************************************************************/
    1045                 : 
    1046                 : /**
    1047                 :  * Copy the string pointed to by pszSrc, NOT including the terminating
    1048                 :  * `\\0' character, to the array pointed to by pszDest.
    1049                 :  *
    1050                 :  * @param pszDest Pointer to the destination string buffer. Should be
    1051                 :  * large enough to hold the resulting string.
    1052                 :  *
    1053                 :  * @param pszSrc Pointer to the source buffer.
    1054                 :  * 
    1055                 :  * @param nMaxLen Maximum length of the resulting string. If string length
    1056                 :  * is greater than nMaxLen, it will be truncated.
    1057                 :  * 
    1058                 :  * @return Number of characters printed.
    1059                 :  */
    1060                 : 
    1061            1562 : int CPLPrintString( char *pszDest, const char *pszSrc, int nMaxLen )
    1062                 : {
    1063            1562 :     char    *pszTemp = pszDest;
    1064            1562 :     int     nChars = 0;
    1065                 : 
    1066            1562 :     if ( !pszDest )
    1067               0 :         return 0;
    1068                 : 
    1069            1562 :     if ( !pszSrc )
    1070                 :     {
    1071               0 :         *pszDest = '\0';
    1072               0 :         return 1;
    1073                 :     }
    1074                 : 
    1075           41530 :     while ( nChars < nMaxLen && *pszSrc )
    1076                 :     {
    1077           38406 :         *pszTemp++ = *pszSrc++;
    1078           38406 :         nChars++;
    1079                 :     }
    1080                 : 
    1081            1562 :     return nChars;
    1082                 : }
    1083                 : 
    1084                 : /************************************************************************/
    1085                 : /*                         CPLPrintStringFill()                         */
    1086                 : /************************************************************************/
    1087                 : 
    1088                 : /**
    1089                 :  * Copy the string pointed to by pszSrc, NOT including the terminating
    1090                 :  * `\\0' character, to the array pointed to by pszDest. Remainder of the
    1091                 :  * destination string will be filled with space characters. This is only
    1092                 :  * difference from the PrintString().
    1093                 :  *
    1094                 :  * @param pszDest Pointer to the destination string buffer. Should be
    1095                 :  * large enough to hold the resulting string.
    1096                 :  *
    1097                 :  * @param pszSrc Pointer to the source buffer.
    1098                 :  * 
    1099                 :  * @param nMaxLen Maximum length of the resulting string. If string length
    1100                 :  * is greater than nMaxLen, it will be truncated.
    1101                 :  * 
    1102                 :  * @return Number of characters printed.
    1103                 :  */
    1104                 : 
    1105             154 : int CPLPrintStringFill( char *pszDest, const char *pszSrc, int nMaxLen )
    1106                 : {
    1107             154 :     char    *pszTemp = pszDest;
    1108                 : 
    1109             154 :     if ( !pszDest )
    1110               0 :         return 0;
    1111                 : 
    1112             154 :     if ( !pszSrc )
    1113                 :     {
    1114               0 :         memset( pszDest, ' ', nMaxLen );
    1115               0 :         return nMaxLen;
    1116                 :     }
    1117                 : 
    1118            1101 :     while ( nMaxLen && *pszSrc )
    1119                 :     {
    1120             793 :         *pszTemp++ = *pszSrc++;
    1121             793 :         nMaxLen--;
    1122                 :     }
    1123                 : 
    1124             154 :     if ( nMaxLen )
    1125              52 :         memset( pszTemp, ' ', nMaxLen );
    1126                 : 
    1127             154 :     return nMaxLen;
    1128                 : }
    1129                 : 
    1130                 : /************************************************************************/
    1131                 : /*                          CPLPrintInt32()                             */
    1132                 : /************************************************************************/
    1133                 : 
    1134                 : /**
    1135                 :  * Print GInt32 value into specified string buffer. This string will not
    1136                 :  * be NULL-terminated.
    1137                 :  *
    1138                 :  * @param pszBuffer Pointer to the destination string buffer. Should be
    1139                 :  * large enough to hold the resulting string. Note, that the string will
    1140                 :  * not be NULL-terminated, so user should do this himself, if needed.
    1141                 :  *
    1142                 :  * @param iValue Numerical value to print.
    1143                 :  * 
    1144                 :  * @param nMaxLen Maximum length of the resulting string. If string length
    1145                 :  * is greater than nMaxLen, it will be truncated.
    1146                 :  * 
    1147                 :  * @return Number of characters printed.
    1148                 :  */
    1149                 : 
    1150               4 : int CPLPrintInt32( char *pszBuffer, GInt32 iValue, int nMaxLen )
    1151                 : {
    1152                 :     char    szTemp[64];
    1153                 : 
    1154               4 :     if ( !pszBuffer )
    1155               0 :         return 0;
    1156                 : 
    1157               4 :     if ( nMaxLen >= 64 )
    1158               0 :         nMaxLen = 63;
    1159                 : 
    1160                 : #if UINT_MAX == 65535
    1161                 :     sprintf( szTemp, "%*ld", nMaxLen, iValue );
    1162                 : #else
    1163               4 :     sprintf( szTemp, "%*d", nMaxLen, iValue );
    1164                 : #endif
    1165                 : 
    1166               4 :     return CPLPrintString( pszBuffer, szTemp, nMaxLen );
    1167                 : }
    1168                 : 
    1169                 : /************************************************************************/
    1170                 : /*                          CPLPrintUIntBig()                           */
    1171                 : /************************************************************************/
    1172                 : 
    1173                 : /**
    1174                 :  * Print GUIntBig value into specified string buffer. This string will not
    1175                 :  * be NULL-terminated.
    1176                 :  *
    1177                 :  * @param pszBuffer Pointer to the destination string buffer. Should be
    1178                 :  * large enough to hold the resulting string. Note, that the string will
    1179                 :  * not be NULL-terminated, so user should do this himself, if needed.
    1180                 :  *
    1181                 :  * @param iValue Numerical value to print.
    1182                 :  * 
    1183                 :  * @param nMaxLen Maximum length of the resulting string. If string length
    1184                 :  * is greater than nMaxLen, it will be truncated.
    1185                 :  * 
    1186                 :  * @return Number of characters printed.
    1187                 :  */
    1188                 : 
    1189              12 : int CPLPrintUIntBig( char *pszBuffer, GUIntBig iValue, int nMaxLen )
    1190                 : {
    1191                 :     char    szTemp[64];
    1192                 : 
    1193              12 :     if ( !pszBuffer )
    1194               0 :         return 0;
    1195                 : 
    1196              12 :     if ( nMaxLen >= 64 )
    1197               0 :         nMaxLen = 63;
    1198                 : 
    1199                 : #if defined(__MSVCRT__) || (defined(WIN32) && defined(_MSC_VER))
    1200                 :     sprintf( szTemp, "%*I64d", nMaxLen, iValue );
    1201                 : # elif HAVE_LONG_LONG
    1202              12 :     sprintf( szTemp, "%*lld", nMaxLen, (long long) iValue );
    1203                 : //    sprintf( szTemp, "%*Ld", nMaxLen, (long long) iValue );
    1204                 : #else
    1205                 :     sprintf( szTemp, "%*ld", nMaxLen, iValue );
    1206                 : #endif
    1207                 : 
    1208              12 :     return CPLPrintString( pszBuffer, szTemp, nMaxLen );
    1209                 : }
    1210                 : 
    1211                 : /************************************************************************/
    1212                 : /*                          CPLPrintPointer()                           */
    1213                 : /************************************************************************/
    1214                 : 
    1215                 : /**
    1216                 :  * Print pointer value into specified string buffer. This string will not
    1217                 :  * be NULL-terminated.
    1218                 :  *
    1219                 :  * @param pszBuffer Pointer to the destination string buffer. Should be
    1220                 :  * large enough to hold the resulting string. Note, that the string will
    1221                 :  * not be NULL-terminated, so user should do this himself, if needed.
    1222                 :  *
    1223                 :  * @param pValue Pointer to ASCII encode.
    1224                 :  * 
    1225                 :  * @param nMaxLen Maximum length of the resulting string. If string length
    1226                 :  * is greater than nMaxLen, it will be truncated.
    1227                 :  * 
    1228                 :  * @return Number of characters printed.
    1229                 :  */
    1230                 : 
    1231             271 : int CPLPrintPointer( char *pszBuffer, void *pValue, int nMaxLen )
    1232                 : {
    1233                 :     char    szTemp[64];
    1234                 : 
    1235             271 :     if ( !pszBuffer )
    1236               0 :         return 0;
    1237                 : 
    1238             271 :     if ( nMaxLen >= 64 )
    1239             270 :         nMaxLen = 63;
    1240                 : 
    1241             271 :     sprintf( szTemp, "%p", pValue );
    1242                 : 
    1243                 :     // On windows, and possibly some other platforms the sprintf("%p")
    1244                 :     // does not prefix things with 0x so it is hard to know later if the
    1245                 :     // value is hex encoded.  Fix this up here. 
    1246                 : 
    1247             271 :     if( !EQUALN(szTemp,"0x",2) )
    1248               0 :         sprintf( szTemp, "0x%p", pValue );
    1249                 : 
    1250             271 :     return CPLPrintString( pszBuffer, szTemp, nMaxLen );
    1251                 : }
    1252                 : 
    1253                 : /************************************************************************/
    1254                 : /*                          CPLPrintDouble()                            */
    1255                 : /************************************************************************/
    1256                 : 
    1257                 : /**
    1258                 :  * Print double value into specified string buffer. Exponential character
    1259                 :  * flag 'E' (or 'e') will be replaced with 'D', as in Fortran. Resulting
    1260                 :  * string will not to be NULL-terminated.
    1261                 :  *
    1262                 :  * @param pszBuffer Pointer to the destination string buffer. Should be
    1263                 :  * large enough to hold the resulting string. Note, that the string will
    1264                 :  * not be NULL-terminated, so user should do this himself, if needed.
    1265                 :  *
    1266                 :  * @param pszFormat Format specifier (for example, "%16.9E").
    1267                 :  *
    1268                 :  * @param dfValue Numerical value to print.
    1269                 :  * 
    1270                 :  * @param pszLocale Pointer to a character string containing locale name
    1271                 :  * ("C", "POSIX", "us_US", "ru_RU.KOI8-R" etc.). If NULL we will not
    1272                 :  * manipulate with locale settings and current process locale will be used for
    1273                 :  * printing. With the pszLocale option we can control what exact locale
    1274                 :  * will be used for printing a numeric value to the string (in most cases
    1275                 :  * it should be C/POSIX).
    1276                 :  *
    1277                 :  * @return Number of characters printed.
    1278                 :  */
    1279                 : 
    1280               0 : int CPLPrintDouble( char *pszBuffer, const char *pszFormat,
    1281                 :                     double dfValue, const char *pszLocale )
    1282                 : {
    1283                 : 
    1284                 : #define DOUBLE_BUFFER_SIZE 64
    1285                 : 
    1286                 :     char    szTemp[DOUBLE_BUFFER_SIZE];
    1287                 :     int     i;
    1288                 : 
    1289               0 :     if ( !pszBuffer )
    1290               0 :         return 0;
    1291                 : 
    1292                 : #if defined(HAVE_LOCALE_H) && defined(HAVE_SETLOCALE)
    1293                 :     char        *pszCurLocale = NULL;
    1294                 : 
    1295                 :     if ( pszLocale || EQUAL( pszLocale, "" ) )
    1296                 :     {
    1297                 :         // Save the current locale
    1298                 :         pszCurLocale = setlocale(LC_ALL, NULL );
    1299                 :         // Set locale to the specified value
    1300                 :         setlocale( LC_ALL, pszLocale );
    1301                 :     }
    1302                 : #else
    1303                 :     (void) pszLocale;
    1304                 : #endif
    1305                 : 
    1306                 : #if defined(HAVE_SNPRINTF)
    1307               0 :     snprintf( szTemp, DOUBLE_BUFFER_SIZE, pszFormat, dfValue );
    1308                 : #else
    1309                 :     sprintf( szTemp, pszFormat, dfValue );
    1310                 : #endif
    1311               0 :     szTemp[DOUBLE_BUFFER_SIZE - 1] = '\0';
    1312                 : 
    1313               0 :     for( i = 0; szTemp[i] != '\0'; i++ )
    1314                 :     {
    1315               0 :         if( szTemp[i] == 'E' || szTemp[i] == 'e' )
    1316               0 :             szTemp[i] = 'D';
    1317                 :     }
    1318                 : 
    1319                 : #if defined(HAVE_LOCALE_H) && defined(HAVE_SETLOCALE)
    1320                 :     // Restore stored locale back
    1321                 :     if ( pszCurLocale )
    1322                 :         setlocale( LC_ALL, pszCurLocale );
    1323                 : #endif
    1324                 : 
    1325               0 :     return CPLPrintString( pszBuffer, szTemp, 64 );
    1326                 : 
    1327                 : #undef DOUBLE_BUFFER_SIZE
    1328                 : 
    1329                 : }
    1330                 : 
    1331                 : /************************************************************************/
    1332                 : /*                            CPLPrintTime()                            */
    1333                 : /************************************************************************/
    1334                 : 
    1335                 : /**
    1336                 :  * Print specified time value accordingly to the format options and
    1337                 :  * specified locale name. This function does following:
    1338                 :  * 
    1339                 :  *  - if locale parameter is not NULL, the current locale setting will be
    1340                 :  *  stored and replaced with the specified one;
    1341                 :  *  - format time value with the strftime(3) function;
    1342                 :  *  - restore back current locale, if was saved.
    1343                 :  * 
    1344                 :  * @param pszBuffer Pointer to the destination string buffer. Should be
    1345                 :  * large enough to hold the resulting string. Note, that the string will
    1346                 :  * not be NULL-terminated, so user should do this himself, if needed.
    1347                 :  *
    1348                 :  * @param nMaxLen Maximum length of the resulting string. If string length is
    1349                 :  * greater than nMaxLen, it will be truncated.
    1350                 :  * 
    1351                 :  * @param pszFormat Controls the output format. Options are the same as
    1352                 :  * for strftime(3) function.
    1353                 :  *
    1354                 :  * @param poBrokenTime Pointer to the broken-down time structure. May be
    1355                 :  * requested with the VSIGMTime() and VSILocalTime() functions.
    1356                 :  *
    1357                 :  * @param pszLocale Pointer to a character string containing locale name
    1358                 :  * ("C", "POSIX", "us_US", "ru_RU.KOI8-R" etc.). If NULL we will not
    1359                 :  * manipulate with locale settings and current process locale will be used for
    1360                 :  * printing. Be aware that it may be unsuitable to use current locale for
    1361                 :  * printing time, because all names will be printed in your native language,
    1362                 :  * as well as time format settings also may be ajusted differently from the
    1363                 :  * C/POSIX defaults. To solve these problems this option was introdiced.
    1364                 :  *
    1365                 :  * @return Number of characters printed.
    1366                 :  */
    1367                 : 
    1368                 : #ifndef WIN32CE /* XXX - mloskot - strftime is not available yet. */
    1369                 : 
    1370               0 : int CPLPrintTime( char *pszBuffer, int nMaxLen, const char *pszFormat,
    1371                 :                   const struct tm *poBrokenTime, const char *pszLocale )
    1372                 : {
    1373               0 :     char    *pszTemp = (char *)CPLMalloc( (nMaxLen + 1) * sizeof(char) );
    1374                 :     int     nChars;
    1375                 : 
    1376                 : #if defined(HAVE_LOCALE_H) && defined(HAVE_SETLOCALE)
    1377                 :     char        *pszCurLocale = NULL;
    1378                 : 
    1379                 :     if ( pszLocale || EQUAL( pszLocale, "" ) )
    1380                 :     {
    1381                 :         // Save the current locale
    1382                 :         pszCurLocale = setlocale(LC_ALL, NULL );
    1383                 :         // Set locale to the specified value
    1384                 :         setlocale( LC_ALL, pszLocale );
    1385                 :     }
    1386                 : #else
    1387                 :     (void) pszLocale;
    1388                 : #endif
    1389                 :     
    1390               0 :     if ( !strftime( pszTemp, nMaxLen + 1, pszFormat, poBrokenTime ) )
    1391               0 :         memset( pszTemp, 0, nMaxLen + 1);
    1392                 : 
    1393                 : #if defined(HAVE_LOCALE_H) && defined(HAVE_SETLOCALE)
    1394                 :     // Restore stored locale back
    1395                 :     if ( pszCurLocale )
    1396                 :         setlocale( LC_ALL, pszCurLocale );
    1397                 : #endif
    1398                 : 
    1399               0 :     nChars = CPLPrintString( pszBuffer, pszTemp, nMaxLen );
    1400                 : 
    1401               0 :     CPLFree( pszTemp );
    1402                 : 
    1403               0 :     return nChars;
    1404                 : }
    1405                 : 
    1406                 : #endif
    1407                 : 
    1408                 : /************************************************************************/
    1409                 : /*                       CPLVerifyConfiguration()                       */
    1410                 : /************************************************************************/
    1411                 : 
    1412        42402646 : void CPLVerifyConfiguration()
    1413                 : 
    1414                 : {
    1415                 : /* -------------------------------------------------------------------- */
    1416                 : /*      Verify data types.                                              */
    1417                 : /* -------------------------------------------------------------------- */
    1418                 :     CPLAssert( sizeof(GInt32) == 4 );
    1419                 :     CPLAssert( sizeof(GInt16) == 2 );
    1420                 :     CPLAssert( sizeof(GByte) == 1 );
    1421                 : 
    1422                 :     if( sizeof(GInt32) != 4 )
    1423                 :         CPLError( CE_Fatal, CPLE_AppDefined, 
    1424                 :                   "sizeof(GInt32) == %d ... yow!\n", 
    1425                 :                   (int) sizeof(GInt32) );
    1426                 : 
    1427                 : /* -------------------------------------------------------------------- */
    1428                 : /*      Verify byte order                                               */
    1429                 : /* -------------------------------------------------------------------- */
    1430                 :     GInt32   nTest;
    1431                 : 
    1432        42402646 :     nTest = 1;
    1433                 : 
    1434                 : #ifdef CPL_LSB
    1435        42402646 :     if( ((GByte *) &nTest)[0] != 1 )
    1436                 : #endif
    1437                 : #ifdef CPL_MSB
    1438                 :     if( ((GByte *) &nTest)[3] != 1 )
    1439                 : #endif    
    1440                 :         CPLError( CE_Fatal, CPLE_AppDefined, 
    1441               0 :                   "CPLVerifyConfiguration(): byte order set wrong.\n" );
    1442        42402646 : }
    1443                 : 
    1444                 : /* Uncomment to get list of options that have been fetched and set */
    1445                 : //#define DEBUG_CONFIG_OPTIONS
    1446                 : 
    1447                 : #ifdef DEBUG_CONFIG_OPTIONS
    1448                 : 
    1449                 : #include <set>
    1450                 : #include "cpl_multiproc.h"
    1451                 : 
    1452                 : static void* hRegisterConfigurationOptionMutex = 0;
    1453                 : static std::set<CPLString>* paoGetKeys = NULL;
    1454                 : static std::set<CPLString>* paoSetKeys = NULL;
    1455                 : 
    1456                 : /************************************************************************/
    1457                 : /*                      CPLShowAccessedOptions()                        */
    1458                 : /************************************************************************/
    1459                 : 
    1460                 : static void CPLShowAccessedOptions()
    1461                 : {
    1462                 :     std::set<CPLString>::iterator aoIter;
    1463                 : 
    1464                 :     printf("Configuration options accessed in reading : "),
    1465                 :     aoIter = paoGetKeys->begin();
    1466                 :     while(aoIter != paoGetKeys->end())
    1467                 :     {
    1468                 :         printf("%s, ", (*aoIter).c_str());
    1469                 :         aoIter ++;
    1470                 :     }
    1471                 :     printf("\n");
    1472                 : 
    1473                 :     printf("Configuration options accessed in writing : "),
    1474                 :     aoIter = paoSetKeys->begin();
    1475                 :     while(aoIter != paoSetKeys->end())
    1476                 :     {
    1477                 :         printf("%s, ", (*aoIter).c_str());
    1478                 :         aoIter ++;
    1479                 :     }
    1480                 :     printf("\n");
    1481                 : 
    1482                 :     delete paoGetKeys;
    1483                 :     delete paoSetKeys;
    1484                 :     paoGetKeys = paoSetKeys = NULL;
    1485                 : }
    1486                 : 
    1487                 : /************************************************************************/
    1488                 : /*                       CPLAccessConfigOption()                        */
    1489                 : /************************************************************************/
    1490                 : 
    1491                 : static void CPLAccessConfigOption(const char* pszKey, int bGet)
    1492                 : {
    1493                 :     CPLMutexHolderD(&hRegisterConfigurationOptionMutex);
    1494                 :     if (paoGetKeys == NULL)
    1495                 :     {
    1496                 :         paoGetKeys = new std::set<CPLString>;
    1497                 :         paoSetKeys = new std::set<CPLString>;
    1498                 :         atexit(CPLShowAccessedOptions);
    1499                 :     }
    1500                 :     if (bGet)
    1501                 :         paoGetKeys->insert(pszKey);
    1502                 :     else
    1503                 :         paoSetKeys->insert(pszKey);
    1504                 : }
    1505                 : #endif
    1506                 : 
    1507                 : /************************************************************************/
    1508                 : /*                         CPLGetConfigOption()                         */
    1509                 : /************************************************************************/
    1510                 : 
    1511                 : /**
    1512                 :   * Get the value of a configuration option.
    1513                 :   * 
    1514                 :   * The value is the value of a (key, value) option set with CPLSetConfigOption().
    1515                 :   * If the given option was no defined with CPLSetConfigOption(), it tries to find
    1516                 :   * it in environment variables.
    1517                 :   *
    1518                 :   * Note: the string returned by CPLGetConfigOption() might be short-lived, and in
    1519                 :   * particular it will become invalid after a call to CPLSetConfigOption() with the
    1520                 :   * same key.
    1521                 :   *
    1522                 :   * To override temporary a potentially existing option with a new value, you can
    1523                 :   * use the following snippet :
    1524                 :   * <pre>
    1525                 :   *     // backup old value
    1526                 :   *     const char* pszOldValTmp = CPLGetConfigOption(pszKey, NULL);
    1527                 :   *     char* pszOldVal = pszOldValTmp ? CPLStrdup(pszOldValTmp) : NULL;
    1528                 :   *     // override with new value
    1529                 :   *     CPLSetConfigOption(pszKey, pszNewVal);
    1530                 :   *     // do something usefull
    1531                 :   *     // restore old value
    1532                 :   *     CPLSetConfigOption(pszKey, pszOldVal);
    1533                 :   *     CPLFree(pszOldVal);
    1534                 :   * </pre>
    1535                 :   *
    1536                 :   * @param pszKey the key of the option to retrieve
    1537                 :   * @param pszDefault a default value if the key does not match existing defined options (may be NULL)
    1538                 :   * @return the value associated to the key, or the default value if not found
    1539                 :   *
    1540                 :   * @see CPLSetConfigOption(), http://trac.osgeo.org/gdal/wiki/ConfigOptions
    1541                 :   */
    1542                 : const char * CPL_STDCALL
    1543         1148224 : CPLGetConfigOption( const char *pszKey, const char *pszDefault )
    1544                 : 
    1545                 : {
    1546                 : #ifdef DEBUG_CONFIG_OPTIONS
    1547                 :     CPLAccessConfigOption(pszKey, TRUE);
    1548                 : #endif
    1549                 : 
    1550         1148224 :     const char *pszResult = NULL;
    1551                 : 
    1552         1148224 :     char **papszTLConfigOptions = (char **) CPLGetTLS( CTLS_CONFIGOPTIONS );
    1553         1148224 :     if( papszTLConfigOptions != NULL )
    1554          866624 :         pszResult = CSLFetchNameValue( papszTLConfigOptions, pszKey );
    1555                 : 
    1556         1148224 :     if( pszResult == NULL )
    1557                 :     {
    1558         1148038 :         CPLMutexHolderD( &hConfigMutex );
    1559                 : 
    1560         1148038 :         pszResult = CSLFetchNameValue( (char **) papszConfigOptions, pszKey );
    1561                 :     }
    1562                 : 
    1563                 : #if !defined(WIN32CE) 
    1564         1148224 :     if( pszResult == NULL )
    1565          470685 :         pszResult = getenv( pszKey );
    1566                 : #endif
    1567                 :     
    1568         1148223 :     if( pszResult == NULL )
    1569          469160 :         return pszDefault;
    1570                 :     else
    1571          679063 :         return pszResult;
    1572                 : }
    1573                 : 
    1574                 : /************************************************************************/
    1575                 : /*                         CPLSetConfigOption()                         */
    1576                 : /************************************************************************/
    1577                 : 
    1578                 : /**
    1579                 :   * Set a configuration option for GDAL/OGR use.
    1580                 :   *
    1581                 :   * Those options are defined as a (key, value) couple. The value corresponding
    1582                 :   * to a key can be got later with the CPLGetConfigOption() method.
    1583                 :   *
    1584                 :   * This mechanism is similar to environment variables, but options set with
    1585                 :   * CPLSetConfigOption() overrides, for CPLGetConfigOption() point of view,
    1586                 :   * values defined in the environment.
    1587                 :   *
    1588                 :   * If CPLSetConfigOption() is called several times with the same key, the
    1589                 :   * value provided during the last call will be used.
    1590                 :   *
    1591                 :   * Options can also be passed on the command line of most GDAL utilities
    1592                 :   * with the with '--config KEY VALUE'. For example,
    1593                 :   * ogrinfo --config CPL_DEBUG ON ~/data/test/point.shp
    1594                 :   *
    1595                 :   * This function can also be used to clear a setting by passing NULL as the
    1596                 :   * value (note: passing NULL will not unset an existing environment variable;
    1597                 :   * it will just unset a value previously set by CPLSetConfigOption()).
    1598                 :   *
    1599                 :   * @param pszKey the key of the option
    1600                 :   * @param pszValue the value of the option, or NULL to clear a setting.
    1601                 :   * 
    1602                 :   * @see http://trac.osgeo.org/gdal/wiki/ConfigOptions
    1603                 :   */
    1604                 : void CPL_STDCALL 
    1605             578 : CPLSetConfigOption( const char *pszKey, const char *pszValue )
    1606                 : 
    1607                 : {
    1608                 : #ifdef DEBUG_CONFIG_OPTIONS
    1609                 :     CPLAccessConfigOption(pszKey, FALSE);
    1610                 : #endif
    1611             578 :     CPLMutexHolderD( &hConfigMutex );
    1612                 : 
    1613                 :     papszConfigOptions = (volatile char **) 
    1614             578 :         CSLSetNameValue( (char **) papszConfigOptions, pszKey, pszValue );
    1615             578 : }
    1616                 : 
    1617                 : /************************************************************************/
    1618                 : /*                   CPLSetThreadLocalConfigOption()                    */
    1619                 : /************************************************************************/
    1620                 : 
    1621                 : /**
    1622                 :   * Set a configuration option for GDAL/OGR use.
    1623                 :   *
    1624                 :   * Those options are defined as a (key, value) couple. The value corresponding
    1625                 :   * to a key can be got later with the CPLGetConfigOption() method.  
    1626                 :   *
    1627                 :   * This function sets the configuration option that only applies in the
    1628                 :   * current thread, as opposed to CPLSetConfigOption() which sets an option
    1629                 :   * that applies on all threads.
    1630                 :   *
    1631                 :   * This function can also be used to clear a setting by passing NULL as the
    1632                 :   * value (note: passing NULL will not unset an existing environment variable;
    1633                 :   * it will just unset a value previously set by CPLSetThreadLocalConfigOption()).
    1634                 :   *
    1635                 :   * @param pszKey the key of the option
    1636                 :   * @param pszValue the value of the option, or NULL to clear a setting.
    1637                 :   */
    1638                 : 
    1639                 : void CPL_STDCALL 
    1640             222 : CPLSetThreadLocalConfigOption( const char *pszKey, const char *pszValue )
    1641                 : 
    1642                 : {
    1643                 : #ifdef DEBUG_CONFIG_OPTIONS
    1644                 :     CPLAccessConfigOption(pszKey, FALSE);
    1645                 : #endif
    1646                 : 
    1647             222 :     char **papszTLConfigOptions = (char **) CPLGetTLS( CTLS_CONFIGOPTIONS );
    1648                 : 
    1649                 :     papszTLConfigOptions = 
    1650             222 :         CSLSetNameValue( papszTLConfigOptions, pszKey, pszValue );
    1651                 : 
    1652             222 :     CPLSetTLSWithFreeFunc( CTLS_CONFIGOPTIONS, papszTLConfigOptions, (CPLTLSFreeFunc)CSLDestroy );
    1653             222 : }
    1654                 : 
    1655                 : /************************************************************************/
    1656                 : /*                           CPLFreeConfig()                            */
    1657                 : /************************************************************************/
    1658                 : 
    1659            1033 : void CPL_STDCALL CPLFreeConfig()
    1660                 : 
    1661                 : {
    1662                 :     {
    1663            1033 :         CPLMutexHolderD( &hConfigMutex );
    1664                 : 
    1665            1033 :         CSLDestroy( (char **) papszConfigOptions);
    1666            1033 :         papszConfigOptions = NULL;
    1667                 :         
    1668            1033 :         char **papszTLConfigOptions = (char **) CPLGetTLS( CTLS_CONFIGOPTIONS );
    1669            1033 :         if( papszTLConfigOptions != NULL )
    1670                 :         {
    1671               2 :             CSLDestroy( papszTLConfigOptions );
    1672               2 :             CPLSetTLS( CTLS_CONFIGOPTIONS, NULL, FALSE );
    1673            1033 :         }
    1674                 :     }
    1675            1033 :     CPLDestroyMutex( hConfigMutex );
    1676            1033 :     hConfigMutex = NULL;
    1677            1033 : }
    1678                 : 
    1679                 : /************************************************************************/
    1680                 : /*                              CPLStat()                               */
    1681                 : /*                                                                      */
    1682                 : /*      Same as VSIStat() except it works on "C:" as if it were         */
    1683                 : /*      "C:\".                                                          */
    1684                 : /************************************************************************/
    1685                 : 
    1686            1151 : int CPLStat( const char *pszPath, VSIStatBuf *psStatBuf )
    1687                 : 
    1688                 : {
    1689            1151 :     if( strlen(pszPath) == 2 && pszPath[1] == ':' )
    1690                 :     {
    1691                 :         char    szAltPath[4];
    1692                 :         
    1693               0 :         szAltPath[0] = pszPath[0];
    1694               0 :         szAltPath[1] = pszPath[1];
    1695               0 :         szAltPath[2] = '\\';
    1696               0 :         szAltPath[3] = '\0';
    1697               0 :         return VSIStat( szAltPath, psStatBuf );
    1698                 :     }
    1699                 :     else
    1700            1151 :         return VSIStat( pszPath, psStatBuf );
    1701                 : }
    1702                 : 
    1703                 : /************************************************************************/
    1704                 : /*                            proj_strtod()                             */
    1705                 : /************************************************************************/
    1706                 : static double
    1707             535 : proj_strtod(char *nptr, char **endptr) 
    1708                 : 
    1709                 : {
    1710             535 :     char c, *cp = nptr;
    1711                 :     double result;
    1712                 : 
    1713                 :     /*
    1714                 :      * Scan for characters which cause problems with VC++ strtod()
    1715                 :      */
    1716            2887 :     while ((c = *cp) != '\0') {
    1717            1832 :         if (c == 'd' || c == 'D') {
    1718                 : 
    1719                 :             /*
    1720                 :              * Found one, so NUL it out, call strtod(),
    1721                 :              * then restore it and return
    1722                 :              */
    1723              15 :             *cp = '\0';
    1724              15 :             result = strtod(nptr, endptr);
    1725              15 :             *cp = c;
    1726              15 :             return result;
    1727                 :         }
    1728            1817 :         ++cp;
    1729                 :     }
    1730                 : 
    1731                 :     /* no offending characters, just handle normally */
    1732                 : 
    1733             520 :     return strtod(nptr, endptr);
    1734                 : }
    1735                 : 
    1736                 : /************************************************************************/
    1737                 : /*                            CPLDMSToDec()                             */
    1738                 : /************************************************************************/
    1739                 : 
    1740                 : static const char*sym = "NnEeSsWw";
    1741                 : static const double vm[] = { 1.0, 0.0166666666667, 0.00027777778 };
    1742                 : 
    1743             523 : double CPLDMSToDec( const char *is )
    1744                 : 
    1745                 : {
    1746                 :     int sign, n, nl;
    1747                 :     char *p, *s, work[64];
    1748                 :     double v, tv;
    1749                 : 
    1750                 :     /* copy sting into work space */
    1751             523 :     while (isspace((unsigned char)(sign = *is))) ++is;
    1752            2903 :     for (n = sizeof(work), s = work, p = (char *)is; isgraph(*p) && --n ; )
    1753            1857 :         *s++ = *p++;
    1754             523 :     *s = '\0';
    1755                 :     /* it is possible that a really odd input (like lots of leading
    1756                 :        zeros) could be truncated in copying into work.  But ... */
    1757             523 :     sign = *(s = work);
    1758             523 :     if (sign == '+' || sign == '-') s++;
    1759             468 :     else sign = '+';
    1760            1058 :     for (v = 0., nl = 0 ; nl < 3 ; nl = n + 1 ) {
    1761             549 :         if (!(isdigit(*s) || *s == '.')) break;
    1762             535 :         if ((tv = proj_strtod(s, &s)) == HUGE_VAL)
    1763               0 :             return tv;
    1764             535 :         switch (*s) {
    1765                 :           case 'D': case 'd':
    1766              15 :             n = 0; break;
    1767                 :           case '\'':
    1768              11 :             n = 1; break;
    1769                 :           case '"':
    1770               7 :             n = 2; break;
    1771                 :           case 'r': case 'R':
    1772               0 :             if (nl) {
    1773               0 :                 return 0.0;
    1774                 :             }
    1775               0 :             ++s;
    1776               0 :             v = tv;
    1777               0 :             goto skip;
    1778                 :           default:
    1779             502 :             v += tv * vm[nl];
    1780             502 :           skip: n = 4;
    1781             502 :             continue;
    1782                 :         }
    1783              33 :         if (n < nl) {
    1784               0 :             return 0.0;
    1785                 :         }
    1786              33 :         v += tv * vm[n];
    1787              33 :         ++s;
    1788                 :     }
    1789                 :     /* postfix sign */
    1790             523 :     if (*s && ((p = (char *) strchr(sym, *s))) != NULL) {
    1791              17 :         sign = (p - sym) >= 4 ? '-' : '+';
    1792              17 :         ++s;
    1793                 :     }
    1794             523 :     if (sign == '-')
    1795              61 :         v = -v;
    1796                 : 
    1797             523 :     return v;
    1798                 : }
    1799                 : 
    1800                 : 
    1801                 : /************************************************************************/
    1802                 : /*                            CPLDecToDMS()                             */
    1803                 : /*                                                                      */
    1804                 : /*      Translate a decimal degrees value to a DMS string with          */
    1805                 : /*      hemisphere.                                                     */
    1806                 : /************************************************************************/
    1807                 : 
    1808             260 : const char *CPLDecToDMS( double dfAngle, const char * pszAxis,
    1809                 :                          int nPrecision )
    1810                 : 
    1811                 : {
    1812             260 :     VALIDATE_POINTER1( pszAxis, "CPLDecToDMS", "" );
    1813                 : 
    1814                 :     int         nDegrees, nMinutes;
    1815                 :     double      dfSeconds, dfABSAngle, dfEpsilon;
    1816                 :     char        szFormat[30];
    1817                 :     const char  *pszHemisphere;
    1818                 :     static CPL_THREADLOCAL char szBuffer[50] = { 0 };
    1819                 :     
    1820                 :     
    1821             260 :     dfEpsilon = (0.5/3600.0) * pow(0.1,nPrecision);
    1822                 : 
    1823             260 :     dfABSAngle = ABS(dfAngle) + dfEpsilon;
    1824             260 :     if (dfABSAngle > 361)
    1825                 :     {
    1826               0 :         return "Invalid angle";
    1827                 :     }
    1828                 : 
    1829             260 :     nDegrees = (int) dfABSAngle;
    1830             260 :     nMinutes = (int) ((dfABSAngle - nDegrees) * 60);
    1831             260 :     dfSeconds = dfABSAngle * 3600 - nDegrees*3600 - nMinutes*60;
    1832                 : 
    1833             260 :     if( dfSeconds > dfEpsilon * 3600.0 )
    1834             260 :         dfSeconds -= dfEpsilon * 3600.0;
    1835                 : 
    1836             360 :     if( EQUAL(pszAxis,"Long") && dfAngle < 0.0 )
    1837             100 :         pszHemisphere = "W";
    1838             160 :     else if( EQUAL(pszAxis,"Long") )
    1839              30 :         pszHemisphere = "E";
    1840             130 :     else if( dfAngle < 0.0 )
    1841              10 :         pszHemisphere = "S";
    1842                 :     else
    1843             120 :         pszHemisphere = "N";
    1844                 : 
    1845             260 :     sprintf( szFormat, "%%3dd%%2d\'%%%d.%df\"%s", nPrecision+3, nPrecision, pszHemisphere );
    1846             260 :     sprintf( szBuffer, szFormat, nDegrees, nMinutes, dfSeconds );
    1847                 : 
    1848             260 :     return( szBuffer );
    1849                 : }
    1850                 : 
    1851                 : /************************************************************************/
    1852                 : /*                         CPLPackedDMSToDec()                          */
    1853                 : /************************************************************************/
    1854                 : 
    1855                 : /**
    1856                 :  * Convert a packed DMS value (DDDMMMSSS.SS) into decimal degrees.
    1857                 :  * 
    1858                 :  * This function converts a packed DMS angle to seconds. The standard
    1859                 :  * packed DMS format is:
    1860                 :  *
    1861                 :  *  degrees * 1000000 + minutes * 1000 + seconds
    1862                 :  *
    1863                 :  * Example:     ang = 120025045.25 yields
    1864                 :  *              deg = 120
    1865                 :  *              min = 25
    1866                 :  *              sec = 45.25
    1867                 :  * 
    1868                 :  * The algorithm used for the conversion is as follows:
    1869                 :  *
    1870                 :  * 1.  The absolute value of the angle is used.
    1871                 :  *
    1872                 :  * 2.  The degrees are separated out:
    1873                 :  *     deg = ang/1000000                    (fractional portion truncated)
    1874                 :  *
    1875                 :  * 3.  The minutes are separated out:
    1876                 :  *     min = (ang - deg * 1000000) / 1000   (fractional portion truncated)
    1877                 :  *
    1878                 :  * 4.  The seconds are then computed:
    1879                 :  *     sec = ang - deg * 1000000 - min * 1000
    1880                 :  *
    1881                 :  * 5.  The total angle in seconds is computed:
    1882                 :  *     sec = deg * 3600.0 + min * 60.0 + sec
    1883                 :  *
    1884                 :  * 6.  The sign of sec is set to that of the input angle.
    1885                 :  *
    1886                 :  * Packed DMS values used by the USGS GCTP package and probably by other
    1887                 :  * software.
    1888                 :  *
    1889                 :  * NOTE: This code does not validate input value. If you give the wrong
    1890                 :  * value, you will get the wrong result.
    1891                 :  *
    1892                 :  * @param dfPacked Angle in packed DMS format.
    1893                 :  *
    1894                 :  * @return Angle in decimal degrees.
    1895                 :  * 
    1896                 :  */
    1897                 : 
    1898              26 : double CPLPackedDMSToDec( double dfPacked )
    1899                 : {
    1900                 :     double  dfDegrees, dfMinutes, dfSeconds, dfSign;
    1901                 : 
    1902              26 :     dfSign = ( dfPacked < 0.0 )? -1 : 1;
    1903                 :         
    1904              26 :     dfSeconds = ABS( dfPacked );
    1905              26 :     dfDegrees = floor(dfSeconds / 1000000.0);
    1906              26 :     dfSeconds = dfSeconds - dfDegrees * 1000000.0;
    1907              26 :     dfMinutes = floor(dfSeconds / 1000.0);
    1908              26 :     dfSeconds = dfSeconds - dfMinutes * 1000.0;
    1909              26 :     dfSeconds = dfSign * ( dfDegrees * 3600.0 + dfMinutes * 60.0 + dfSeconds);
    1910              26 :     dfDegrees = dfSeconds / 3600.0;
    1911                 : 
    1912              26 :     return dfDegrees;
    1913                 : }
    1914                 : 
    1915                 : /************************************************************************/
    1916                 : /*                         CPLDecToPackedDMS()                          */
    1917                 : /************************************************************************/
    1918                 : /**
    1919                 :  * Convert decimal degrees into packed DMS value (DDDMMMSSS.SS).
    1920                 :  * 
    1921                 :  * This function converts a value, specified in decimal degrees into
    1922                 :  * packed DMS angle. The standard packed DMS format is:
    1923                 :  *
    1924                 :  *  degrees * 1000000 + minutes * 1000 + seconds
    1925                 :  *
    1926                 :  * See also CPLPackedDMSToDec().
    1927                 :  *
    1928                 :  * @param dfDec Angle in decimal degrees.
    1929                 :  *
    1930                 :  * @return Angle in packed DMS format.
    1931                 :  * 
    1932                 :  */
    1933                 : 
    1934               8 : double CPLDecToPackedDMS( double dfDec )
    1935                 : {
    1936                 :     double  dfDegrees, dfMinutes, dfSeconds, dfSign;
    1937                 : 
    1938               8 :     dfSign = ( dfDec < 0.0 )? -1 : 1;
    1939                 : 
    1940               8 :     dfDec = ABS( dfDec );
    1941               8 :     dfDegrees = floor( dfDec );
    1942               8 :     dfMinutes = floor( ( dfDec - dfDegrees ) * 60.0 );
    1943               8 :     dfSeconds = ( dfDec - dfDegrees ) * 3600.0 - dfMinutes * 60.0;
    1944                 : 
    1945               8 :     return dfSign * (dfDegrees * 1000000.0 + dfMinutes * 1000.0 + dfSeconds);
    1946                 : }
    1947                 : 
    1948                 : /************************************************************************/
    1949                 : /*                         CPLStringToComplex()                         */
    1950                 : /************************************************************************/
    1951                 : 
    1952             615 : void CPL_DLL CPLStringToComplex( const char *pszString, 
    1953                 :                                  double *pdfReal, double *pdfImag )
    1954                 : 
    1955                 : {
    1956                 :     int  i;
    1957             615 :     int  iPlus = -1, iImagEnd = -1;
    1958                 : 
    1959            1230 :     while( *pszString == ' ' )
    1960               0 :         pszString++;
    1961                 : 
    1962             615 :     *pdfReal = CPLAtof(pszString);
    1963             615 :     *pdfImag = 0.0;
    1964                 : 
    1965            1236 :     for( i = 0; pszString[i] != '\0' && pszString[i] != ' ' && i < 100; i++ )
    1966                 :     {
    1967             621 :         if( pszString[i] == '+' && i > 0 )
    1968               0 :             iPlus = i;
    1969             621 :         if( pszString[i] == '-' && i > 0 )
    1970               0 :             iPlus = i;
    1971             621 :         if( pszString[i] == 'i' )
    1972               0 :             iImagEnd = i;
    1973                 :     }
    1974                 : 
    1975             615 :     if( iPlus > -1 && iImagEnd > -1 && iPlus < iImagEnd )
    1976                 :     {
    1977               0 :         *pdfImag = CPLAtof(pszString + iPlus);
    1978                 :     }
    1979                 : 
    1980                 :     return;
    1981                 : }
    1982                 : 
    1983                 : /************************************************************************/
    1984                 : /*                           CPLOpenShared()                            */
    1985                 : /************************************************************************/
    1986                 : 
    1987                 : /**
    1988                 :  * Open a shared file handle. 
    1989                 :  *
    1990                 :  * Some operating systems have limits on the number of file handles that can
    1991                 :  * be open at one time.  This function attempts to maintain a registry of
    1992                 :  * already open file handles, and reuse existing ones if the same file
    1993                 :  * is requested by another part of the application. 
    1994                 :  *
    1995                 :  * Note that access is only shared for access types "r", "rb", "r+" and 
    1996                 :  * "rb+".  All others will just result in direct VSIOpen() calls.  Keep in
    1997                 :  * mind that a file is only reused if the file name is exactly the same. 
    1998                 :  * Different names referring to the same file will result in different 
    1999                 :  * handles.  
    2000                 :  *
    2001                 :  * The VSIFOpen() or VSIFOpenL() function is used to actually open the file, 
    2002                 :  * when an existing file handle can't be shared. 
    2003                 :  *
    2004                 :  * @param pszFilename the name of the file to open.
    2005                 :  * @param pszAccess the normal fopen()/VSIFOpen() style access string.
    2006                 :  * @param bLarge If TRUE VSIFOpenL() (for large files) will be used instead of
    2007                 :  * VSIFOpen(). 
    2008                 :  *
    2009                 :  * @return a file handle or NULL if opening fails. 
    2010                 :  */
    2011                 : 
    2012              13 : FILE *CPLOpenShared( const char *pszFilename, const char *pszAccess,
    2013                 :                      int bLarge )
    2014                 : 
    2015                 : {
    2016                 :     int i;
    2017                 :     int bReuse;
    2018              13 :     CPLMutexHolderD( &hSharedFileMutex );
    2019              13 :     GIntBig nPID = CPLGetPID();
    2020                 : 
    2021                 : /* -------------------------------------------------------------------- */
    2022                 : /*      Is there an existing file we can use?                           */
    2023                 : /* -------------------------------------------------------------------- */
    2024              13 :     bReuse = EQUAL(pszAccess,"rb") || EQUAL(pszAccess, "rb+");
    2025                 : 
    2026              15 :     for( i = 0; bReuse && i < nSharedFileCount; i++ )
    2027                 :     {
    2028              22 :         if( strcmp(pasSharedFileList[i].pszFilename,pszFilename) == 0 
    2029               5 :             && !bLarge == !pasSharedFileList[i].bLarge
    2030               5 :             && EQUAL(pasSharedFileList[i].pszAccess,pszAccess)
    2031               5 :             && nPID == pasSharedFileListExtra[i].nPID)
    2032                 :         {
    2033               5 :             pasSharedFileList[i].nRefCount++;
    2034               5 :             return pasSharedFileList[i].fp;
    2035                 :         }
    2036                 :     }
    2037                 : 
    2038                 : /* -------------------------------------------------------------------- */
    2039                 : /*      Open the file.                                                  */
    2040                 : /* -------------------------------------------------------------------- */
    2041                 :     FILE *fp;
    2042                 : 
    2043               8 :     if( bLarge )
    2044               8 :         fp = (FILE*) VSIFOpenL( pszFilename, pszAccess );
    2045                 :     else
    2046               0 :         fp = VSIFOpen( pszFilename, pszAccess );
    2047                 : 
    2048               8 :     if( fp == NULL )
    2049               0 :         return NULL;
    2050                 : 
    2051                 : /* -------------------------------------------------------------------- */
    2052                 : /*      Add an entry to the list.                                       */
    2053                 : /* -------------------------------------------------------------------- */
    2054               8 :     nSharedFileCount++;
    2055                 : 
    2056                 :     pasSharedFileList = (CPLSharedFileInfo *)
    2057                 :         CPLRealloc( (void *) pasSharedFileList, 
    2058               8 :                     sizeof(CPLSharedFileInfo) * nSharedFileCount );
    2059                 :     pasSharedFileListExtra = (CPLSharedFileInfoExtra *)
    2060                 :         CPLRealloc( (void *) pasSharedFileListExtra, 
    2061               8 :                     sizeof(CPLSharedFileInfoExtra) * nSharedFileCount );
    2062                 : 
    2063               8 :     pasSharedFileList[nSharedFileCount-1].fp = fp;
    2064               8 :     pasSharedFileList[nSharedFileCount-1].nRefCount = 1;
    2065               8 :     pasSharedFileList[nSharedFileCount-1].bLarge = bLarge;
    2066               8 :     pasSharedFileList[nSharedFileCount-1].pszFilename =CPLStrdup(pszFilename);
    2067               8 :     pasSharedFileList[nSharedFileCount-1].pszAccess = CPLStrdup(pszAccess);
    2068               8 :     pasSharedFileListExtra[nSharedFileCount-1].nPID = nPID;
    2069                 : 
    2070               8 :     return fp;
    2071                 : }
    2072                 : 
    2073                 : /************************************************************************/
    2074                 : /*                           CPLCloseShared()                           */
    2075                 : /************************************************************************/
    2076                 : 
    2077                 : /**
    2078                 :  * Close shared file.
    2079                 :  *
    2080                 :  * Dereferences the indicated file handle, and closes it if the reference
    2081                 :  * count has dropped to zero.  A CPLError() is issued if the file is not
    2082                 :  * in the shared file list.
    2083                 :  *
    2084                 :  * @param fp file handle from CPLOpenShared() to deaccess.
    2085                 :  */
    2086                 : 
    2087              13 : void CPLCloseShared( FILE * fp )
    2088                 : 
    2089                 : {
    2090              13 :     CPLMutexHolderD( &hSharedFileMutex );
    2091                 :     int i;
    2092                 : 
    2093                 : /* -------------------------------------------------------------------- */
    2094                 : /*      Search for matching information.                                */
    2095                 : /* -------------------------------------------------------------------- */
    2096              13 :     for( i = 0; i < nSharedFileCount && fp != pasSharedFileList[i].fp; i++ ){}
    2097                 : 
    2098              13 :     if( i == nSharedFileCount )
    2099                 :     {
    2100                 :         CPLError( CE_Failure, CPLE_AppDefined, 
    2101                 :                   "Unable to find file handle %p in CPLCloseShared().",
    2102               0 :                   fp );
    2103                 :         return;
    2104                 :     }
    2105                 : 
    2106                 : /* -------------------------------------------------------------------- */
    2107                 : /*      Dereference and return if there are still some references.      */
    2108                 : /* -------------------------------------------------------------------- */
    2109              13 :     if( --pasSharedFileList[i].nRefCount > 0 )
    2110                 :         return;
    2111                 : 
    2112                 : /* -------------------------------------------------------------------- */
    2113                 : /*      Close the file, and remove the information.                     */
    2114                 : /* -------------------------------------------------------------------- */
    2115               8 :     if( pasSharedFileList[i].bLarge )
    2116               8 :         VSIFCloseL( (VSILFILE*) pasSharedFileList[i].fp );
    2117                 :     else
    2118               0 :         VSIFClose( pasSharedFileList[i].fp );
    2119                 : 
    2120               8 :     CPLFree( pasSharedFileList[i].pszFilename );
    2121               8 :     CPLFree( pasSharedFileList[i].pszAccess );
    2122                 : 
    2123               8 :     nSharedFileCount --;
    2124                 :     memmove( (void *) (pasSharedFileList + i), 
    2125                 :              (void *) (pasSharedFileList + nSharedFileCount), 
    2126               8 :              sizeof(CPLSharedFileInfo) );
    2127                 :     memmove( (void *) (pasSharedFileListExtra + i), 
    2128                 :              (void *) (pasSharedFileListExtra + nSharedFileCount), 
    2129               8 :              sizeof(CPLSharedFileInfoExtra) );
    2130                 : 
    2131               8 :     if( nSharedFileCount == 0 )
    2132                 :     {
    2133               7 :         CPLFree( (void *) pasSharedFileList );
    2134               7 :         pasSharedFileList = NULL;
    2135               7 :         CPLFree( (void *) pasSharedFileListExtra );
    2136               7 :         pasSharedFileListExtra = NULL;
    2137               0 :     }
    2138                 : }
    2139                 : 
    2140                 : /************************************************************************/
    2141                 : /*                          CPLGetSharedList()                          */
    2142                 : /************************************************************************/
    2143                 : 
    2144                 : /**
    2145                 :  * Fetch list of open shared files.
    2146                 :  *
    2147                 :  * @param pnCount place to put the count of entries. 
    2148                 :  *
    2149                 :  * @return the pointer to the first in the array of shared file info 
    2150                 :  * structures.
    2151                 :  */
    2152                 : 
    2153               0 : CPLSharedFileInfo *CPLGetSharedList( int *pnCount )
    2154                 : 
    2155                 : {
    2156               0 :     if( pnCount != NULL )
    2157               0 :         *pnCount = nSharedFileCount;
    2158                 :         
    2159               0 :     return (CPLSharedFileInfo *) pasSharedFileList;
    2160                 : }
    2161                 : 
    2162                 : /************************************************************************/
    2163                 : /*                         CPLDumpSharedList()                          */
    2164                 : /************************************************************************/
    2165                 : 
    2166                 : /**
    2167                 :  * Report open shared files.
    2168                 :  *
    2169                 :  * Dumps all open shared files to the indicated file handle.  If the
    2170                 :  * file handle is NULL information is sent via the CPLDebug() call. 
    2171                 :  *
    2172                 :  * @param fp File handle to write to.
    2173                 :  */
    2174                 : 
    2175              19 : void CPLDumpSharedList( FILE *fp )
    2176                 : 
    2177                 : {
    2178                 :     int i;
    2179                 : 
    2180              19 :     if( nSharedFileCount > 0 )
    2181                 :     {
    2182               0 :         if( fp == NULL )
    2183               0 :             CPLDebug( "CPL", "%d Shared files open.", nSharedFileCount );
    2184                 :         else
    2185               0 :             fprintf( fp, "%d Shared files open.", nSharedFileCount );
    2186                 :     }
    2187                 : 
    2188              19 :     for( i = 0; i < nSharedFileCount; i++ )
    2189                 :     {
    2190               0 :         if( fp == NULL )
    2191                 :             CPLDebug( "CPL", 
    2192                 :                       "%2d %d %4s %s", 
    2193               0 :                       pasSharedFileList[i].nRefCount, 
    2194               0 :                       pasSharedFileList[i].bLarge,
    2195               0 :                       pasSharedFileList[i].pszAccess,
    2196               0 :                       pasSharedFileList[i].pszFilename );
    2197                 :         else
    2198                 :             fprintf( fp, "%2d %d %4s %s", 
    2199               0 :                      pasSharedFileList[i].nRefCount, 
    2200               0 :                      pasSharedFileList[i].bLarge,
    2201               0 :                      pasSharedFileList[i].pszAccess,
    2202               0 :                      pasSharedFileList[i].pszFilename );
    2203                 :     }
    2204              19 : }
    2205                 : 
    2206                 : /************************************************************************/
    2207                 : /*                           CPLUnlinkTree()                            */
    2208                 : /************************************************************************/
    2209                 : 
    2210                 : /**
    2211                 :  * @return 0 on successful completion, -1 if function fails.
    2212                 :  */
    2213                 : 
    2214              20 : int CPLUnlinkTree( const char *pszPath )
    2215                 : 
    2216                 : {
    2217                 : /* -------------------------------------------------------------------- */
    2218                 : /*      First, ensure there isn't any such file yet.                    */
    2219                 : /* -------------------------------------------------------------------- */
    2220                 :     VSIStatBuf sStatBuf;
    2221                 : 
    2222              20 :     if( VSIStat( pszPath, &sStatBuf ) != 0 )
    2223                 :     {
    2224                 :         CPLError( CE_Failure, CPLE_AppDefined, 
    2225                 :                   "It seems no file system object called '%s' exists.",
    2226               2 :                   pszPath );
    2227                 : 
    2228               2 :         return -1;
    2229                 :     }
    2230                 : 
    2231                 : /* -------------------------------------------------------------------- */
    2232                 : /*      If it's a simple file, just delete it.                          */
    2233                 : /* -------------------------------------------------------------------- */
    2234              18 :     if( VSI_ISREG( sStatBuf.st_mode ) )
    2235                 :     {
    2236              17 :         if( VSIUnlink( pszPath ) != 0 )
    2237                 :         {
    2238                 :             CPLError( CE_Failure, CPLE_AppDefined, "Failed to unlink %s.", 
    2239               0 :                       pszPath );
    2240                 : 
    2241               0 :             return -1;
    2242                 :         }
    2243                 :         else
    2244              17 :             return 0;
    2245                 :     }
    2246                 : 
    2247                 : /* -------------------------------------------------------------------- */
    2248                 : /*      If it is a directory recurse then unlink the directory.         */
    2249                 : /* -------------------------------------------------------------------- */
    2250               1 :     else if( VSI_ISDIR( sStatBuf.st_mode ) )
    2251                 :     {
    2252               1 :         char **papszItems = CPLReadDir( pszPath );
    2253                 :         int  i;
    2254                 : 
    2255              18 :         for( i = 0; papszItems != NULL && papszItems[i] != NULL; i++ )
    2256                 :         {
    2257                 :             char *pszSubPath;
    2258                 :             int nErr;
    2259                 : 
    2260              17 :             if( EQUAL(papszItems[i],".") || EQUAL(papszItems[i],"..") )
    2261               2 :                 continue;
    2262                 : 
    2263                 :             pszSubPath = CPLStrdup(
    2264              15 :                 CPLFormFilename( pszPath, papszItems[i], NULL ) );
    2265                 : 
    2266              15 :             nErr = CPLUnlinkTree( pszSubPath );
    2267              15 :             CPLFree( pszSubPath );
    2268                 : 
    2269              15 :             if( nErr != 0 )
    2270                 :             {
    2271               0 :                 CSLDestroy( papszItems );
    2272               0 :                 return nErr;
    2273                 :             }
    2274                 :         }
    2275                 :         
    2276               1 :         CSLDestroy( papszItems );
    2277                 : 
    2278               1 :         if( VSIRmdir( pszPath ) != 0 )
    2279                 :         {
    2280                 :             CPLError( CE_Failure, CPLE_AppDefined, "Failed to unlink %s.", 
    2281               0 :                       pszPath );
    2282                 : 
    2283               0 :             return -1;
    2284                 :         }
    2285                 :         else
    2286               1 :             return 0;
    2287                 :     }
    2288                 : 
    2289                 : /* -------------------------------------------------------------------- */
    2290                 : /*      otherwise report an error.                                      */
    2291                 : /* -------------------------------------------------------------------- */
    2292                 :     else
    2293                 :     {
    2294                 :         CPLError( CE_Failure, CPLE_AppDefined, 
    2295                 :                   "Failed to unlink %s.\nUnrecognised filesystem object.",
    2296               0 :                   pszPath );
    2297               0 :         return 1000;
    2298                 :     }
    2299                 : }
    2300                 : 
    2301                 : /************************************************************************/
    2302                 : /*                            CPLCopyFile()                             */
    2303                 : /************************************************************************/
    2304                 : 
    2305              10 : int CPLCopyFile( const char *pszNewPath, const char *pszOldPath )
    2306                 : 
    2307                 : {
    2308                 :     VSILFILE *fpOld, *fpNew;
    2309                 :     GByte *pabyBuffer;
    2310                 :     size_t nBufferSize;
    2311                 :     size_t nBytesRead;
    2312              10 :     int nRet = 0;
    2313                 : 
    2314                 : /* -------------------------------------------------------------------- */
    2315                 : /*      Open old and new file.                                          */
    2316                 : /* -------------------------------------------------------------------- */
    2317              10 :     fpOld = VSIFOpenL( pszOldPath, "rb" );
    2318              10 :     if( fpOld == NULL )
    2319               0 :         return -1;
    2320                 : 
    2321              10 :     fpNew = VSIFOpenL( pszNewPath, "wb" );
    2322              10 :     if( fpNew == NULL )
    2323                 :     {
    2324               2 :         VSIFCloseL( fpOld );
    2325               2 :         return -1;
    2326                 :     }
    2327                 : 
    2328                 : /* -------------------------------------------------------------------- */
    2329                 : /*      Prepare buffer.                                                 */
    2330                 : /* -------------------------------------------------------------------- */
    2331               8 :     nBufferSize = 1024 * 1024;
    2332               8 :     pabyBuffer = (GByte *) CPLMalloc(nBufferSize);
    2333                 : 
    2334                 : /* -------------------------------------------------------------------- */
    2335                 : /*      Copy file over till we run out of stuff.                        */
    2336                 : /* -------------------------------------------------------------------- */
    2337               8 :     do { 
    2338               8 :         nBytesRead = VSIFReadL( pabyBuffer, 1, nBufferSize, fpOld );
    2339               8 :         if( long(nBytesRead) < 0 )
    2340               0 :             nRet = -1;
    2341                 : 
    2342               8 :         if( nRet == 0
    2343                 :             && VSIFWriteL( pabyBuffer, 1, nBytesRead, fpNew ) < nBytesRead )
    2344               0 :             nRet = -1;
    2345                 :     } while( nRet == 0 && nBytesRead == nBufferSize );
    2346                 : 
    2347                 : /* -------------------------------------------------------------------- */
    2348                 : /*      Cleanup                                                         */
    2349                 : /* -------------------------------------------------------------------- */
    2350               8 :     VSIFCloseL( fpNew );
    2351               8 :     VSIFCloseL( fpOld );
    2352                 : 
    2353               8 :     CPLFree( pabyBuffer );
    2354                 : 
    2355               8 :     return nRet;
    2356                 : }
    2357                 : 
    2358                 : /************************************************************************/
    2359                 : /*                            CPLMoveFile()                             */
    2360                 : /************************************************************************/
    2361                 : 
    2362               4 : int CPLMoveFile( const char *pszNewPath, const char *pszOldPath )
    2363                 : 
    2364                 : {
    2365               4 :     if( VSIRename( pszOldPath, pszNewPath ) == 0 )
    2366               4 :         return 0;
    2367                 : 
    2368               0 :     int nRet = CPLCopyFile( pszNewPath, pszOldPath );
    2369                 : 
    2370               0 :     if( nRet == 0 )
    2371               0 :         VSIUnlink( pszOldPath );
    2372                 :     
    2373               0 :     return nRet;
    2374                 : }
    2375                 : 
    2376                 : /************************************************************************/
    2377                 : /* ==================================================================== */
    2378                 : /*                              CPLLocaleC                              */
    2379                 : /* ==================================================================== */
    2380                 : /************************************************************************/
    2381                 : 
    2382                 : #include <locale.h>
    2383                 : 
    2384                 : /************************************************************************/
    2385                 : /*                             CPLLocaleC()                             */
    2386                 : /************************************************************************/
    2387                 : 
    2388           88022 : CPLLocaleC::CPLLocaleC() : pszOldLocale(CPLStrdup(setlocale(LC_NUMERIC,NULL)))
    2389                 : 
    2390                 : {
    2391           88022 :     if( CSLTestBoolean(CPLGetConfigOption("GDAL_DISABLE_CPLLOCALEC","NO"))
    2392                 :         || EQUAL(pszOldLocale,"C")
    2393                 :         || EQUAL(pszOldLocale,"POSIX")
    2394                 :         || setlocale(LC_NUMERIC,"C") == NULL )
    2395                 :     {
    2396           88022 :         CPLFree( pszOldLocale );
    2397           88022 :         pszOldLocale = NULL;
    2398                 :     }
    2399           88022 : }
    2400                 : 
    2401                 : /************************************************************************/
    2402                 : /*                            ~CPLLocaleC()                             */
    2403                 : /************************************************************************/
    2404                 : 
    2405           88022 : CPLLocaleC::~CPLLocaleC()
    2406                 : 
    2407                 : {
    2408           88022 :     if( pszOldLocale != NULL )
    2409                 :     {
    2410               0 :         setlocale( LC_NUMERIC, pszOldLocale );
    2411               0 :         CPLFree( pszOldLocale );
    2412                 :     }
    2413           88022 : }
    2414                 : 
    2415                 : /************************************************************************/
    2416                 : /*                          CPLCheckForFile()                           */
    2417                 : /************************************************************************/
    2418                 : 
    2419                 : /**
    2420                 :  * Check for file existance.
    2421                 :  *
    2422                 :  * The function checks if a named file exists in the filesystem, hopefully
    2423                 :  * in an efficient fashion if a sibling file list is available.   It exists
    2424                 :  * primarily to do faster file checking for functions like GDAL open methods
    2425                 :  * that get a list of files from the target directory. 
    2426                 :  *
    2427                 :  * If the sibling file list exists (is not NULL) it is assumed to be a list
    2428                 :  * of files in the same directory as the target file, and it will be checked
    2429                 :  * (case insensitively) for a match.  If a match is found, pszFilename is
    2430                 :  * updated with the correct case and TRUE is returned. 
    2431                 :  *
    2432                 :  * If papszSiblingFiles is NULL, a VSIStatL() is used to test for the files
    2433                 :  * existance, and no case insensitive testing is done. 
    2434                 :  *
    2435                 :  * @param pszFilename name of file to check for - filename case updated in some cases.
    2436                 :  * @param papszSiblingFiles a list of files in the same directory as 
    2437                 :  * pszFilename if available, or NULL. This list should have no path components.
    2438                 :  *
    2439                 :  * @return TRUE if a match is found, or FALSE if not.
    2440                 :  */
    2441                 : 
    2442            7430 : int CPLCheckForFile( char *pszFilename, char **papszSiblingFiles )
    2443                 : 
    2444                 : {
    2445                 : /* -------------------------------------------------------------------- */
    2446                 : /*      Fallback case if we don't have a sibling file list.             */
    2447                 : /* -------------------------------------------------------------------- */
    2448            7430 :     if( papszSiblingFiles == NULL )
    2449                 :     {
    2450                 :         VSIStatBufL sStatBuf;
    2451                 : 
    2452            3704 :         return VSIStatL( pszFilename, &sStatBuf ) == 0;
    2453                 :     }
    2454                 : 
    2455                 : /* -------------------------------------------------------------------- */
    2456                 : /*      We have sibling files, compare the non-path filename portion    */
    2457                 : /*      of pszFilename too all entries.                                 */
    2458                 : /* -------------------------------------------------------------------- */
    2459            3726 :     CPLString osFileOnly = CPLGetFilename( pszFilename );
    2460                 :     int i;
    2461                 : 
    2462          194119 :     for( i = 0; papszSiblingFiles[i] != NULL; i++ )
    2463                 :     {
    2464          190494 :         if( EQUAL(papszSiblingFiles[i],osFileOnly) )
    2465                 :         {
    2466                 :             strcpy( pszFilename + strlen(pszFilename) - strlen(osFileOnly), 
    2467             101 :                     papszSiblingFiles[i] );
    2468             101 :             return TRUE;
    2469                 :         }
    2470                 :     }
    2471                 : 
    2472            3625 :     return FALSE;
    2473                 : }
    2474                 : 
    2475                 : /************************************************************************/
    2476                 : /*      Stub implementation of zip services if we don't have libz.      */
    2477                 : /************************************************************************/
    2478                 : 
    2479                 : #if !defined(HAVE_LIBZ)
    2480                 : 
    2481                 : void *CPLCreateZip( const char *pszZipFilename, char **papszOptions )
    2482                 : 
    2483                 : {
    2484                 :     CPLError( CE_Failure, CPLE_NotSupported,
    2485                 :               "This GDAL/OGR build does not include zlib and zip services." );
    2486                 :     return NULL;
    2487                 : }
    2488                 : 
    2489                 : CPLErr CPLCreateFileInZip( void *hZip, const char *pszFilename, 
    2490                 :                            char **papszOptions )
    2491                 : 
    2492                 : {
    2493                 :     return CE_Failure;
    2494                 : }
    2495                 : 
    2496                 : CPLErr CPLWriteFileInZip( void *hZip, const void *pBuffer, int nBufferSize )
    2497                 : 
    2498                 : {
    2499                 :     return CE_Failure;
    2500                 : }
    2501                 : 
    2502                 : CPLErr CPLCloseFileInZip( void *hZip )
    2503                 : 
    2504                 : {
    2505                 :     return CE_Failure;
    2506                 : }
    2507                 : 
    2508                 : CPLErr CPLCloseZip( void *hZip )
    2509                 : 
    2510                 : {
    2511                 :     return CE_Failure;
    2512                 : }
    2513                 : 
    2514                 : #endif /* !defined(HAVE_LIBZ) */

Generated by: LCOV version 1.7