LCOV - code coverage report
Current view: directory - port - cpl_conv.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 560 411 73.4 %
Date: 2010-01-09 Functions: 45 38 84.4 %

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

Generated by: LCOV version 1.7