LTP GCOV extension - code coverage report
Current view: directory - port - cpl_conv.cpp
Test: gdal_filtered.info
Date: 2010-07-12 Instrumented lines: 542
Code covered: 73.6 % Executed lines: 399

       1                 : /******************************************************************************
       2                 :  * $Id: cpl_conv.cpp 18894 2010-02-23 19:26:15Z warmerdam $
       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 18894 2010-02-23 19:26:15Z warmerdam $");
      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         1668853 : void *CPLCalloc( size_t nCount, size_t nSize )
      73                 : 
      74                 : {
      75                 :     void        *pReturn;
      76                 : 
      77         1668853 :     if( nSize * nCount == 0 )
      78           15188 :         return NULL;
      79                 :     
      80         1653665 :     pReturn = VSICalloc( nCount, nSize );
      81         1653665 :     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         1653665 :     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         1548005 : void *CPLMalloc( size_t nSize )
     111                 : 
     112                 : {
     113                 :     void        *pReturn;
     114                 : 
     115         1548005 :     CPLVerifyConfiguration();
     116                 : 
     117         1548005 :     if( nSize == 0 )
     118            1031 :         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         1546974 :     pReturn = VSIMalloc( nSize );
     129         1546974 :     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         1546974 :     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         6596090 : void * CPLRealloc( void * pData, size_t nNewSize )
     164                 : 
     165                 : {
     166                 :     void        *pReturn;
     167                 : 
     168         6596090 :     if ( nNewSize == 0 )
     169                 :     {
     170           73397 :         VSIFree(pData);
     171           73397 :         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         6522693 :     if( pData == NULL )
     183          838853 :         pReturn = VSIMalloc( nNewSize );
     184                 :     else
     185         5683840 :         pReturn = VSIRealloc( pData, nNewSize );
     186                 :     
     187         6522693 :     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         6522693 :     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         6222982 : char *CPLStrdup( const char * pszString )
     220                 : 
     221                 : {
     222                 :     char        *pszReturn;
     223                 : 
     224         6222982 :     if( pszString == NULL )
     225          122183 :         pszString = "";
     226                 : 
     227         6222982 :     pszReturn = VSIStrdup( pszString );
     228                 :         
     229         6222982 :     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         6222982 :     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               7 : char *CPLStrlwr( char *pszString )
     255                 : 
     256                 : {
     257               7 :     if (pszString)
     258                 :     {
     259               7 :         char *pszTemp = pszString;
     260                 : 
     261              35 :         while (*pszTemp)
     262                 :         {
     263              21 :             *pszTemp = (char) tolower (*pszTemp);
     264              21 :             pszTemp++;
     265                 :         }
     266                 :     }
     267                 : 
     268               7 :     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          443538 : char *CPLFGets( char *pszBuffer, int nBufferSize, FILE * fp )
     296                 : 
     297                 : {
     298                 :     int nActuallyRead, nOriginalOffset;
     299                 : 
     300          443538 :     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          443538 :     nOriginalOffset = VSIFTell( fp );
     311          443538 :     if( VSIFGets( pszBuffer, nBufferSize, fp ) == NULL )
     312             422 :         return NULL;
     313                 :     
     314          443116 :     nActuallyRead = strlen(pszBuffer);
     315          443116 :     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          443116 :     if( nBufferSize == nActuallyRead+1
     323                 :         && 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          482384 :     if( nActuallyRead > 1 
     339                 :         && pszBuffer[nActuallyRead-1] == 10 
     340                 :         && pszBuffer[nActuallyRead-2] == 13 )
     341                 :     {
     342           39268 :         pszBuffer[nActuallyRead-2] = '\0';
     343                 :     }
     344          403848 :     else if( pszBuffer[nActuallyRead-1] == 10 
     345                 :              || pszBuffer[nActuallyRead-1] == 13 )
     346                 :     {
     347          141924 :         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          443116 :     char *pszExtraNewline = strchr( pszBuffer, 13 );
     356                 :     
     357          443116 :     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          443116 :     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          867601 : static char *CPLReadLineBuffer( int nRequiredSize )
     399                 : 
     400                 : {
     401                 :     
     402                 : /* -------------------------------------------------------------------- */
     403                 : /*      A required size of -1 means the buffer should be freed.         */
     404                 : /* -------------------------------------------------------------------- */
     405          867601 :     if( nRequiredSize == -1 )
     406                 :     {
     407             589 :         if( CPLGetTLS( CTLS_RLBUFFERINFO ) != NULL )
     408                 :         {
     409             589 :             CPLFree( CPLGetTLS( CTLS_RLBUFFERINFO ) );
     410             589 :             CPLSetTLS( CTLS_RLBUFFERINFO, NULL, FALSE );
     411                 :         }
     412             589 :         return NULL;
     413                 :     }
     414                 : 
     415                 : /* -------------------------------------------------------------------- */
     416                 : /*      If the buffer doesn't exist yet, create it.                     */
     417                 : /* -------------------------------------------------------------------- */
     418          867012 :     GUInt32 *pnAlloc = (GUInt32 *) CPLGetTLS( CTLS_RLBUFFERINFO );
     419                 : 
     420          867012 :     if( pnAlloc == NULL )
     421                 :     {
     422             651 :         pnAlloc = (GUInt32 *) CPLMalloc(200);
     423             651 :         *pnAlloc = 196;
     424             651 :         CPLSetTLS( CTLS_RLBUFFERINFO, pnAlloc, TRUE );
     425                 :     }
     426                 : 
     427                 : /* -------------------------------------------------------------------- */
     428                 : /*      If it is too small, grow it bigger.                             */
     429                 : /* -------------------------------------------------------------------- */
     430          867012 :     if( (int) *pnAlloc < nRequiredSize+1 )
     431                 :     {
     432             342 :         int nNewSize = nRequiredSize + 4 + 500;
     433                 : 
     434             342 :         GUInt32* pnAllocNew = (GUInt32 *) VSIRealloc(pnAlloc,nNewSize);
     435             342 :         if( pnAllocNew == NULL )
     436                 :         {
     437               0 :             VSIFree( pnAlloc );
     438               0 :             CPLSetTLS( CTLS_RLBUFFERINFO, NULL, FALSE );
     439               0 :             return NULL;
     440                 :         }
     441             342 :         pnAlloc = pnAllocNew;
     442                 :             
     443             342 :         *pnAlloc = nNewSize - 4;
     444             342 :         CPLSetTLS( CTLS_RLBUFFERINFO, pnAlloc, TRUE );
     445                 :     }
     446                 : 
     447          867012 :     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          181803 : const char *CPLReadLine( FILE * fp )
     477                 : 
     478                 : {
     479          181803 :     char *pszRLBuffer = CPLReadLineBuffer(1);
     480          181803 :     int         nReadSoFar = 0;
     481                 : 
     482                 : /* -------------------------------------------------------------------- */
     483                 : /*      Cleanup case.                                                   */
     484                 : /* -------------------------------------------------------------------- */
     485          181803 :     if( fp == NULL )
     486                 :     {
     487             178 :         CPLReadLineBuffer( -1 );
     488             178 :         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          443112 :     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          443532 :         pszRLBuffer = CPLReadLineBuffer( nReadSoFar + 129 );
     504          443532 :         if( pszRLBuffer == NULL )
     505               0 :             return NULL;
     506                 : 
     507                 : /* -------------------------------------------------------------------- */
     508                 : /*      Do the actual read.                                             */
     509                 : /* -------------------------------------------------------------------- */
     510          443532 :         if( CPLFGets( pszRLBuffer+nReadSoFar, 128, fp ) == NULL 
     511                 :             && nReadSoFar == 0 )
     512             420 :             return NULL;
     513                 : 
     514          443112 :         nBytesReadThisTime = strlen(pszRLBuffer+nReadSoFar);
     515          443112 :         nReadSoFar += nBytesReadThisTime;
     516                 : 
     517                 :     } while( nBytesReadThisTime >= 127
     518                 :              && pszRLBuffer[nReadSoFar-1] != 13
     519                 :              && pszRLBuffer[nReadSoFar-1] != 10 );
     520                 : 
     521          181205 :     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           29671 : const char *CPLReadLineL( FILE * fp )
     540                 : {
     541           29671 :     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          238371 : const char *CPLReadLine2L( FILE * fp, int nMaxCars, char** papszOptions )
     565                 : 
     566                 : {
     567                 : /* -------------------------------------------------------------------- */
     568                 : /*      Cleanup case.                                                   */
     569                 : /* -------------------------------------------------------------------- */
     570          238371 :     if( fp == NULL )
     571                 :     {
     572             411 :         CPLReadLineBuffer( -1 );
     573             411 :         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          237960 :     const size_t nChunkSize = 40;
     582                 :     char szChunk[nChunkSize];
     583          237960 :     size_t nChunkBytesRead = 0;
     584          237960 :     int nBufLength = 0;
     585          237960 :     size_t nChunkBytesConsumed = 0;
     586                 : 
     587            3717 :     while( TRUE )
     588                 :     {
     589                 : /* -------------------------------------------------------------------- */
     590                 : /*      Read a chunk from the input file.                               */
     591                 : /* -------------------------------------------------------------------- */
     592          241677 :         pszRLBuffer = CPLReadLineBuffer( nBufLength + nChunkSize + 1 );
     593                 : 
     594          241677 :         if( nChunkBytesRead == nChunkBytesConsumed + 1 )
     595                 :         {
     596                 : 
     597                 :             // case where one character is left over from last read.
     598            3717 :             szChunk[0] = szChunk[nChunkBytesConsumed];
     599                 : 
     600            3717 :             nChunkBytesConsumed = 0;
     601            3717 :             nChunkBytesRead = VSIFReadL( szChunk+1, 1, nChunkSize-1, fp ) + 1;
     602                 :         }
     603                 :         else
     604                 :         {
     605          237960 :             nChunkBytesConsumed = 0;
     606                 : 
     607                 :             // fresh read.
     608          237960 :             nChunkBytesRead = VSIFReadL( szChunk, 1, nChunkSize, fp );
     609          237960 :             if( nChunkBytesRead == 0 )
     610                 :             {
     611             357 :                 if( nBufLength == 0 )
     612             357 :                     return NULL;
     613                 :                 else
     614               0 :                     break;
     615                 :             }
     616                 :         }
     617                 :         
     618                 : /* -------------------------------------------------------------------- */
     619                 : /*      copy over characters watching for end-of-line.                  */
     620                 : /* -------------------------------------------------------------------- */
     621          241320 :         int bBreak = FALSE;
     622         7815611 :         while( nChunkBytesConsumed < nChunkBytesRead-1 && !bBreak )
     623                 :         {
     624         7353819 :             if( (szChunk[nChunkBytesConsumed] == 13
     625                 :                  && szChunk[nChunkBytesConsumed+1] == 10)
     626                 :                 || (szChunk[nChunkBytesConsumed] == 10
     627                 :                     && szChunk[nChunkBytesConsumed+1] == 13) )
     628                 :             {
     629           20848 :                 nChunkBytesConsumed += 2;
     630           20848 :                 bBreak = TRUE;
     631                 :             }
     632         7528104 :             else if( szChunk[nChunkBytesConsumed] == 10
     633                 :                      || szChunk[nChunkBytesConsumed] == 13 )
     634                 :             {
     635          215981 :                 nChunkBytesConsumed += 1;
     636          215981 :                 bBreak = TRUE;
     637                 :             }
     638                 :             else
     639                 :             {
     640         7096142 :                 pszRLBuffer[nBufLength++] = szChunk[nChunkBytesConsumed++];
     641         7096142 :                 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          241320 :         if( bBreak )
     651          236829 :             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            4491 :         if( nChunkBytesConsumed == nChunkBytesRead-1 
     659                 :             && nChunkBytesRead < nChunkSize )
     660                 :         {
     661             774 :             if( szChunk[nChunkBytesConsumed] == 10
     662                 :                 || szChunk[nChunkBytesConsumed] == 13 )
     663                 :             {
     664             514 :                 nChunkBytesConsumed++;
     665             514 :                 break;
     666                 :             }
     667                 : 
     668             260 :             pszRLBuffer[nBufLength++] = szChunk[nChunkBytesConsumed++];
     669             260 :             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          237603 :     if( nChunkBytesConsumed < nChunkBytesRead )
     678                 :     {
     679          235119 :         size_t nBytesToPush = nChunkBytesRead - nChunkBytesConsumed;
     680                 :         
     681          235119 :         VSIFSeekL( fp, VSIFTellL( fp ) - nBytesToPush, SEEK_SET );
     682                 :     }
     683                 : 
     684          237603 :     pszRLBuffer[nBufLength] = '\0';
     685                 : 
     686          237603 :     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                 : char *CPLScanString( const char *pszString, int nMaxLength,
     714             307 :                      int bTrimSpaces, int bNormalize )
     715                 : {
     716                 :     char    *pszBuffer;
     717                 : 
     718             307 :     if ( !pszString )
     719               0 :         return NULL;
     720                 : 
     721             307 :     if ( !nMaxLength )
     722               2 :         return CPLStrdup( "" );
     723                 : 
     724             305 :     pszBuffer = (char *)CPLMalloc( nMaxLength + 1 );
     725             305 :     if ( !pszBuffer )
     726               0 :         return NULL;
     727                 : 
     728             305 :     strncpy( pszBuffer, pszString,  nMaxLength );
     729             305 :     pszBuffer[nMaxLength] = '\0';
     730                 : 
     731             305 :     if ( bTrimSpaces )
     732                 :     {
     733             305 :         size_t  i = strlen( pszBuffer );
     734            1177 :         while ( i-- > 0 && isspace((unsigned char)pszBuffer[i]) )
     735             567 :             pszBuffer[i] = '\0';
     736                 :     }
     737                 : 
     738             305 :     if ( bNormalize )
     739                 :     {
     740             244 :         size_t  i = strlen( pszBuffer );
     741            2191 :         while ( i-- > 0 )
     742                 :         {
     743            1703 :             if ( pszBuffer[i] == ':' )
     744               0 :                 pszBuffer[i] = '_';
     745                 :         }
     746                 :     }
     747                 : 
     748             305 :     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               5 : long CPLScanLong( const char *pszString, int nMaxLength )
     770                 : {
     771                 :     long    iValue;
     772               5 :     char    *pszValue = (char *)CPLMalloc( nMaxLength + 1);
     773                 : 
     774                 : /* -------------------------------------------------------------------- */
     775                 : /*      Compute string into local buffer, and terminate it.             */
     776                 : /* -------------------------------------------------------------------- */
     777               5 :     strncpy( pszValue, pszString, nMaxLength );
     778               5 :     pszValue[nMaxLength] = '\0';
     779                 : 
     780                 : /* -------------------------------------------------------------------- */
     781                 : /*      Use atol() to fetch out the result                              */
     782                 : /* -------------------------------------------------------------------- */
     783               5 :     iValue = atol( pszValue );
     784                 : 
     785               5 :     CPLFree( pszValue );
     786               5 :     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            7324 : GUIntBig CPLScanUIntBig( const char *pszString, int nMaxLength )
     849                 : {
     850                 :     GUIntBig    iValue;
     851            7324 :     char        *pszValue = (char *)CPLMalloc( nMaxLength + 1);
     852                 : 
     853                 : /* -------------------------------------------------------------------- */
     854                 : /*      Compute string into local buffer, and terminate it.             */
     855                 : /* -------------------------------------------------------------------- */
     856            7324 :     strncpy( pszValue, pszString, nMaxLength );
     857            7324 :     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            7324 :     iValue = atoll( pszValue );
     866                 : #else
     867                 :     iValue = atol( pszValue );
     868                 : #endif
     869                 : 
     870            7324 :     CPLFree( pszValue );
     871            7324 :     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              54 : 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              54 :     if( nMaxLength > (int) sizeof(szTemp)-1 )
     903               0 :         nMaxLength = sizeof(szTemp)-1;
     904                 : 
     905              54 :     strncpy( szTemp, pszString, nMaxLength );
     906              54 :     szTemp[nMaxLength] = '\0';
     907                 : 
     908                 : /* -------------------------------------------------------------------- */
     909                 : /*      On MSVC we have to scanf pointer values without the 0x          */
     910                 : /*      prefix.                                                         */
     911                 : /* -------------------------------------------------------------------- */
     912              54 :     if( EQUALN(szTemp,"0x",2) )
     913                 :     {
     914              54 :         pResult = NULL;
     915                 : 
     916                 : #if defined(__MSVCRT__) || (defined(WIN32) && defined(_MSC_VER))
     917                 :         sscanf( szTemp+2, "%p", &pResult );
     918                 : #else
     919              54 :         sscanf( szTemp, "%p", &pResult );
     920                 : #endif
     921                 :     }
     922                 :     
     923                 :     else
     924                 :     {
     925                 : #if SIZEOF_VOIDP == 8
     926               0 :         pResult = (void *) CPLScanUIntBig( szTemp, nMaxLength );
     927                 : #else
     928                 :         pResult = (void *) CPLScanULong( szTemp, nMaxLength );
     929                 : #endif
     930                 :     }
     931                 : 
     932              54 :     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             130 : int CPLPrintString( char *pszDest, const char *pszSrc, int nMaxLen )
    1004                 : {
    1005             130 :     char    *pszTemp = pszDest;
    1006             130 :     int     nChars = 0;
    1007                 : 
    1008             130 :     if ( !pszDest )
    1009               0 :         return 0;
    1010                 : 
    1011             130 :     if ( !pszSrc )
    1012                 :     {
    1013               0 :         *pszDest = '\0';
    1014               0 :         return 1;
    1015                 :     }
    1016                 : 
    1017            4482 :     while ( nChars < nMaxLen && *pszSrc )
    1018                 :     {
    1019            4222 :         *pszTemp++ = *pszSrc++;
    1020            4222 :         nChars++;
    1021                 :     }
    1022                 : 
    1023             130 :     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              86 : int CPLPrintStringFill( char *pszDest, const char *pszSrc, int nMaxLen )
    1048                 : {
    1049              86 :     char    *pszTemp = pszDest;
    1050                 : 
    1051              86 :     if ( !pszDest )
    1052               0 :         return 0;
    1053                 : 
    1054              86 :     if ( !pszSrc )
    1055                 :     {
    1056               0 :         memset( pszDest, ' ', nMaxLen );
    1057               0 :         return nMaxLen;
    1058                 :     }
    1059                 : 
    1060             678 :     while ( nMaxLen && *pszSrc )
    1061                 :     {
    1062             506 :         *pszTemp++ = *pszSrc++;
    1063             506 :         nMaxLen--;
    1064                 :     }
    1065                 : 
    1066              86 :     if ( nMaxLen )
    1067              43 :         memset( pszTemp, ' ', nMaxLen );
    1068                 : 
    1069              86 :     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              51 : int CPLPrintUIntBig( char *pszBuffer, GUIntBig iValue, int nMaxLen )
    1132                 : {
    1133                 :     char    szTemp[64];
    1134                 : 
    1135              51 :     if ( !pszBuffer )
    1136               0 :         return 0;
    1137                 : 
    1138              51 :     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              51 :     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              51 :     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              54 : int CPLPrintPointer( char *pszBuffer, void *pValue, int nMaxLen )
    1174                 : {
    1175                 :     char    szTemp[64];
    1176                 : 
    1177              54 :     if ( !pszBuffer )
    1178               0 :         return 0;
    1179                 : 
    1180              54 :     if ( nMaxLen >= 64 )
    1181              54 :         nMaxLen = 63;
    1182                 : 
    1183              54 :     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              54 :     if( !EQUALN(szTemp,"0x",2) )
    1190               0 :         sprintf( szTemp, "0x%p", pValue );
    1191                 : 
    1192              54 :     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                 : int CPLPrintDouble( char *pszBuffer, const char *pszFormat,
    1223               0 :                     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                 : int CPLPrintTime( char *pszBuffer, int nMaxLen, const char *pszFormat,
    1313               0 :                   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         1548005 : 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         1548005 :     nTest = 1;
    1375                 : 
    1376                 : #ifdef CPL_LSB
    1377         1548005 :     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         1548005 : }
    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(), http://trac.osgeo.org/gdal/wiki/ConfigOptions
    1402                 :   */
    1403                 : const char * CPL_STDCALL
    1404          780724 : CPLGetConfigOption( const char *pszKey, const char *pszDefault )
    1405                 : 
    1406                 : {
    1407          780724 :     const char *pszResult = NULL;
    1408                 : 
    1409          780724 :     char **papszTLConfigOptions = (char **) CPLGetTLS( CTLS_CONFIGOPTIONS );
    1410          780724 :     if( papszTLConfigOptions != NULL )
    1411               0 :         pszResult = CSLFetchNameValue( papszTLConfigOptions, pszKey );
    1412                 : 
    1413          780724 :     if( pszResult == NULL )
    1414                 :     {
    1415          780724 :         CPLMutexHolderD( &hConfigMutex );
    1416                 : 
    1417          780724 :         pszResult = CSLFetchNameValue( (char **) papszConfigOptions, pszKey );
    1418                 :     }
    1419                 : 
    1420                 : #if !defined(WIN32CE) 
    1421          780724 :     if( pszResult == NULL )
    1422          531459 :         pszResult = getenv( pszKey );
    1423                 : #endif
    1424                 :     
    1425          780724 :     if( pszResult == NULL )
    1426          530192 :         return pszDefault;
    1427                 :     else
    1428          250532 :         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                 :   * @see http://trac.osgeo.org/gdal/wiki/ConfigOptions
    1456                 :   */
    1457                 : void CPL_STDCALL 
    1458             264 : CPLSetConfigOption( const char *pszKey, const char *pszValue )
    1459                 : 
    1460                 : {
    1461             264 :     CPLMutexHolderD( &hConfigMutex );
    1462                 : 
    1463                 :     papszConfigOptions = (volatile char **) 
    1464             264 :         CSLSetNameValue( (char **) papszConfigOptions, pszKey, pszValue );
    1465             264 : }
    1466                 : 
    1467                 : /************************************************************************/
    1468                 : /*                   CPLSetThreadLocalConfigOption()                    */
    1469                 : /************************************************************************/
    1470                 : 
    1471                 : /**
    1472                 :   * Set a configuration option for GDAL/OGR use.
    1473                 :   *
    1474                 :   * Those options are defined as a (key, value) couple. The value corresponding
    1475                 :   * to a key can be got later with the CPLGetConfigOption() method.  
    1476                 :   *
    1477                 :   * This function sets the configuration option that only applies in the
    1478                 :   * current thread, as opposed to CPLSetConfigOption() which sets an option
    1479                 :   * that applies on all threads.
    1480                 :   *
    1481                 :   * @param pszKey the key of the option
    1482                 :   * @param pszValue the value of the option
    1483                 :   */
    1484                 : 
    1485                 : void CPL_STDCALL 
    1486               0 : CPLSetThreadLocalConfigOption( const char *pszKey, const char *pszValue )
    1487                 : 
    1488                 : {
    1489               0 :     char **papszTLConfigOptions = (char **) CPLGetTLS( CTLS_CONFIGOPTIONS );
    1490                 : 
    1491                 :     papszTLConfigOptions = 
    1492               0 :         CSLSetNameValue( papszTLConfigOptions, pszKey, pszValue );
    1493                 : 
    1494               0 :     CPLSetTLS( CTLS_CONFIGOPTIONS, papszTLConfigOptions, FALSE );
    1495               0 : }
    1496                 : 
    1497                 : /************************************************************************/
    1498                 : /*                           CPLFreeConfig()                            */
    1499                 : /************************************************************************/
    1500                 : 
    1501             719 : void CPL_STDCALL CPLFreeConfig()
    1502                 : 
    1503                 : {
    1504             719 :     CPLMutexHolderD( &hConfigMutex );
    1505                 : 
    1506             719 :     CSLDestroy( (char **) papszConfigOptions);
    1507             719 :     papszConfigOptions = NULL;
    1508                 : 
    1509             719 :     char **papszTLConfigOptions = (char **) CPLGetTLS( CTLS_CONFIGOPTIONS );
    1510             719 :     if( papszTLConfigOptions != NULL )
    1511                 :     {
    1512               0 :         CSLDestroy( papszTLConfigOptions );
    1513               0 :         CPLSetTLS( CTLS_CONFIGOPTIONS, NULL, FALSE );
    1514             719 :     }
    1515             719 : }
    1516                 : 
    1517                 : /************************************************************************/
    1518                 : /*                              CPLStat()                               */
    1519                 : /*                                                                      */
    1520                 : /*      Same as VSIStat() except it works on "C:" as if it were         */
    1521                 : /*      "C:\".                                                          */
    1522                 : /************************************************************************/
    1523                 : 
    1524             767 : int CPLStat( const char *pszPath, VSIStatBuf *psStatBuf )
    1525                 : 
    1526                 : {
    1527             767 :     if( strlen(pszPath) == 2 && pszPath[1] == ':' )
    1528                 :     {
    1529                 :         char    szAltPath[4];
    1530                 :         
    1531               0 :         szAltPath[0] = pszPath[0];
    1532               0 :         szAltPath[1] = pszPath[1];
    1533               0 :         szAltPath[2] = '\\';
    1534               0 :         szAltPath[3] = '\0';
    1535               0 :         return VSIStat( szAltPath, psStatBuf );
    1536                 :     }
    1537                 :     else
    1538             767 :         return VSIStat( pszPath, psStatBuf );
    1539                 : }
    1540                 : 
    1541                 : /************************************************************************/
    1542                 : /*                            proj_strtod()                             */
    1543                 : /************************************************************************/
    1544                 : static double
    1545             242 : proj_strtod(char *nptr, char **endptr) 
    1546                 : 
    1547                 : {
    1548             242 :     char c, *cp = nptr;
    1549                 :     double result;
    1550                 : 
    1551                 :     /*
    1552                 :      * Scan for characters which cause problems with VC++ strtod()
    1553                 :      */
    1554            1651 :     while ((c = *cp) != '\0') {
    1555            1205 :         if (c == 'd' || c == 'D') {
    1556                 : 
    1557                 :             /*
    1558                 :              * Found one, so NUL it out, call strtod(),
    1559                 :              * then restore it and return
    1560                 :              */
    1561              38 :             *cp = '\0';
    1562              38 :             result = strtod(nptr, endptr);
    1563              38 :             *cp = c;
    1564              38 :             return result;
    1565                 :         }
    1566            1167 :         ++cp;
    1567                 :     }
    1568                 : 
    1569                 :     /* no offending characters, just handle normally */
    1570                 : 
    1571             204 :     return strtod(nptr, endptr);
    1572                 : }
    1573                 : 
    1574                 : /************************************************************************/
    1575                 : /*                            CPLDMSToDec()                             */
    1576                 : /************************************************************************/
    1577                 : 
    1578                 : static const char*sym = "NnEeSsWw";
    1579                 : static const double vm[] = { 1.0, 0.0166666666667, 0.00027777778 };
    1580                 : 
    1581             184 : double CPLDMSToDec( const char *is )
    1582                 : 
    1583                 : {
    1584                 :     int sign, n, nl;
    1585                 :     char *p, *s, work[64];
    1586                 :     double v, tv;
    1587                 : 
    1588                 :     /* copy sting into work space */
    1589             184 :     while (isspace((unsigned char)(sign = *is))) ++is;
    1590            1409 :     for (n = sizeof(work), s = work, p = (char *)is; isgraph(*p) && --n ; )
    1591            1041 :         *s++ = *p++;
    1592             184 :     *s = '\0';
    1593                 :     /* it is possible that a really odd input (like lots of leading
    1594                 :        zeros) could be truncated in copying into work.  But ... */
    1595             184 :     sign = *(s = work);
    1596             184 :     if (sign == '+' || sign == '-') s++;
    1597             173 :     else sign = '+';
    1598             426 :     for (v = 0., nl = 0 ; nl < 3 ; nl = n + 1 ) {
    1599             254 :         if (!(isdigit(*s) || *s == '.')) break;
    1600             242 :         if ((tv = proj_strtod(s, &s)) == HUGE_VAL)
    1601               0 :             return tv;
    1602             242 :         switch (*s) {
    1603                 :           case 'D': case 'd':
    1604              38 :             n = 0; break;
    1605                 :           case '\'':
    1606              32 :             n = 1; break;
    1607                 :           case '"':
    1608              27 :             n = 2; break;
    1609                 :           case 'r': case 'R':
    1610               0 :             if (nl) {
    1611               0 :                 return 0.0;
    1612                 :             }
    1613               0 :             ++s;
    1614               0 :             v = tv;
    1615               0 :             goto skip;
    1616                 :           default:
    1617             145 :             v += tv * vm[nl];
    1618             145 :           skip: n = 4;
    1619             145 :             continue;
    1620                 :         }
    1621              97 :         if (n < nl) {
    1622               0 :             return 0.0;
    1623                 :         }
    1624              97 :         v += tv * vm[n];
    1625              97 :         ++s;
    1626                 :     }
    1627                 :     /* postfix sign */
    1628             184 :     if (*s && (p = (char *) strchr(sym, *s))) {
    1629              40 :         sign = (p - sym) >= 4 ? '-' : '+';
    1630              40 :         ++s;
    1631                 :     }
    1632             184 :     if (sign == '-')
    1633              23 :         v = -v;
    1634                 : 
    1635             184 :     return v;
    1636                 : }
    1637                 : 
    1638                 : 
    1639                 : /************************************************************************/
    1640                 : /*                            CPLDecToDMS()                             */
    1641                 : /*                                                                      */
    1642                 : /*      Translate a decimal degrees value to a DMS string with          */
    1643                 : /*      hemisphere.                                                     */
    1644                 : /************************************************************************/
    1645                 : 
    1646                 : const char *CPLDecToDMS( double dfAngle, const char * pszAxis,
    1647             260 :                          int nPrecision )
    1648                 : 
    1649                 : {
    1650             260 :     VALIDATE_POINTER1( pszAxis, "CPLDecToDMS", "" );
    1651                 : 
    1652                 :     int         nDegrees, nMinutes;
    1653                 :     double      dfSeconds, dfABSAngle, dfEpsilon;
    1654                 :     char        szFormat[30];
    1655                 :     const char  *pszHemisphere;
    1656                 :     static CPL_THREADLOCAL char szBuffer[50] = { 0 };
    1657                 :     
    1658                 :     
    1659             260 :     dfEpsilon = (0.5/3600.0) * pow(0.1,nPrecision);
    1660                 : 
    1661             260 :     dfABSAngle = ABS(dfAngle) + dfEpsilon;
    1662             260 :     if (dfABSAngle > 361)
    1663                 :     {
    1664               0 :         return "Invalid angle";
    1665                 :     }
    1666                 : 
    1667             260 :     nDegrees = (int) dfABSAngle;
    1668             260 :     nMinutes = (int) ((dfABSAngle - nDegrees) * 60);
    1669             260 :     dfSeconds = dfABSAngle * 3600 - nDegrees*3600 - nMinutes*60;
    1670                 : 
    1671             260 :     if( dfSeconds > dfEpsilon * 3600.0 )
    1672             260 :         dfSeconds -= dfEpsilon * 3600.0;
    1673                 : 
    1674             360 :     if( EQUAL(pszAxis,"Long") && dfAngle < 0.0 )
    1675             100 :         pszHemisphere = "W";
    1676             160 :     else if( EQUAL(pszAxis,"Long") )
    1677              30 :         pszHemisphere = "E";
    1678             130 :     else if( dfAngle < 0.0 )
    1679              10 :         pszHemisphere = "S";
    1680                 :     else
    1681             120 :         pszHemisphere = "N";
    1682                 : 
    1683             260 :     sprintf( szFormat, "%%3dd%%2d\'%%.%df\"%s", nPrecision, pszHemisphere );
    1684             260 :     sprintf( szBuffer, szFormat, nDegrees, nMinutes, dfSeconds );
    1685                 : 
    1686             260 :     return( szBuffer );
    1687                 : }
    1688                 : 
    1689                 : /************************************************************************/
    1690                 : /*                         CPLPackedDMSToDec()                          */
    1691                 : /************************************************************************/
    1692                 : 
    1693                 : /**
    1694                 :  * Convert a packed DMS value (DDDMMMSSS.SS) into decimal degrees.
    1695                 :  * 
    1696                 :  * This function converts a packed DMS angle to seconds. The standard
    1697                 :  * packed DMS format is:
    1698                 :  *
    1699                 :  *  degrees * 1000000 + minutes * 1000 + seconds
    1700                 :  *
    1701                 :  * Example:     ang = 120025045.25 yields
    1702                 :  *              deg = 120
    1703                 :  *              min = 25
    1704                 :  *              sec = 45.25
    1705                 :  * 
    1706                 :  * The algorithm used for the conversion is as follows:
    1707                 :  *
    1708                 :  * 1.  The absolute value of the angle is used.
    1709                 :  *
    1710                 :  * 2.  The degrees are separated out:
    1711                 :  *     deg = ang/1000000                    (fractional portion truncated)
    1712                 :  *
    1713                 :  * 3.  The minutes are separated out:
    1714                 :  *     min = (ang - deg * 1000000) / 1000   (fractional portion truncated)
    1715                 :  *
    1716                 :  * 4.  The seconds are then computed:
    1717                 :  *     sec = ang - deg * 1000000 - min * 1000
    1718                 :  *
    1719                 :  * 5.  The total angle in seconds is computed:
    1720                 :  *     sec = deg * 3600.0 + min * 60.0 + sec
    1721                 :  *
    1722                 :  * 6.  The sign of sec is set to that of the input angle.
    1723                 :  *
    1724                 :  * Packed DMS values used by the USGS GCTP package and probably by other
    1725                 :  * software.
    1726                 :  *
    1727                 :  * NOTE: This code does not validate input value. If you give the wrong
    1728                 :  * value, you will get the wrong result.
    1729                 :  *
    1730                 :  * @param dfPacked Angle in packed DMS format.
    1731                 :  *
    1732                 :  * @return Angle in decimal degrees.
    1733                 :  * 
    1734                 :  */
    1735                 : 
    1736              32 : double CPLPackedDMSToDec( double dfPacked )
    1737                 : {
    1738                 :     double  dfDegrees, dfMinutes, dfSeconds, dfSign;
    1739                 : 
    1740              32 :     dfSign = ( dfPacked < 0.0 )? -1 : 1;
    1741                 :         
    1742              32 :     dfSeconds = ABS( dfPacked );
    1743              32 :     dfDegrees = floor(dfSeconds / 1000000.0);
    1744              32 :     dfSeconds = dfSeconds - dfDegrees * 1000000.0;
    1745              32 :     dfMinutes = floor(dfSeconds / 1000.0);
    1746              32 :     dfSeconds = dfSeconds - dfMinutes * 1000.0;
    1747              32 :     dfSeconds = dfSign * ( dfDegrees * 3600.0 + dfMinutes * 60.0 + dfSeconds);
    1748              32 :     dfDegrees = dfSeconds / 3600.0;
    1749                 : 
    1750              32 :     return dfDegrees;
    1751                 : }
    1752                 : 
    1753                 : /************************************************************************/
    1754                 : /*                         CPLDecToPackedDMS()                          */
    1755                 : /************************************************************************/
    1756                 : /**
    1757                 :  * Convert decimal degrees into packed DMS value (DDDMMMSSS.SS).
    1758                 :  * 
    1759                 :  * This function converts a value, specified in decimal degrees into
    1760                 :  * packed DMS angle. The standard packed DMS format is:
    1761                 :  *
    1762                 :  *  degrees * 1000000 + minutes * 1000 + seconds
    1763                 :  *
    1764                 :  * See also CPLPackedDMSToDec().
    1765                 :  *
    1766                 :  * @param dfDec Angle in decimal degrees.
    1767                 :  *
    1768                 :  * @return Angle in packed DMS format.
    1769                 :  * 
    1770                 :  */
    1771                 : 
    1772               8 : double CPLDecToPackedDMS( double dfDec )
    1773                 : {
    1774                 :     double  dfDegrees, dfMinutes, dfSeconds, dfSign;
    1775                 : 
    1776               8 :     dfSign = ( dfDec < 0.0 )? -1 : 1;
    1777                 : 
    1778               8 :     dfDec = ABS( dfDec );
    1779               8 :     dfDegrees = floor( dfDec );
    1780               8 :     dfMinutes = floor( ( dfDec - dfDegrees ) * 60.0 );
    1781               8 :     dfSeconds = ( dfDec - dfDegrees ) * 3600.0 - dfMinutes * 60.0;
    1782                 : 
    1783               8 :     return dfSign * (dfDegrees * 1000000.0 + dfMinutes * 1000.0 + dfSeconds);
    1784                 : }
    1785                 : 
    1786                 : /************************************************************************/
    1787                 : /*                         CPLStringToComplex()                         */
    1788                 : /************************************************************************/
    1789                 : 
    1790                 : void CPL_DLL CPLStringToComplex( const char *pszString, 
    1791             515 :                                  double *pdfReal, double *pdfImag )
    1792                 : 
    1793                 : {
    1794                 :     int  i;
    1795             515 :     int  iPlus = -1, iImagEnd = -1;
    1796                 : 
    1797            1030 :     while( *pszString == ' ' )
    1798               0 :         pszString++;
    1799                 : 
    1800             515 :     *pdfReal = atof(pszString);
    1801             515 :     *pdfImag = 0.0;
    1802                 : 
    1803            1036 :     for( i = 0; pszString[i] != '\0' && pszString[i] != ' ' && i < 100; i++ )
    1804                 :     {
    1805             521 :         if( pszString[i] == '+' && i > 0 )
    1806               0 :             iPlus = i;
    1807             521 :         if( pszString[i] == '-' && i > 0 )
    1808               0 :             iPlus = i;
    1809             521 :         if( pszString[i] == 'i' )
    1810               0 :             iImagEnd = i;
    1811                 :     }
    1812                 : 
    1813             515 :     if( iPlus > -1 && iImagEnd > -1 && iPlus < iImagEnd )
    1814                 :     {
    1815               0 :         *pdfImag = atof(pszString + iPlus);
    1816                 :     }
    1817                 : 
    1818                 :     return;
    1819                 : }
    1820                 : 
    1821                 : /************************************************************************/
    1822                 : /*                           CPLOpenShared()                            */
    1823                 : /************************************************************************/
    1824                 : 
    1825                 : /**
    1826                 :  * Open a shared file handle. 
    1827                 :  *
    1828                 :  * Some operating systems have limits on the number of file handles that can
    1829                 :  * be open at one time.  This function attempts to maintain a registry of
    1830                 :  * already open file handles, and reuse existing ones if the same file
    1831                 :  * is requested by another part of the application. 
    1832                 :  *
    1833                 :  * Note that access is only shared for access types "r", "rb", "r+" and 
    1834                 :  * "rb+".  All others will just result in direct VSIOpen() calls.  Keep in
    1835                 :  * mind that a file is only reused if the file name is exactly the same. 
    1836                 :  * Different names referring to the same file will result in different 
    1837                 :  * handles.  
    1838                 :  *
    1839                 :  * The VSIFOpen() or VSIFOpenL() function is used to actually open the file, 
    1840                 :  * when an existing file handle can't be shared. 
    1841                 :  *
    1842                 :  * @param pszFilename the name of the file to open.
    1843                 :  * @param pszAccess the normal fopen()/VSIFOpen() style access string.
    1844                 :  * @param bLarge If TRUE VSIFOpenL() (for large files) will be used instead of
    1845                 :  * VSIFOpen(). 
    1846                 :  *
    1847                 :  * @return a file handle or NULL if opening fails. 
    1848                 :  */
    1849                 : 
    1850                 : FILE *CPLOpenShared( const char *pszFilename, const char *pszAccess,
    1851               9 :                      int bLarge )
    1852                 : 
    1853                 : {
    1854                 :     int i;
    1855                 :     int bReuse;
    1856               9 :     CPLMutexHolderD( &hSharedFileMutex );
    1857                 : 
    1858                 : /* -------------------------------------------------------------------- */
    1859                 : /*      Is there an existing file we can use?                           */
    1860                 : /* -------------------------------------------------------------------- */
    1861               9 :     bReuse = EQUAL(pszAccess,"rb") || EQUAL(pszAccess, "rb+");
    1862                 : 
    1863              11 :     for( i = 0; bReuse && i < nSharedFileCount; i++ )
    1864                 :     {
    1865               5 :         if( strcmp(pasSharedFileList[i].pszFilename,pszFilename) == 0 
    1866                 :             && !bLarge == !pasSharedFileList[i].bLarge
    1867                 :             && EQUAL(pasSharedFileList[i].pszAccess,pszAccess) )
    1868                 :         {
    1869               3 :             pasSharedFileList[i].nRefCount++;
    1870               3 :             return pasSharedFileList[i].fp;
    1871                 :         }
    1872                 :     }
    1873                 : 
    1874                 : /* -------------------------------------------------------------------- */
    1875                 : /*      Open the file.                                                  */
    1876                 : /* -------------------------------------------------------------------- */
    1877                 :     FILE *fp;
    1878                 : 
    1879               6 :     if( bLarge )
    1880               6 :         fp = VSIFOpenL( pszFilename, pszAccess );
    1881                 :     else
    1882               0 :         fp = VSIFOpen( pszFilename, pszAccess );
    1883                 : 
    1884               6 :     if( fp == NULL )
    1885               0 :         return NULL;
    1886                 : 
    1887                 : /* -------------------------------------------------------------------- */
    1888                 : /*      Add an entry to the list.                                       */
    1889                 : /* -------------------------------------------------------------------- */
    1890               6 :     nSharedFileCount++;
    1891                 : 
    1892                 :     pasSharedFileList = (CPLSharedFileInfo *)
    1893                 :         CPLRealloc( (void *) pasSharedFileList, 
    1894               6 :                     sizeof(CPLSharedFileInfo) * nSharedFileCount );
    1895                 : 
    1896               6 :     pasSharedFileList[nSharedFileCount-1].fp = fp;
    1897               6 :     pasSharedFileList[nSharedFileCount-1].nRefCount = 1;
    1898               6 :     pasSharedFileList[nSharedFileCount-1].bLarge = bLarge;
    1899               6 :     pasSharedFileList[nSharedFileCount-1].pszFilename =CPLStrdup(pszFilename);
    1900               6 :     pasSharedFileList[nSharedFileCount-1].pszAccess = CPLStrdup(pszAccess);
    1901                 : 
    1902               6 :     return fp;
    1903                 : }
    1904                 : 
    1905                 : /************************************************************************/
    1906                 : /*                           CPLCloseShared()                           */
    1907                 : /************************************************************************/
    1908                 : 
    1909                 : /**
    1910                 :  * Close shared file.
    1911                 :  *
    1912                 :  * Dereferences the indicated file handle, and closes it if the reference
    1913                 :  * count has dropped to zero.  A CPLError() is issued if the file is not
    1914                 :  * in the shared file list.
    1915                 :  *
    1916                 :  * @param fp file handle from CPLOpenShared() to deaccess.
    1917                 :  */
    1918                 : 
    1919               9 : void CPLCloseShared( FILE * fp )
    1920                 : 
    1921                 : {
    1922               9 :     CPLMutexHolderD( &hSharedFileMutex );
    1923                 :     int i;
    1924                 : 
    1925                 : /* -------------------------------------------------------------------- */
    1926                 : /*      Search for matching information.                                */
    1927                 : /* -------------------------------------------------------------------- */
    1928               9 :     for( i = 0; i < nSharedFileCount && fp != pasSharedFileList[i].fp; i++ ){}
    1929                 : 
    1930               9 :     if( i == nSharedFileCount )
    1931                 :     {
    1932                 :         CPLError( CE_Failure, CPLE_AppDefined, 
    1933                 :                   "Unable to find file handle %p in CPLCloseShared().",
    1934               0 :                   fp );
    1935               3 :         return;
    1936                 :     }
    1937                 : 
    1938                 : /* -------------------------------------------------------------------- */
    1939                 : /*      Dereference and return if there are still some references.      */
    1940                 : /* -------------------------------------------------------------------- */
    1941               9 :     if( --pasSharedFileList[i].nRefCount > 0 )
    1942                 :         return;
    1943                 : 
    1944                 : /* -------------------------------------------------------------------- */
    1945                 : /*      Close the file, and remove the information.                     */
    1946                 : /* -------------------------------------------------------------------- */
    1947               6 :     if( pasSharedFileList[i].bLarge )
    1948               6 :         VSIFCloseL( pasSharedFileList[i].fp );
    1949                 :     else
    1950               0 :         VSIFClose( pasSharedFileList[i].fp );
    1951                 : 
    1952               6 :     CPLFree( pasSharedFileList[i].pszFilename );
    1953               6 :     CPLFree( pasSharedFileList[i].pszAccess );
    1954                 : 
    1955                 : //    pasSharedFileList[i] = pasSharedFileList[--nSharedFileCount];
    1956                 :     memcpy( (void *) (pasSharedFileList + i), 
    1957                 :             (void *) (pasSharedFileList + --nSharedFileCount), 
    1958               6 :             sizeof(CPLSharedFileInfo) );
    1959                 : 
    1960               6 :     if( nSharedFileCount == 0 )
    1961                 :     {
    1962               5 :         CPLFree( (void *) pasSharedFileList );
    1963               5 :         pasSharedFileList = NULL;
    1964               0 :     }
    1965                 : }
    1966                 : 
    1967                 : /************************************************************************/
    1968                 : /*                          CPLGetSharedList()                          */
    1969                 : /************************************************************************/
    1970                 : 
    1971                 : /**
    1972                 :  * Fetch list of open shared files.
    1973                 :  *
    1974                 :  * @param pnCount place to put the count of entries. 
    1975                 :  *
    1976                 :  * @return the pointer to the first in the array of shared file info 
    1977                 :  * structures.
    1978                 :  */
    1979                 : 
    1980               0 : CPLSharedFileInfo *CPLGetSharedList( int *pnCount )
    1981                 : 
    1982                 : {
    1983               0 :     if( pnCount != NULL )
    1984               0 :         *pnCount = nSharedFileCount;
    1985                 :         
    1986               0 :     return (CPLSharedFileInfo *) pasSharedFileList;
    1987                 : }
    1988                 : 
    1989                 : /************************************************************************/
    1990                 : /*                         CPLDumpSharedList()                          */
    1991                 : /************************************************************************/
    1992                 : 
    1993                 : /**
    1994                 :  * Report open shared files.
    1995                 :  *
    1996                 :  * Dumps all open shared files to the indicated file handle.  If the
    1997                 :  * file handle is NULL information is sent via the CPLDebug() call. 
    1998                 :  *
    1999                 :  * @param fp File handle to write to.
    2000                 :  */
    2001                 : 
    2002              17 : void CPLDumpSharedList( FILE *fp )
    2003                 : 
    2004                 : {
    2005                 :     int i;
    2006                 : 
    2007              17 :     if( nSharedFileCount > 0 )
    2008                 :     {
    2009               0 :         if( fp == NULL )
    2010               0 :             CPLDebug( "CPL", "%d Shared files open.", nSharedFileCount );
    2011                 :         else
    2012               0 :             fprintf( fp, "%d Shared files open.", nSharedFileCount );
    2013                 :     }
    2014                 : 
    2015              17 :     for( i = 0; i < nSharedFileCount; i++ )
    2016                 :     {
    2017               0 :         if( fp == NULL )
    2018                 :             CPLDebug( "CPL", 
    2019                 :                       "%2d %d %4s %s", 
    2020                 :                       pasSharedFileList[i].nRefCount, 
    2021                 :                       pasSharedFileList[i].bLarge,
    2022                 :                       pasSharedFileList[i].pszAccess,
    2023               0 :                       pasSharedFileList[i].pszFilename );
    2024                 :         else
    2025                 :             fprintf( fp, "%2d %d %4s %s", 
    2026                 :                      pasSharedFileList[i].nRefCount, 
    2027                 :                      pasSharedFileList[i].bLarge,
    2028                 :                      pasSharedFileList[i].pszAccess,
    2029               0 :                      pasSharedFileList[i].pszFilename );
    2030                 :     }
    2031              17 : }
    2032                 : 
    2033                 : /************************************************************************/
    2034                 : /*                           CPLUnlinkTree()                            */
    2035                 : /************************************************************************/
    2036                 : 
    2037                 : /**
    2038                 :  * @return 0 on successful completion, -1 if function fails.
    2039                 :  */
    2040                 : 
    2041              14 : int CPLUnlinkTree( const char *pszPath )
    2042                 : 
    2043                 : {
    2044                 : /* -------------------------------------------------------------------- */
    2045                 : /*      First, ensure there isn't any such file yet.                    */
    2046                 : /* -------------------------------------------------------------------- */
    2047                 :     VSIStatBuf sStatBuf;
    2048                 : 
    2049              14 :     if( VSIStat( pszPath, &sStatBuf ) != 0 )
    2050                 :     {
    2051                 :         CPLError( CE_Failure, CPLE_AppDefined, 
    2052                 :                   "It seems no file system object called '%s' exists.",
    2053               2 :                   pszPath );
    2054                 : 
    2055               2 :         return -1;
    2056                 :     }
    2057                 : 
    2058                 : /* -------------------------------------------------------------------- */
    2059                 : /*      If it's a simple file, just delete it.                          */
    2060                 : /* -------------------------------------------------------------------- */
    2061              12 :     if( VSI_ISREG( sStatBuf.st_mode ) )
    2062                 :     {
    2063              11 :         if( VSIUnlink( pszPath ) != 0 )
    2064                 :         {
    2065                 :             CPLError( CE_Failure, CPLE_AppDefined, "Failed to unlink %s.", 
    2066               0 :                       pszPath );
    2067                 : 
    2068               0 :             return -1;
    2069                 :         }
    2070                 :         else
    2071              11 :             return 0;
    2072                 :     }
    2073                 : 
    2074                 : /* -------------------------------------------------------------------- */
    2075                 : /*      If it is a directory recurse then unlink the directory.         */
    2076                 : /* -------------------------------------------------------------------- */
    2077               1 :     else if( VSI_ISDIR( sStatBuf.st_mode ) )
    2078                 :     {
    2079               1 :         char **papszItems = CPLReadDir( pszPath );
    2080                 :         int  i;
    2081                 : 
    2082              14 :         for( i = 0; papszItems != NULL && papszItems[i] != NULL; i++ )
    2083                 :         {
    2084                 :             char *pszSubPath;
    2085                 :             int nErr;
    2086                 : 
    2087              13 :             if( EQUAL(papszItems[i],".") || EQUAL(papszItems[i],"..") )
    2088               2 :                 continue;
    2089                 : 
    2090                 :             pszSubPath = CPLStrdup(
    2091              11 :                 CPLFormFilename( pszPath, papszItems[i], NULL ) );
    2092                 : 
    2093              11 :             nErr = CPLUnlinkTree( pszSubPath );
    2094              11 :             CPLFree( pszSubPath );
    2095                 : 
    2096              11 :             if( nErr != 0 )
    2097                 :             {
    2098               0 :                 CSLDestroy( papszItems );
    2099               0 :                 return nErr;
    2100                 :             }
    2101                 :         }
    2102                 :         
    2103               1 :         CSLDestroy( papszItems );
    2104                 : 
    2105               1 :         if( VSIRmdir( pszPath ) != 0 )
    2106                 :         {
    2107                 :             CPLError( CE_Failure, CPLE_AppDefined, "Failed to unlink %s.", 
    2108               0 :                       pszPath );
    2109                 : 
    2110               0 :             return -1;
    2111                 :         }
    2112                 :         else
    2113               1 :             return 0;
    2114                 :     }
    2115                 : 
    2116                 : /* -------------------------------------------------------------------- */
    2117                 : /*      otherwise report an error.                                      */
    2118                 : /* -------------------------------------------------------------------- */
    2119                 :     else
    2120                 :     {
    2121                 :         CPLError( CE_Failure, CPLE_AppDefined, 
    2122                 :                   "Failed to unlink %s.\nUnrecognised filesystem object.",
    2123               0 :                   pszPath );
    2124               0 :         return 1000;
    2125                 :     }
    2126                 : }
    2127                 : 
    2128                 : /************************************************************************/
    2129                 : /*                            CPLCopyFile()                             */
    2130                 : /************************************************************************/
    2131                 : 
    2132               0 : int CPLCopyFile( const char *pszNewPath, const char *pszOldPath )
    2133                 : 
    2134                 : {
    2135                 :     FILE *fpOld, *fpNew;
    2136                 :     GByte *pabyBuffer;
    2137                 :     size_t nBufferSize;
    2138                 :     size_t nBytesRead;
    2139               0 :     int nRet = 0;
    2140                 : 
    2141                 : /* -------------------------------------------------------------------- */
    2142                 : /*      Open old and new file.                                          */
    2143                 : /* -------------------------------------------------------------------- */
    2144               0 :     fpOld = VSIFOpenL( pszOldPath, "rb" );
    2145               0 :     if( fpOld == NULL )
    2146               0 :         return -1;
    2147                 : 
    2148               0 :     fpNew = VSIFOpenL( pszNewPath, "wb" );
    2149               0 :     if( fpNew == NULL )
    2150                 :     {
    2151               0 :         VSIFCloseL( fpOld );
    2152               0 :         return -1;
    2153                 :     }
    2154                 : 
    2155                 : /* -------------------------------------------------------------------- */
    2156                 : /*      Prepare buffer.                                                 */
    2157                 : /* -------------------------------------------------------------------- */
    2158               0 :     nBufferSize = 1024 * 1024;
    2159               0 :     pabyBuffer = (GByte *) CPLMalloc(nBufferSize);
    2160                 : 
    2161                 : /* -------------------------------------------------------------------- */
    2162                 : /*      Copy file over till we run out of stuff.                        */
    2163                 : /* -------------------------------------------------------------------- */
    2164               0 :     do { 
    2165               0 :         nBytesRead = VSIFReadL( pabyBuffer, 1, nBufferSize, fpOld );
    2166                 :         if( nBytesRead < 0 )
    2167                 :             nRet = -1;
    2168                 : 
    2169               0 :         if( nRet == 0
    2170                 :             && VSIFWriteL( pabyBuffer, 1, nBytesRead, fpNew ) < nBytesRead )
    2171               0 :             nRet = -1;
    2172                 :     } while( nRet == 0 && nBytesRead == nBufferSize );
    2173                 : 
    2174                 : /* -------------------------------------------------------------------- */
    2175                 : /*      Cleanup                                                         */
    2176                 : /* -------------------------------------------------------------------- */
    2177               0 :     VSIFCloseL( fpNew );
    2178               0 :     VSIFCloseL( fpOld );
    2179                 : 
    2180               0 :     CPLFree( pabyBuffer );
    2181                 : 
    2182               0 :     return nRet;
    2183                 : }
    2184                 : 
    2185                 : /************************************************************************/
    2186                 : /*                            CPLMoveFile()                             */
    2187                 : /************************************************************************/
    2188                 : 
    2189               0 : int CPLMoveFile( const char *pszNewPath, const char *pszOldPath )
    2190                 : 
    2191                 : {
    2192               0 :     if( VSIRename( pszNewPath, pszOldPath ) == 0 )
    2193               0 :         return 0;
    2194                 : 
    2195               0 :     int nRet = CPLCopyFile( pszNewPath, pszOldPath );
    2196                 : 
    2197               0 :     if( nRet == 0 )
    2198               0 :         VSIUnlink( pszOldPath );
    2199                 :     
    2200               0 :     return nRet;
    2201                 : }
    2202                 : 
    2203                 : /************************************************************************/
    2204                 : /* ==================================================================== */
    2205                 : /*                              CPLLocaleC                              */
    2206                 : /* ==================================================================== */
    2207                 : /************************************************************************/
    2208                 : 
    2209                 : #include <locale.h>
    2210                 : 
    2211                 : /************************************************************************/
    2212                 : /*                             CPLLocaleC()                             */
    2213                 : /************************************************************************/
    2214                 : 
    2215           41322 : CPLLocaleC::CPLLocaleC() : pszOldLocale(CPLStrdup(setlocale(LC_NUMERIC,NULL)))
    2216                 : 
    2217                 : {
    2218           41322 :     if( setlocale(LC_NUMERIC,"C") == NULL )
    2219                 :     {
    2220               0 :         CPLFree( pszOldLocale );
    2221               0 :         pszOldLocale = NULL;
    2222                 :     }
    2223           41322 : }
    2224                 : 
    2225                 : /************************************************************************/
    2226                 : /*                            ~CPLLocaleC()                             */
    2227                 : /************************************************************************/
    2228                 : 
    2229           41322 : CPLLocaleC::~CPLLocaleC()
    2230                 : 
    2231                 : {
    2232           41322 :     if( pszOldLocale != NULL )
    2233                 :     {
    2234           41322 :         setlocale( LC_NUMERIC, pszOldLocale );
    2235           41322 :         CPLFree( pszOldLocale );
    2236                 :     }
    2237           41322 : }
    2238                 : 
    2239                 : /************************************************************************/
    2240                 : /*                          CPLCheckForFile()                           */
    2241                 : /************************************************************************/
    2242                 : 
    2243                 : /**
    2244                 :  * Check for file existance.
    2245                 :  *
    2246                 :  * The function checks if a named file exists in the filesystem, hopefully
    2247                 :  * in an efficient fashion if a sibling file list is available.   It exists
    2248                 :  * primarily to do faster file checking for functions like GDAL open methods
    2249                 :  * that get a list of files from the target directory. 
    2250                 :  *
    2251                 :  * If the sibling file list exists (is not NULL) it is assumed to be a list
    2252                 :  * of files in the same directory as the target file, and it will be checked
    2253                 :  * (case insensitively) for a match.  If a match is found, pszFilename is
    2254                 :  * updated with the correct case and TRUE is returned. 
    2255                 :  *
    2256                 :  * If papszSiblingFiles is NULL, a VSIStatL() is used to test for the files
    2257                 :  * existance, and no case insensitive testing is done. 
    2258                 :  *
    2259                 :  * @param pszFilename name of file to check for - filename case updated in some cases.
    2260                 :  * @param papszSiblingFiles a list of files in the same directory as 
    2261                 :  * pszFilename if available, or NULL. This list should have no path components.
    2262                 :  *
    2263                 :  * @return TRUE if a match is found, or FALSE if not.
    2264                 :  */
    2265                 : 
    2266            6690 : int CPLCheckForFile( char *pszFilename, char **papszSiblingFiles )
    2267                 : 
    2268                 : {
    2269                 : /* -------------------------------------------------------------------- */
    2270                 : /*      Fallback case if we don't have a sibling file list.             */
    2271                 : /* -------------------------------------------------------------------- */
    2272            6690 :     if( papszSiblingFiles == NULL )
    2273                 :     {
    2274                 :         VSIStatBufL sStatBuf;
    2275                 : 
    2276            6662 :         return VSIStatL( pszFilename, &sStatBuf ) == 0;
    2277                 :     }
    2278                 : 
    2279                 : /* -------------------------------------------------------------------- */
    2280                 : /*      We have sibling files, compare the non-path filename portion    */
    2281                 : /*      of pszFilename too all entries.                                 */
    2282                 : /* -------------------------------------------------------------------- */
    2283              28 :     CPLString osFileOnly = CPLGetFilename( pszFilename );
    2284                 :     int i;
    2285                 : 
    2286            2532 :     for( i = 0; papszSiblingFiles[i] != NULL; i++ )
    2287                 :     {
    2288            2506 :         if( EQUAL(papszSiblingFiles[i],osFileOnly) )
    2289                 :         {
    2290                 :             strcpy( pszFilename + strlen(pszFilename) - strlen(osFileOnly), 
    2291               2 :                     papszSiblingFiles[i] );
    2292              30 :             return TRUE;
    2293                 :         }
    2294                 :     }
    2295                 : 
    2296              26 :     return FALSE;
    2297                 : }

Generated by: LTP GCOV extension version 1.5