LCOV - code coverage report
Current view: directory - port - cpl_vsisimple.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 139 100 71.9 %
Date: 2012-04-28 Functions: 30 24 80.0 %

       1                 : /******************************************************************************
       2                 :  * $Id: cpl_vsisimple.cpp 23604 2011-12-19 22:49:08Z rouault $
       3                 :  *
       4                 :  * Project:  Common Portability Library 
       5                 :  * Purpose:  Simple implementation of POSIX VSI 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                 :  *
      30                 :  * NB: Note that in wrappers we are always saving the error state (errno
      31                 :  * variable) to avoid side effects during debug prints or other possible
      32                 :  * standard function calls (error states will be overwritten after such
      33                 :  * a call).
      34                 :  *
      35                 :  ****************************************************************************/
      36                 : 
      37                 : #include "cpl_config.h"
      38                 : #include "cpl_port.h"
      39                 : #include "cpl_vsi.h"
      40                 : #include "cpl_error.h"
      41                 : #include "cpl_string.h"
      42                 : 
      43                 : /* Uncomment to check consistent usage of VSIMalloc(), VSIRealloc(), */
      44                 : /* VSICalloc(), VSIFree(), VSIStrdup() */
      45                 : //#define DEBUG_VSIMALLOC
      46                 : 
      47                 : /* Uncomment to compute memory usage statistics. */
      48                 : /* DEBUG_VSIMALLOC must also be defined */
      49                 : //#define DEBUG_VSIMALLOC_STATS
      50                 : 
      51                 : /* Uncomment to print every memory allocation or deallocation. */
      52                 : /* DEBUG_VSIMALLOC must also be defined */
      53                 : //#define DEBUG_VSIMALLOC_VERBOSE
      54                 : 
      55                 : CPL_CVSID("$Id: cpl_vsisimple.cpp 23604 2011-12-19 22:49:08Z rouault $");
      56                 : 
      57                 : /* for stat() */
      58                 : 
      59                 : /* Unix or Windows NT/2000/XP */
      60                 : #if !defined(WIN32) && !defined(WIN32CE)
      61                 : #  include <unistd.h>
      62                 : #elif !defined(WIN32CE) /* not Win32 platform */
      63                 : #  include <io.h>
      64                 : #  include <fcntl.h>
      65                 : #  include <direct.h>
      66                 : #endif
      67                 : 
      68                 : /* Windows CE or other platforms */
      69                 : #if defined(WIN32CE)
      70                 : #  include <wce_io.h>
      71                 : #  include <wce_stat.h>
      72                 : #  include <wce_stdio.h>
      73                 : #  include <wce_string.h>
      74                 : #  include <wce_time.h>
      75                 : # define time wceex_time
      76                 : #else
      77                 : #  include <sys/stat.h>
      78                 : #  include <time.h>
      79                 : #endif
      80                 : 
      81                 : /************************************************************************/
      82                 : /*                              VSIFOpen()                              */
      83                 : /************************************************************************/
      84                 : 
      85           24654 : FILE *VSIFOpen( const char * pszFilename, const char * pszAccess )
      86                 : 
      87                 : {
      88           24654 :     FILE *fp = NULL;
      89                 :     int     nError;
      90                 : 
      91                 : #if defined(WIN32) && !defined(WIN32CE)
      92                 :     if( CSLTestBoolean(
      93                 :             CPLGetConfigOption( "GDAL_FILENAME_IS_UTF8", "YES" ) ) )
      94                 :     {
      95                 :         wchar_t *pwszFilename = 
      96                 :             CPLRecodeToWChar( pszFilename, CPL_ENC_UTF8, CPL_ENC_UCS2 );
      97                 :         wchar_t *pwszAccess = 
      98                 :             CPLRecodeToWChar( pszAccess, CPL_ENC_UTF8, CPL_ENC_UCS2 );
      99                 : 
     100                 :         fp = _wfopen( pwszFilename, pwszAccess );
     101                 : 
     102                 :         CPLFree( pwszFilename );
     103                 :         CPLFree( pwszAccess );
     104                 :     }
     105                 :     else
     106                 : #endif
     107           24654 :     fp = fopen( (char *) pszFilename, (char *) pszAccess );
     108                 : 
     109           24654 :     nError = errno;
     110                 :     VSIDebug3( "VSIFOpen(%s,%s) = %p", pszFilename, pszAccess, fp );
     111           24654 :     errno = nError;
     112                 : 
     113           24654 :     return( fp );
     114                 : }
     115                 : 
     116                 : /************************************************************************/
     117                 : /*                             VSIFClose()                              */
     118                 : /************************************************************************/
     119                 : 
     120           22170 : int VSIFClose( FILE * fp )
     121                 : 
     122                 : {
     123                 :     VSIDebug1( "VSIClose(%p)", fp );
     124                 : 
     125           22170 :     return( fclose(fp) );
     126                 : }
     127                 : 
     128                 : /************************************************************************/
     129                 : /*                              VSIFSeek()                              */
     130                 : /************************************************************************/
     131                 : 
     132          818421 : int VSIFSeek( FILE * fp, long nOffset, int nWhence )
     133                 : 
     134                 : {
     135          818421 :     int     nResult = fseek( fp, nOffset, nWhence );
     136          818421 :     int     nError = errno;
     137                 : 
     138                 : #ifdef VSI_DEBUG
     139                 :     if( nWhence == SEEK_SET )
     140                 :     {
     141                 :         VSIDebug3( "VSIFSeek(%p,%ld,SEEK_SET) = %d", fp, nOffset, nResult );
     142                 :     }
     143                 :     else if( nWhence == SEEK_END )
     144                 :     {
     145                 :         VSIDebug3( "VSIFSeek(%p,%ld,SEEK_END) = %d", fp, nOffset, nResult );
     146                 :     }
     147                 :     else if( nWhence == SEEK_CUR )
     148                 :     {
     149                 :         VSIDebug3( "VSIFSeek(%p,%ld,SEEK_CUR) = %d", fp, nOffset, nResult );
     150                 :     }
     151                 :     else
     152                 :     {
     153                 :         VSIDebug4( "VSIFSeek(%p,%ld,%d-Unknown) = %d",
     154                 :                    fp, nOffset, nWhence, nResult );
     155                 :     }
     156                 : #endif 
     157                 : 
     158          818421 :     errno = nError;
     159          818421 :     return nResult;
     160                 : }
     161                 : 
     162                 : /************************************************************************/
     163                 : /*                              VSIFTell()                              */
     164                 : /************************************************************************/
     165                 : 
     166         4842031 : long VSIFTell( FILE * fp )
     167                 : 
     168                 : {
     169         4842031 :     long    nOffset = ftell(fp);
     170         4842031 :     int     nError = errno;
     171                 : 
     172                 :     VSIDebug2( "VSIFTell(%p) = %ld", fp, nOffset );
     173                 : 
     174         4842031 :     errno = nError;
     175         4842031 :     return nOffset;
     176                 : }
     177                 : 
     178                 : /************************************************************************/
     179                 : /*                             VSIRewind()                              */
     180                 : /************************************************************************/
     181                 : 
     182           15004 : void VSIRewind( FILE * fp )
     183                 : 
     184                 : {
     185                 :     VSIDebug1("VSIRewind(%p)", fp );
     186           15004 :     rewind( fp );
     187           15004 : }
     188                 : 
     189                 : /************************************************************************/
     190                 : /*                              VSIFRead()                              */
     191                 : /************************************************************************/
     192                 : 
     193          834324 : size_t VSIFRead( void * pBuffer, size_t nSize, size_t nCount, FILE * fp )
     194                 : 
     195                 : {
     196          834324 :     size_t  nResult = fread( pBuffer, nSize, nCount, fp );
     197          834324 :     int     nError = errno;
     198                 : 
     199                 :     VSIDebug4( "VSIFRead(%p,%ld,%ld) = %ld", 
     200                 :                fp, (long)nSize, (long)nCount, (long)nResult );
     201                 : 
     202          834324 :     errno = nError;
     203          834324 :     return nResult;
     204                 : }
     205                 : 
     206                 : /************************************************************************/
     207                 : /*                             VSIFWrite()                              */
     208                 : /************************************************************************/
     209                 : 
     210            3222 : size_t VSIFWrite( const void *pBuffer, size_t nSize, size_t nCount, FILE * fp )
     211                 : 
     212                 : {
     213            3222 :     size_t  nResult = fwrite( pBuffer, nSize, nCount, fp );
     214            3222 :     int     nError = errno;
     215                 : 
     216                 :     VSIDebug4( "VSIFWrite(%p,%ld,%ld) = %ld", 
     217                 :                fp, (long)nSize, (long)nCount, (long)nResult );
     218                 : 
     219            3222 :     errno = nError;
     220            3222 :     return nResult;
     221                 : }
     222                 : 
     223                 : /************************************************************************/
     224                 : /*                             VSIFFlush()                              */
     225                 : /************************************************************************/
     226                 : 
     227               4 : void VSIFFlush( FILE * fp )
     228                 : 
     229                 : {
     230                 :     VSIDebug1( "VSIFFlush(%p)", fp );
     231               4 :     fflush( fp );
     232               4 : }
     233                 : 
     234                 : /************************************************************************/
     235                 : /*                              VSIFGets()                              */
     236                 : /************************************************************************/
     237                 : 
     238         2747101 : char *VSIFGets( char *pszBuffer, int nBufferSize, FILE * fp )
     239                 : 
     240                 : {
     241         2747101 :     return( fgets( pszBuffer, nBufferSize, fp ) );
     242                 : }
     243                 : 
     244                 : /************************************************************************/
     245                 : /*                              VSIFGetc()                              */
     246                 : /************************************************************************/
     247                 : 
     248           16742 : int VSIFGetc( FILE * fp )
     249                 : 
     250                 : {
     251           16742 :     return( fgetc( fp ) );
     252                 : }
     253                 : 
     254                 : /************************************************************************/
     255                 : /*                             VSIUngetc()                              */
     256                 : /************************************************************************/
     257                 : 
     258             234 : int VSIUngetc( int c, FILE * fp )
     259                 : 
     260                 : {
     261             234 :     return( ungetc( c, fp ) );
     262                 : }
     263                 : 
     264                 : /************************************************************************/
     265                 : /*                             VSIFPrintf()                             */
     266                 : /*                                                                      */
     267                 : /*      This is a little more complicated than just calling             */
     268                 : /*      fprintf() because of the variable arguments.  Instead we        */
     269                 : /*      have to use vfprintf().                                         */
     270                 : /************************************************************************/
     271                 : 
     272              72 : int     VSIFPrintf( FILE * fp, const char * pszFormat, ... )
     273                 : 
     274                 : {
     275                 :     va_list     args;
     276                 :     int         nReturn;
     277                 : 
     278              72 :     va_start( args, pszFormat );
     279              72 :     nReturn = vfprintf( fp, pszFormat, args );
     280              72 :     va_end( args );
     281                 : 
     282              72 :     return( nReturn );
     283                 : }
     284                 : 
     285                 : /************************************************************************/
     286                 : /*                              VSIFEof()                               */
     287                 : /************************************************************************/
     288                 : 
     289          482604 : int VSIFEof( FILE * fp )
     290                 : 
     291                 : {
     292          482604 :     return( feof( fp ) );
     293                 : }
     294                 : 
     295                 : /************************************************************************/
     296                 : /*                              VSIFPuts()                              */
     297                 : /************************************************************************/
     298                 : 
     299               0 : int VSIFPuts( const char * pszString, FILE * fp )
     300                 : 
     301                 : {
     302               0 :     return fputs( pszString, fp );
     303                 : }
     304                 : 
     305                 : /************************************************************************/
     306                 : /*                              VSIFPutc()                              */
     307                 : /************************************************************************/
     308                 : 
     309               0 : int VSIFPutc( int nChar, FILE * fp )
     310                 : 
     311                 : {
     312               0 :     return( fputc( nChar, fp ) );
     313                 : }
     314                 : 
     315                 : 
     316                 : #ifdef DEBUG_VSIMALLOC_STATS
     317                 : #include "cpl_multiproc.h"
     318                 : 
     319                 : static void* hMemStatMutex = 0;
     320                 : static size_t nCurrentTotalAllocs = 0;
     321                 : static size_t nMaxTotalAllocs = 0;
     322                 : static GUIntBig nVSIMallocs = 0;
     323                 : static GUIntBig nVSICallocs = 0;
     324                 : static GUIntBig nVSIReallocs = 0;
     325                 : static GUIntBig nVSIFrees = 0;
     326                 : 
     327                 : /************************************************************************/
     328                 : /*                         VSIShowMemStats()                            */
     329                 : /************************************************************************/
     330                 : 
     331                 : void VSIShowMemStats()
     332                 : {
     333                 :     char* pszShowMemStats = getenv("CPL_SHOW_MEM_STATS");
     334                 :     if (pszShowMemStats == NULL || pszShowMemStats[0] == '\0' )
     335                 :         return;
     336                 :     printf("Current VSI memory usage        : " CPL_FRMT_GUIB " bytes\n",
     337                 :             (GUIntBig)nCurrentTotalAllocs);
     338                 :     printf("Maximum VSI memory usage        : " CPL_FRMT_GUIB " bytes\n",
     339                 :             (GUIntBig)nMaxTotalAllocs);
     340                 :     printf("Number of calls to VSIMalloc()  : " CPL_FRMT_GUIB "\n",
     341                 :             nVSIMallocs);
     342                 :     printf("Number of calls to VSICalloc()  : " CPL_FRMT_GUIB "\n",
     343                 :             nVSICallocs);
     344                 :     printf("Number of calls to VSIRealloc() : " CPL_FRMT_GUIB "\n",
     345                 :             nVSIReallocs);
     346                 :     printf("Number of calls to VSIFree()    : " CPL_FRMT_GUIB "\n",
     347                 :             nVSIFrees);
     348                 :     printf("VSIMalloc + VSICalloc - VSIFree : " CPL_FRMT_GUIB "\n",
     349                 :             nVSIMallocs + nVSICallocs - nVSIFrees);
     350                 : }
     351                 : #endif
     352                 : 
     353                 : #ifdef DEBUG_VSIMALLOC
     354                 : static GIntBig nMaxPeakAllocSize = -1;
     355                 : static GIntBig nMaxCumulAllocSize = -1;
     356                 : #endif
     357                 : 
     358                 : /************************************************************************/
     359                 : /*                             VSICalloc()                              */
     360                 : /************************************************************************/
     361                 : 
     362        10926591 : void *VSICalloc( size_t nCount, size_t nSize )
     363                 : 
     364                 : {
     365                 : #ifdef DEBUG_VSIMALLOC
     366                 :     size_t nMul = nCount * nSize;
     367                 :     if (nCount != 0 && nMul / nCount != nSize)
     368                 :     {
     369                 :         fprintf(stderr, "Overflow in VSICalloc(%d, %d)\n",
     370                 :                 (int)nCount, (int)nSize);
     371                 :         return NULL;
     372                 :     }
     373                 :     if (nMaxPeakAllocSize < 0)
     374                 :     {
     375                 :         char* pszMaxPeakAllocSize = getenv("CPL_MAX_PEAK_ALLOC_SIZE");
     376                 :         nMaxPeakAllocSize = (pszMaxPeakAllocSize) ? atoi(pszMaxPeakAllocSize) : 0;
     377                 :         char* pszMaxCumulAllocSize = getenv("CPL_MAX_CUMUL_ALLOC_SIZE");
     378                 :         nMaxCumulAllocSize = (pszMaxCumulAllocSize) ? atoi(pszMaxCumulAllocSize) : 0;
     379                 :     }
     380                 :     if (nMaxPeakAllocSize > 0 && (GIntBig)nMul > nMaxPeakAllocSize)
     381                 :         return NULL;
     382                 : #ifdef DEBUG_VSIMALLOC_STATS
     383                 :     if (nMaxCumulAllocSize > 0 && (GIntBig)nCurrentTotalAllocs + (GIntBig)nMul > nMaxCumulAllocSize)
     384                 :         return NULL;
     385                 : #endif
     386                 :     char* ptr = (char*) calloc(1, 2 * sizeof(void*) + nMul);
     387                 :     if (ptr == NULL)
     388                 :         return NULL;
     389                 :     ptr[0] = 'V';
     390                 :     ptr[1] = 'S';
     391                 :     ptr[2] = 'I';
     392                 :     ptr[3] = 'M';
     393                 :     memcpy(ptr + sizeof(void*), &nMul, sizeof(void*));
     394                 : #if defined(DEBUG_VSIMALLOC_STATS) || defined(DEBUG_VSIMALLOC_VERBOSE)
     395                 :     {
     396                 :         CPLMutexHolderD(&hMemStatMutex);
     397                 : #ifdef DEBUG_VSIMALLOC_VERBOSE
     398                 :         fprintf(stderr, "Thread[%p] VSICalloc(%d,%d) = %p\n",
     399                 :                 (void*)CPLGetPID(), (int)nCount, (int)nSize, ptr + 2 * sizeof(void*));
     400                 : #endif
     401                 : #ifdef DEBUG_VSIMALLOC_STATS
     402                 :         nVSICallocs ++;
     403                 :         if (nMaxTotalAllocs == 0)
     404                 :             atexit(VSIShowMemStats);
     405                 :         nCurrentTotalAllocs += nMul;
     406                 :         if (nCurrentTotalAllocs > nMaxTotalAllocs)
     407                 :             nMaxTotalAllocs = nCurrentTotalAllocs;
     408                 : #endif
     409                 :     }
     410                 : #endif
     411                 :     return ptr + 2 * sizeof(void*);
     412                 : #else
     413        10926591 :     return( calloc( nCount, nSize ) );
     414                 : #endif
     415                 : }
     416                 : 
     417                 : /************************************************************************/
     418                 : /*                             VSIMalloc()                              */
     419                 : /************************************************************************/
     420                 : 
     421        75697315 : void *VSIMalloc( size_t nSize )
     422                 : 
     423                 : {
     424                 : #ifdef DEBUG_VSIMALLOC
     425                 :     if (nMaxPeakAllocSize < 0)
     426                 :     {
     427                 :         char* pszMaxPeakAllocSize = getenv("CPL_MAX_PEAK_ALLOC_SIZE");
     428                 :         nMaxPeakAllocSize = (pszMaxPeakAllocSize) ? atoi(pszMaxPeakAllocSize) : 0;
     429                 :         char* pszMaxCumulAllocSize = getenv("CPL_MAX_CUMUL_ALLOC_SIZE");
     430                 :         nMaxCumulAllocSize = (pszMaxCumulAllocSize) ? atoi(pszMaxCumulAllocSize) : 0;
     431                 :     }
     432                 :     if (nMaxPeakAllocSize > 0 && (GIntBig)nSize > nMaxPeakAllocSize)
     433                 :         return NULL;
     434                 : #ifdef DEBUG_VSIMALLOC_STATS
     435                 :     if (nMaxCumulAllocSize > 0 && (GIntBig)nCurrentTotalAllocs + (GIntBig)nSize > nMaxCumulAllocSize)
     436                 :         return NULL;
     437                 : #endif
     438                 :     char* ptr = (char*) malloc(2 * sizeof(void*) + nSize);
     439                 :     if (ptr == NULL)
     440                 :         return NULL;
     441                 :     ptr[0] = 'V';
     442                 :     ptr[1] = 'S';
     443                 :     ptr[2] = 'I';
     444                 :     ptr[3] = 'M';
     445                 :     memcpy(ptr + sizeof(void*), &nSize, sizeof(void*));
     446                 : #if defined(DEBUG_VSIMALLOC_STATS) || defined(DEBUG_VSIMALLOC_VERBOSE)
     447                 :     {
     448                 :         CPLMutexHolderD(&hMemStatMutex);
     449                 : #ifdef DEBUG_VSIMALLOC_VERBOSE
     450                 :         fprintf(stderr, "Thread[%p] VSIMalloc(%d) = %p\n",
     451                 :                 (void*)CPLGetPID(), (int)nSize, ptr + 2 * sizeof(void*));
     452                 : #endif
     453                 : #ifdef DEBUG_VSIMALLOC_STATS
     454                 :         nVSIMallocs ++;
     455                 :         if (nMaxTotalAllocs == 0)
     456                 :             atexit(VSIShowMemStats);
     457                 :         nCurrentTotalAllocs += nSize;
     458                 :         if (nCurrentTotalAllocs > nMaxTotalAllocs)
     459                 :             nMaxTotalAllocs = nCurrentTotalAllocs;
     460                 : #endif
     461                 :     }
     462                 : #endif
     463                 :     return ptr + 2 * sizeof(void*);
     464                 : #else
     465        75697315 :     return( malloc( nSize ) );
     466                 : #endif
     467                 : }
     468                 : 
     469                 : #ifdef DEBUG_VSIMALLOC
     470                 : void VSICheckMarker(char* ptr)
     471                 : {
     472                 :     if (memcmp(ptr, "VSIM", 4) != 0)
     473                 :     {
     474                 :         CPLError(CE_Fatal, CPLE_AppDefined,
     475                 :                  "Inconsistant use of VSI memory allocation primitives for %p : %c%c%c%c",
     476                 :                  ptr, ptr[0], ptr[1], ptr[2], ptr[3]);
     477                 :     }
     478                 : }
     479                 : 
     480                 : #endif
     481                 : 
     482                 : /************************************************************************/
     483                 : /*                             VSIRealloc()                             */
     484                 : /************************************************************************/      
     485                 : 
     486        29036810 : void * VSIRealloc( void * pData, size_t nNewSize )
     487                 : 
     488                 : {
     489                 : #ifdef DEBUG_VSIMALLOC
     490                 :     if (pData == NULL)
     491                 :         return VSIMalloc(nNewSize);
     492                 :         
     493                 :     char* ptr = ((char*)pData) - 2 * sizeof(void*);
     494                 :     VSICheckMarker(ptr);
     495                 : #ifdef DEBUG_VSIMALLOC_STATS
     496                 :     size_t nOldSize;
     497                 :     memcpy(&nOldSize, ptr + sizeof(void*), sizeof(void*));
     498                 : #endif
     499                 : 
     500                 :     if (nMaxPeakAllocSize < 0)
     501                 :     {
     502                 :         char* pszMaxPeakAllocSize = getenv("CPL_MAX_PEAK_ALLOC_SIZE");
     503                 :         nMaxPeakAllocSize = (pszMaxPeakAllocSize) ? atoi(pszMaxPeakAllocSize) : 0;
     504                 :     }
     505                 :     if (nMaxPeakAllocSize > 0 && (GIntBig)nNewSize > nMaxPeakAllocSize)
     506                 :         return NULL;
     507                 : #ifdef DEBUG_VSIMALLOC_STATS
     508                 :     if (nMaxCumulAllocSize > 0 && (GIntBig)nCurrentTotalAllocs + (GIntBig)nNewSize - (GIntBig)nOldSize > nMaxCumulAllocSize)
     509                 :         return NULL;
     510                 : #endif
     511                 : 
     512                 :     void* newptr = realloc(ptr, nNewSize + 2 * sizeof(void*));
     513                 :     if (newptr == NULL)
     514                 :         return NULL;
     515                 :     ptr = (char*) newptr;
     516                 :     memcpy(ptr + sizeof(void*), &nNewSize, sizeof(void*));
     517                 : 
     518                 : #if defined(DEBUG_VSIMALLOC_STATS) || defined(DEBUG_VSIMALLOC_VERBOSE)
     519                 :     {
     520                 :         CPLMutexHolderD(&hMemStatMutex);
     521                 : #ifdef DEBUG_VSIMALLOC_VERBOSE
     522                 :         fprintf(stderr, "Thread[%p] VSIRealloc(%p, %d) = %p\n",
     523                 :                 (void*)CPLGetPID(), pData, (int)nNewSize, ptr + 2 * sizeof(void*));
     524                 : #endif
     525                 : #ifdef DEBUG_VSIMALLOC_STATS
     526                 :         nVSIReallocs ++;
     527                 :         nCurrentTotalAllocs -= nOldSize;
     528                 :         nCurrentTotalAllocs += nNewSize;
     529                 :         if (nCurrentTotalAllocs > nMaxTotalAllocs)
     530                 :             nMaxTotalAllocs = nCurrentTotalAllocs;
     531                 : #endif
     532                 :     }
     533                 : #endif
     534                 :     return ptr + 2 * sizeof(void*);
     535                 : #else
     536        29036810 :     return( realloc( pData, nNewSize ) );
     537                 : #endif
     538                 : }
     539                 : 
     540                 : /************************************************************************/
     541                 : /*                              VSIFree()                               */
     542                 : /************************************************************************/
     543                 : 
     544       121518093 : void VSIFree( void * pData )
     545                 : 
     546                 : {
     547                 : #ifdef DEBUG_VSIMALLOC
     548                 :     if (pData == NULL)
     549                 :         return;
     550                 : 
     551                 :     char* ptr = ((char*)pData) - 2 * sizeof(void*);
     552                 :     VSICheckMarker(ptr);
     553                 :     ptr[0] = 'M';
     554                 :     ptr[1] = 'I';
     555                 :     ptr[2] = 'S';
     556                 :     ptr[3] = 'V';
     557                 : #if defined(DEBUG_VSIMALLOC_STATS) || defined(DEBUG_VSIMALLOC_VERBOSE)
     558                 :     size_t nOldSize;
     559                 :     memcpy(&nOldSize, ptr + sizeof(void*), sizeof(void*));
     560                 :     {
     561                 :         CPLMutexHolderD(&hMemStatMutex);
     562                 : #ifdef DEBUG_VSIMALLOC_VERBOSE
     563                 :         fprintf(stderr, "Thread[%p] VSIFree(%p, (%d bytes))\n",
     564                 :                 (void*)CPLGetPID(), pData, (int)nOldSize);
     565                 : #endif
     566                 : #ifdef DEBUG_VSIMALLOC_STATS
     567                 :         nVSIFrees ++;
     568                 :         nCurrentTotalAllocs -= nOldSize;
     569                 : #endif
     570                 :     }
     571                 : #endif
     572                 :     free(ptr);
     573                 : #else
     574       121518093 :     if( pData != NULL )
     575        98046879 :         free( pData );
     576                 : #endif
     577       121518093 : }
     578                 : 
     579                 : /************************************************************************/
     580                 : /*                             VSIStrdup()                              */
     581                 : /************************************************************************/
     582                 : 
     583         9878577 : char *VSIStrdup( const char * pszString )
     584                 : 
     585                 : {
     586                 : #ifdef DEBUG_VSIMALLOC
     587                 :     int nSize = strlen(pszString) + 1;
     588                 :     char* ptr = (char*) VSIMalloc(nSize);
     589                 :     if (ptr == NULL)
     590                 :         return NULL;
     591                 :     memcpy(ptr, pszString, nSize);
     592                 :     return ptr;
     593                 : #else
     594         9878577 :     return( strdup( pszString ) );
     595                 : #endif
     596                 : }
     597                 : 
     598                 : /************************************************************************/
     599                 : /*                          VSICheckMul2()                              */
     600                 : /************************************************************************/
     601                 : 
     602           51209 : static size_t VSICheckMul2( size_t mul1, size_t mul2, int *pbOverflowFlag)
     603                 : {
     604           51209 :     size_t res = mul1 * mul2;
     605           51209 :     if (mul1 != 0)
     606                 :     {
     607           51207 :         if (res / mul1 == mul2)
     608                 :         {
     609           51207 :             if (pbOverflowFlag)
     610           51207 :                 *pbOverflowFlag = FALSE;
     611           51207 :             return res;
     612                 :         }
     613                 :         else
     614                 :         {
     615               0 :             if (pbOverflowFlag)
     616               0 :                 *pbOverflowFlag = TRUE;
     617                 :             CPLError(CE_Failure, CPLE_OutOfMemory,
     618                 :                      "Multiplication overflow : %lu * %lu",
     619               0 :                      (unsigned long)mul1, (unsigned long)mul2);
     620                 :         }
     621                 :     }
     622                 :     else
     623                 :     {
     624               2 :         if (pbOverflowFlag)
     625               2 :              *pbOverflowFlag = FALSE;
     626                 :     }
     627               2 :     return 0;
     628                 : }
     629                 : 
     630                 : /************************************************************************/
     631                 : /*                          VSICheckMul3()                              */
     632                 : /************************************************************************/
     633                 : 
     634           31264 : static size_t VSICheckMul3( size_t mul1, size_t mul2, size_t mul3, int *pbOverflowFlag)
     635                 : {
     636           31264 :     if (mul1 != 0)
     637                 :     {
     638           31264 :         size_t res = mul1 * mul2;
     639           31264 :         if (res / mul1 == mul2)
     640                 :         {
     641           31264 :             size_t res2 = res * mul3;
     642           31264 :             if (mul3 != 0)
     643                 :             {
     644           31264 :                 if (res2 / mul3 == res)
     645                 :                 {
     646           31264 :                     if (pbOverflowFlag)
     647           31264 :                         *pbOverflowFlag = FALSE;
     648           31264 :                     return res2;
     649                 :                 }
     650                 :                 else
     651                 :                 {
     652               0 :                     if (pbOverflowFlag)
     653               0 :                         *pbOverflowFlag = TRUE;
     654                 :                     CPLError(CE_Failure, CPLE_OutOfMemory,
     655                 :                      "Multiplication overflow : %lu * %lu * %lu",
     656               0 :                      (unsigned long)mul1, (unsigned long)mul2, (unsigned long)mul3);
     657                 :                 }
     658                 :             }
     659                 :             else
     660                 :             {
     661               0 :                 if (pbOverflowFlag)
     662               0 :                     *pbOverflowFlag = FALSE;
     663                 :             }
     664                 :         }
     665                 :         else
     666                 :         {
     667               0 :             if (pbOverflowFlag)
     668               0 :                 *pbOverflowFlag = TRUE;
     669                 :             CPLError(CE_Failure, CPLE_OutOfMemory,
     670                 :                      "Multiplication overflow : %lu * %lu * %lu",
     671               0 :                      (unsigned long)mul1, (unsigned long)mul2, (unsigned long)mul3);
     672                 :         }
     673                 :     }
     674                 :     else
     675                 :     {
     676               0 :         if (pbOverflowFlag)
     677               0 :              *pbOverflowFlag = FALSE;
     678                 :     }
     679               0 :     return 0;
     680                 : }
     681                 : 
     682                 : 
     683                 : 
     684                 : /**
     685                 :  VSIMalloc2 allocates (nSize1 * nSize2) bytes.
     686                 :  In case of overflow of the multiplication, or if memory allocation fails, a
     687                 :  NULL pointer is returned and a CE_Failure error is raised with CPLError().
     688                 :  If nSize1 == 0 || nSize2 == 0, a NULL pointer will also be returned.
     689                 :  CPLFree() or VSIFree() can be used to free memory allocated by this function.
     690                 : */
     691           51209 : void CPL_DLL *VSIMalloc2( size_t nSize1, size_t nSize2 )
     692                 : {
     693           51209 :     int bOverflowFlag = FALSE;
     694                 :     size_t nSizeToAllocate;
     695                 :     void* pReturn;
     696                 : 
     697           51209 :     nSizeToAllocate = VSICheckMul2( nSize1, nSize2, &bOverflowFlag );
     698           51209 :     if (bOverflowFlag)
     699               0 :         return NULL;
     700                 : 
     701           51209 :     if (nSizeToAllocate == 0)
     702             130 :         return NULL;
     703                 : 
     704           51079 :     pReturn = VSIMalloc(nSizeToAllocate);
     705                 : 
     706           51079 :     if( pReturn == NULL )
     707                 :     {
     708                 :         CPLError( CE_Failure, CPLE_OutOfMemory,
     709                 :                   "VSIMalloc2(): Out of memory allocating %lu bytes.\n",
     710               0 :                   (unsigned long)nSizeToAllocate );
     711                 :     }
     712                 : 
     713           51079 :     return pReturn;
     714                 : }
     715                 : 
     716                 : /**
     717                 :  VSIMalloc3 allocates (nSize1 * nSize2 * nSize3) bytes.
     718                 :  In case of overflow of the multiplication, or if memory allocation fails, a
     719                 :  NULL pointer is returned and a CE_Failure error is raised with CPLError().
     720                 :  If nSize1 == 0 || nSize2 == 0 || nSize3 == 0, a NULL pointer will also be returned.
     721                 :  CPLFree() or VSIFree() can be used to free memory allocated by this function.
     722                 : */
     723           31264 : void CPL_DLL *VSIMalloc3( size_t nSize1, size_t nSize2, size_t nSize3 )
     724                 : {
     725           31264 :     int bOverflowFlag = FALSE;
     726                 : 
     727                 :     size_t nSizeToAllocate;
     728                 :     void* pReturn;
     729                 : 
     730           31264 :     nSizeToAllocate = VSICheckMul3( nSize1, nSize2, nSize3, &bOverflowFlag );
     731           31264 :     if (bOverflowFlag)
     732               0 :         return NULL;
     733                 : 
     734           31264 :     if (nSizeToAllocate == 0)
     735               0 :         return NULL;
     736                 : 
     737           31264 :     pReturn = VSIMalloc(nSizeToAllocate);
     738                 : 
     739           31264 :     if( pReturn == NULL )
     740                 :     {
     741                 :         CPLError( CE_Failure, CPLE_OutOfMemory,
     742                 :                   "VSIMalloc3(): Out of memory allocating %lu bytes.\n",
     743               0 :                   (unsigned long)nSizeToAllocate );
     744                 :     }
     745                 : 
     746           31264 :     return pReturn;
     747                 : }
     748                 : 
     749                 : 
     750                 : /************************************************************************/
     751                 : /*                              VSIStat()                               */
     752                 : /************************************************************************/
     753                 : 
     754           10256 : int VSIStat( const char * pszFilename, VSIStatBuf * pStatBuf )
     755                 : 
     756                 : {
     757                 : #if defined(WIN32) && !defined(WIN32CE)
     758                 :     if( CSLTestBoolean(
     759                 :             CPLGetConfigOption( "GDAL_FILENAME_IS_UTF8", "YES" ) ) )
     760                 :     {
     761                 :         int nResult;
     762                 :         wchar_t *pwszFilename = 
     763                 :             CPLRecodeToWChar( pszFilename, CPL_ENC_UTF8, CPL_ENC_UCS2 );
     764                 : 
     765                 :         nResult = _wstat( pwszFilename, (struct _stat *) pStatBuf );
     766                 : 
     767                 :         CPLFree( pwszFilename );
     768                 : 
     769                 :         return nResult;
     770                 :     }
     771                 :     else
     772                 : #endif 
     773           10256 :         return( stat( pszFilename, pStatBuf ) );
     774                 : }
     775                 : 
     776                 : /************************************************************************/
     777                 : /*                              VSITime()                               */
     778                 : /************************************************************************/
     779                 : 
     780               0 : unsigned long VSITime( unsigned long * pnTimeToSet )
     781                 : 
     782                 : {
     783                 :     time_t tTime;
     784                 :         
     785               0 :     tTime = time( NULL );
     786                 : 
     787               0 :     if( pnTimeToSet != NULL )
     788               0 :         *pnTimeToSet = (unsigned long) tTime;
     789                 : 
     790               0 :     return (unsigned long) tTime;
     791                 : }
     792                 : 
     793                 : /************************************************************************/
     794                 : /*                              VSICTime()                              */
     795                 : /************************************************************************/
     796                 : 
     797               0 : const char *VSICTime( unsigned long nTime )
     798                 : 
     799                 : {
     800               0 :     time_t tTime = (time_t) nTime;
     801                 : 
     802               0 :     return (const char *) ctime( &tTime );
     803                 : }
     804                 : 
     805                 : /************************************************************************/
     806                 : /*                             VSIGMTime()                              */
     807                 : /************************************************************************/
     808                 : 
     809               0 : struct tm *VSIGMTime( const time_t *pnTime, struct tm *poBrokenTime )
     810                 : {
     811                 : 
     812                 : #if HAVE_GMTIME_R
     813                 :     gmtime_r( pnTime, poBrokenTime );
     814                 : #else
     815                 :     struct tm   *poTime;
     816               0 :     poTime = gmtime( pnTime );
     817               0 :     memcpy( poBrokenTime, poTime, sizeof(tm) );
     818                 : #endif
     819                 : 
     820               0 :     return poBrokenTime;
     821                 : }
     822                 : 
     823                 : /************************************************************************/
     824                 : /*                             VSILocalTime()                           */
     825                 : /************************************************************************/
     826                 : 
     827               0 : struct tm *VSILocalTime( const time_t *pnTime, struct tm *poBrokenTime )
     828                 : {
     829                 : 
     830                 : #if HAVE_LOCALTIME_R
     831                 :     localtime_r( pnTime, poBrokenTime );
     832                 : #else
     833                 :     struct tm   *poTime;
     834               0 :     poTime = localtime( pnTime );
     835               0 :     memcpy( poBrokenTime, poTime, sizeof(tm) );
     836                 : #endif
     837                 : 
     838               0 :     return poBrokenTime;
     839                 : }
     840                 : 
     841                 : /************************************************************************/
     842                 : /*                            VSIStrerror()                             */
     843                 : /************************************************************************/
     844                 : 
     845              32 : char *VSIStrerror( int nErrno )
     846                 : 
     847                 : {
     848              32 :     return strerror( nErrno );
     849                 : }

Generated by: LCOV version 1.7