LCOV - code coverage report
Current view: directory - port - cpl_vsil_unix_stdio_64.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 101 101 100.0 %
Date: 2010-01-09 Functions: 21 21 100.0 %

       1                 : /**********************************************************************
       2                 :  * $Id: cpl_vsil_unix_stdio_64.cpp 17402 2009-07-16 20:11:00Z warmerdam $
       3                 :  *
       4                 :  * Project:  CPL - Common Portability Library
       5                 :  * Purpose:  Implement VSI large file api for Unix platforms with fseek64()
       6                 :  *           and ftell64() such as IRIX. 
       7                 :  * Author:   Frank Warmerdam, warmerdam@pobox.com
       8                 :  *
       9                 :  **********************************************************************
      10                 :  * Copyright (c) 2001, Frank Warmerdam
      11                 :  *
      12                 :  * Permission is hereby granted, free of charge, to any person obtaining a
      13                 :  * copy of this software and associated documentation files (the "Software"),
      14                 :  * to deal in the Software without restriction, including without limitation
      15                 :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      16                 :  * and/or sell copies of the Software, and to permit persons to whom the
      17                 :  * Software is furnished to do so, subject to the following conditions:
      18                 :  * 
      19                 :  * The above copyright notice and this permission notice shall be included
      20                 :  * in all copies or substantial portions of the Software.
      21                 :  * 
      22                 :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
      23                 :  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      24                 :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
      25                 :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      26                 :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      27                 :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
      28                 :  * DEALINGS IN THE SOFTWARE.
      29                 :  ****************************************************************************
      30                 :  *
      31                 :  * NB: Note that in wrappers we are always saving the error state (errno
      32                 :  * variable) to avoid side effects during debug prints or other possible
      33                 :  * standard function calls (error states will be overwritten after such
      34                 :  * a call).
      35                 :  *
      36                 :  ****************************************************************************/
      37                 : 
      38                 : #include "cpl_port.h"
      39                 : 
      40                 : #if !defined(WIN32) && !defined(WIN32CE)
      41                 : 
      42                 : #include "cpl_vsi_virtual.h"
      43                 : #include "cpl_string.h"
      44                 : 
      45                 : #include <unistd.h>
      46                 : #include <sys/stat.h>
      47                 : #include <sys/types.h>
      48                 : #include <dirent.h>
      49                 : #include <errno.h>
      50                 : 
      51                 : CPL_CVSID("$Id: cpl_vsil_unix_stdio_64.cpp 17402 2009-07-16 20:11:00Z warmerdam $");
      52                 : 
      53                 : #if defined(UNIX_STDIO_64)
      54                 : 
      55                 : #ifndef VSI_FTELL64
      56                 : #define VSI_FTELL64 ftell64
      57                 : #endif
      58                 : #ifndef VSI_FSEEK64
      59                 : #define VSI_FSEEK64 fseek64
      60                 : #endif
      61                 : #ifndef VSI_FOPEN64
      62                 : #define VSI_FOPEN64 fopen64
      63                 : #endif
      64                 : #ifndef VSI_STAT64
      65                 : #define VSI_STAT64 stat64
      66                 : #endif
      67                 : #ifndef VSI_STAT64_T
      68                 : #define VSI_STAT64_T stat64
      69                 : #endif
      70                 : 
      71                 : #else /* not UNIX_STDIO_64 */
      72                 : 
      73                 : #ifndef VSI_FTELL64
      74                 : #define VSI_FTELL64 ftell
      75                 : #endif
      76                 : #ifndef VSI_FSEEK64
      77                 : #define VSI_FSEEK64 fseek
      78                 : #endif
      79                 : #ifndef VSI_FOPEN64
      80                 : #define VSI_FOPEN64 fopen
      81                 : #endif
      82                 : #ifndef VSI_STAT64
      83                 : #define VSI_STAT64 stat
      84                 : #endif
      85                 : #ifndef VSI_STAT64_T
      86                 : #define VSI_STAT64_T stat
      87                 : #endif
      88                 : 
      89                 : #endif /* ndef UNIX_STDIO_64 */
      90                 : 
      91                 : /************************************************************************/
      92                 : /* ==================================================================== */
      93                 : /*                       VSIUnixStdioFilesystemHandler                  */
      94                 : /* ==================================================================== */
      95                 : /************************************************************************/
      96                 : 
      97                 : class VSIUnixStdioFilesystemHandler : public VSIFilesystemHandler 
      98            1105 : {
      99                 : public:
     100                 :     virtual VSIVirtualHandle *Open( const char *pszFilename, 
     101                 :                                     const char *pszAccess);
     102                 :     virtual int      Stat( const char *pszFilename, VSIStatBufL *pStatBuf );
     103                 :     virtual int      Unlink( const char *pszFilename );
     104                 :     virtual int      Rename( const char *oldpath, const char *newpath );
     105                 :     virtual int      Mkdir( const char *pszDirname, long nMode );
     106                 :     virtual int      Rmdir( const char *pszDirname );
     107                 :     virtual char   **ReadDir( const char *pszDirname );
     108                 : };
     109                 : 
     110                 : /************************************************************************/
     111                 : /* ==================================================================== */
     112                 : /*                        VSIUnixStdioHandle                            */
     113                 : /* ==================================================================== */
     114                 : /************************************************************************/
     115                 : 
     116                 : class VSIUnixStdioHandle : public VSIVirtualHandle
     117           40123 : {
     118                 :   public:
     119                 :     FILE          *fp;
     120                 :     vsi_l_offset  nOffset;
     121                 :     int           bLastOpWrite;
     122                 :     int           bLastOpRead;
     123                 :     int           bAtEOF;
     124                 : 
     125                 :     virtual int       Seek( vsi_l_offset nOffset, int nWhence );
     126                 :     virtual vsi_l_offset Tell();
     127                 :     virtual size_t    Read( void *pBuffer, size_t nSize, size_t nMemb );
     128                 :     virtual size_t    Write( const void *pBuffer, size_t nSize, size_t nMemb );
     129                 :     virtual int       Eof();
     130                 :     virtual int       Flush();
     131                 :     virtual int       Close();
     132                 : };
     133                 : 
     134                 : /************************************************************************/
     135                 : /*                               Close()                                */
     136                 : /************************************************************************/
     137                 : 
     138           13374 : int VSIUnixStdioHandle::Close()
     139                 : 
     140                 : {
     141                 :     VSIDebug1( "VSIUnixStdioHandle::Close(%p)", fp );
     142                 : 
     143           13374 :     return fclose( fp );
     144                 : }
     145                 : 
     146                 : /************************************************************************/
     147                 : /*                                Seek()                                */
     148                 : /************************************************************************/
     149                 : 
     150          471667 : int VSIUnixStdioHandle::Seek( vsi_l_offset nOffset, int nWhence )
     151                 : 
     152                 : {
     153                 :     // seeks that do nothing are still surprisingly expensive with MSVCRT.
     154                 :     // try and short circuit if possible.
     155          471667 :     if( nWhence == SEEK_SET && nOffset == this->nOffset )
     156          145552 :         return 0;
     157                 : 
     158          326115 :     if( nWhence == SEEK_END && nOffset == 0 && bAtEOF )
     159          238219 :         return 0;
     160                 : 
     161           87896 :     int     nResult = VSI_FSEEK64( fp, nOffset, nWhence );
     162           87896 :     int     nError = errno;
     163                 : 
     164                 : #ifdef VSI_DEBUG
     165                 : 
     166                 :     if( nWhence == SEEK_SET )
     167                 :     {
     168                 :         VSIDebug3( "VSIUnixStdioHandle::Seek(%p,%d,SEEK_SET) = %d",
     169                 :                    fp, nOffset, nResult );
     170                 :     }
     171                 :     else if( nWhence == SEEK_END )
     172                 :     {
     173                 :         VSIDebug3( "VSIUnixStdioHandle::Seek(%p,%d,SEEK_END) = %d",
     174                 :                    fp, nOffset, nResult );
     175                 :     }
     176                 :     else if( nWhence == SEEK_CUR )
     177                 :     {
     178                 :         VSIDebug3( "VSIUnixStdioHandle::Seek(%p,%d,SEEK_CUR) = %d",
     179                 :                    fp, nOffset, nResult );
     180                 :     }
     181                 :     else
     182                 :     {
     183                 :         VSIDebug4( "VSIUnixStdioHandle::Seek(%p,%d,%d-Unknown) = %d",
     184                 :                    fp, nOffset, nWhence, nResult );
     185                 :     }
     186                 : 
     187                 : #endif 
     188                 : 
     189           87896 :     if( nResult != -1 )
     190                 :     {
     191           87896 :         if( nWhence == SEEK_SET )
     192                 :         {
     193           78961 :             this->nOffset = nOffset;
     194           78961 :             bAtEOF = FALSE;
     195                 :         }
     196            8935 :         else if( nWhence == SEEK_END )
     197                 :         {
     198            7520 :             this->nOffset = VSI_FTELL64( fp );
     199            7520 :             bAtEOF = TRUE;
     200                 :         }
     201            1415 :         else if( nWhence == SEEK_CUR )
     202                 :         {
     203            1415 :             this->nOffset += nOffset;
     204            1415 :             bAtEOF = FALSE;
     205                 :         }
     206                 :     }
     207                 :         
     208           87896 :     bLastOpWrite = FALSE;
     209           87896 :     bLastOpRead = FALSE;
     210                 : 
     211           87896 :     errno = nError;
     212           87896 :     return nResult;
     213                 : }
     214                 : 
     215                 : /************************************************************************/
     216                 : /*                                Tell()                                */
     217                 : /************************************************************************/
     218                 : 
     219          580163 : vsi_l_offset VSIUnixStdioHandle::Tell()
     220                 : 
     221                 : {
     222                 : #ifdef notdef
     223                 :     vsi_l_offset    nOffset = VSI_FTELL64( fp );
     224                 :     int             nError = errno;
     225                 : 
     226                 :     VSIDebug2( "VSIUnixStdioHandle::Tell(%p) = %ld", fp, (long)nOffset );
     227                 : 
     228                 :     errno = nError;
     229                 :     return nOffset;
     230                 : #endif
     231          580163 :     return nOffset;
     232                 : }
     233                 : 
     234                 : /************************************************************************/
     235                 : /*                               Flush()                                */
     236                 : /************************************************************************/
     237                 : 
     238             522 : int VSIUnixStdioHandle::Flush()
     239                 : 
     240                 : {
     241                 :     VSIDebug1( "VSIUnixStdioHandle::Flush(%p)", fp );
     242                 : 
     243             522 :     return fflush( fp );
     244                 : }
     245                 : 
     246                 : /************************************************************************/
     247                 : /*                                Read()                                */
     248                 : /************************************************************************/
     249                 : 
     250         1326255 : size_t VSIUnixStdioHandle::Read( void * pBuffer, size_t nSize, size_t nCount )
     251                 : 
     252                 : {
     253                 : /* -------------------------------------------------------------------- */
     254                 : /*      If a fwrite() is followed by an fread(), the POSIX rules are    */
     255                 : /*      that some of the write may still be buffered and lost.  We      */
     256                 : /*      are required to do a seek between to force flushing.   So we    */
     257                 : /*      keep careful track of what happened last to know if we          */
     258                 : /*      skipped a flushing seek that we may need to do now.             */
     259                 : /* -------------------------------------------------------------------- */
     260         1326255 :     if( bLastOpWrite )
     261            1086 :         VSI_FSEEK64( fp, nOffset, SEEK_SET );
     262                 : 
     263                 : /* -------------------------------------------------------------------- */
     264                 : /*      Perform the read.                                               */
     265                 : /* -------------------------------------------------------------------- */
     266         1326255 :     size_t  nResult = fread( pBuffer, nSize, nCount, fp );
     267         1326255 :     int     nError = errno;
     268                 : 
     269                 :     VSIDebug4( "VSIUnixStdioHandle::Read(%p,%ld,%ld) = %ld", 
     270                 :                fp, (long)nSize, (long)nCount, (long)nResult );
     271                 : 
     272         1326255 :     errno = nError;
     273                 : 
     274                 : /* -------------------------------------------------------------------- */
     275                 : /*      Update current offset.                                          */
     276                 : /* -------------------------------------------------------------------- */
     277         1326255 :     nOffset += nSize * nResult;
     278         1326255 :     bLastOpWrite = FALSE;
     279         1326255 :     bLastOpRead = TRUE;
     280                 :     
     281         1326255 :     return nResult;
     282                 : }
     283                 : 
     284                 : /************************************************************************/
     285                 : /*                               Write()                                */
     286                 : /************************************************************************/
     287                 : 
     288         1626641 : size_t VSIUnixStdioHandle::Write( const void * pBuffer, size_t nSize, 
     289                 :                                   size_t nCount )
     290                 : 
     291                 : {
     292                 : /* -------------------------------------------------------------------- */
     293                 : /*      If a fwrite() is followed by an fread(), the POSIX rules are    */
     294                 : /*      that some of the write may still be buffered and lost.  We      */
     295                 : /*      are required to do a seek between to force flushing.   So we    */
     296                 : /*      keep careful track of what happened last to know if we          */
     297                 : /*      skipped a flushing seek that we may need to do now.             */
     298                 : /* -------------------------------------------------------------------- */
     299         1626641 :     if( bLastOpRead )
     300            1975 :         VSI_FSEEK64( fp, nOffset, SEEK_SET );
     301                 : 
     302                 : /* -------------------------------------------------------------------- */
     303                 : /*      Perform the write.                                              */
     304                 : /* -------------------------------------------------------------------- */
     305         1626641 :     size_t  nResult = fwrite( pBuffer, nSize, nCount, fp );
     306         1626641 :     int     nError = errno;
     307                 : 
     308                 :     VSIDebug4( "VSIUnixStdioHandle::Write(%p,%ld,%ld) = %ld", 
     309                 :                fp, (long)nSize, (long)nCount, (long)nResult );
     310                 : 
     311         1626641 :     errno = nError;
     312                 : 
     313                 : /* -------------------------------------------------------------------- */
     314                 : /*      Update current offset.                                          */
     315                 : /* -------------------------------------------------------------------- */
     316         1626641 :     nOffset += nSize * nResult;
     317         1626641 :     bLastOpWrite = TRUE;
     318         1626641 :     bLastOpRead = FALSE;
     319                 :     
     320         1626641 :     return nResult;
     321                 : }
     322                 : 
     323                 : /************************************************************************/
     324                 : /*                                Eof()                                 */
     325                 : /************************************************************************/
     326                 : 
     327           41113 : int VSIUnixStdioHandle::Eof()
     328                 : 
     329                 : {
     330           41113 :     if( !bAtEOF )
     331           40987 :         bAtEOF = feof(fp);
     332                 : 
     333           41113 :     if( bAtEOF )
     334            1644 :         return 1;
     335                 :     else
     336           39469 :         return 0;
     337                 : }
     338                 : 
     339                 : /************************************************************************/
     340                 : /* ==================================================================== */
     341                 : /*                       VSIUnixStdioFilesystemHandler                  */
     342                 : /* ==================================================================== */
     343                 : /************************************************************************/
     344                 : 
     345                 : /************************************************************************/
     346                 : /*                                Open()                                */
     347                 : /************************************************************************/
     348                 : 
     349                 : VSIVirtualHandle *
     350           37865 : VSIUnixStdioFilesystemHandler::Open( const char *pszFilename, 
     351                 :                                      const char *pszAccess )
     352                 : 
     353                 : {
     354           37865 :     FILE    *fp = VSI_FOPEN64( pszFilename, pszAccess );
     355           37865 :     int     nError = errno;
     356                 :     
     357                 :     VSIDebug3( "VSIUnixStdioFilesystemHandler::Open(\"%s\",\"%s\") = %p",
     358                 :                pszFilename, pszAccess, fp );
     359                 : 
     360           37865 :     if( fp == NULL )
     361                 :     {
     362           24490 :         errno = nError;
     363           24490 :         return NULL;
     364                 :     }
     365                 : 
     366           13375 :     VSIUnixStdioHandle *poHandle = new VSIUnixStdioHandle;
     367                 :     
     368           13375 :     poHandle->fp = fp;
     369           13375 :     poHandle->nOffset = 0;
     370           13375 :     poHandle->bLastOpWrite = FALSE;
     371           13375 :     poHandle->bLastOpRead = FALSE;
     372           13375 :     poHandle->bAtEOF = FALSE;
     373                 : 
     374           13375 :     errno = nError;
     375           13375 :     return poHandle;
     376                 : }
     377                 : 
     378                 : /************************************************************************/
     379                 : /*                                Stat()                                */
     380                 : /************************************************************************/
     381                 : 
     382           48964 : int VSIUnixStdioFilesystemHandler::Stat( const char * pszFilename, 
     383                 :                                          VSIStatBufL * pStatBuf )
     384                 : 
     385                 : {
     386           48964 :     return( VSI_STAT64( pszFilename, pStatBuf ) );
     387                 : }
     388                 : 
     389                 : /************************************************************************/
     390                 : /*                               Unlink()                               */
     391                 : /************************************************************************/
     392                 : 
     393            1752 : int VSIUnixStdioFilesystemHandler::Unlink( const char * pszFilename )
     394                 : 
     395                 : {
     396            1752 :     return unlink( pszFilename );
     397                 : }
     398                 : 
     399                 : /************************************************************************/
     400                 : /*                               Rename()                               */
     401                 : /************************************************************************/
     402                 : 
     403               9 : int VSIUnixStdioFilesystemHandler::Rename( const char *oldpath,
     404                 :                                            const char *newpath )
     405                 : 
     406                 : {
     407               9 :     return rename( oldpath, newpath );
     408                 : }
     409                 : 
     410                 : /************************************************************************/
     411                 : /*                               Mkdir()                                */
     412                 : /************************************************************************/
     413                 : 
     414              21 : int VSIUnixStdioFilesystemHandler::Mkdir( const char * pszPathname,
     415                 :                                           long nMode )
     416                 : 
     417                 : {
     418              21 :     return mkdir( pszPathname, nMode );
     419                 : }
     420                 : 
     421                 : /************************************************************************/
     422                 : /*                               Rmdir()                                */
     423                 : /************************************************************************/
     424                 : 
     425              10 : int VSIUnixStdioFilesystemHandler::Rmdir( const char * pszPathname )
     426                 : 
     427                 : {
     428              10 :     return rmdir( pszPathname );
     429                 : }
     430                 : 
     431                 : /************************************************************************/
     432                 : /*                              ReadDir()                               */
     433                 : /************************************************************************/
     434                 : 
     435            5398 : char **VSIUnixStdioFilesystemHandler::ReadDir( const char *pszPath )
     436                 : 
     437                 : {
     438                 :     DIR           *hDir;
     439                 :     struct dirent *psDirEntry;
     440            5398 :     char          **papszDir = NULL;
     441                 : 
     442            5398 :     if (strlen(pszPath) == 0)
     443               3 :         pszPath = ".";
     444                 : 
     445            5398 :     if ( (hDir = opendir(pszPath)) != NULL )
     446                 :     {
     447                 :         /* In case of really big number of files in the directory, CSLAddString */
     448                 :         /* can be slow (see #2158). We then directly build the list. */
     449            4929 :         int nItems=0;
     450            4929 :         int nAllocatedItems=0;
     451          232542 :         while( (psDirEntry = readdir(hDir)) != NULL )
     452                 :         {
     453          222684 :             if (nItems == 0)
     454                 :             {
     455            4929 :                 papszDir = (char**) CPLCalloc(2,sizeof(char*));
     456            4929 :                 nAllocatedItems = 1;
     457                 :             }
     458          217755 :             else if (nItems >= nAllocatedItems)
     459                 :             {
     460           20953 :                 nAllocatedItems = nAllocatedItems * 2;
     461                 :                 papszDir = (char**)CPLRealloc(papszDir, 
     462           20953 :                                               (nAllocatedItems+2)*sizeof(char*));
     463                 :             }
     464                 : 
     465          222684 :             papszDir[nItems] = CPLStrdup(psDirEntry->d_name);
     466          222684 :             papszDir[nItems+1] = NULL;
     467                 : 
     468          222684 :             nItems++;
     469                 :         }
     470                 : 
     471            4929 :         closedir( hDir );
     472                 :     }
     473                 :     else
     474                 :     {
     475                 :         /* Should we generate an error???  
     476                 :          * For now we'll just return NULL (at the end of the function)
     477                 :          */
     478                 :     }
     479                 : 
     480            5398 :     return papszDir;
     481                 : }
     482                 : 
     483                 : /************************************************************************/
     484                 : /*                     VSIInstallLargeFileHandler()                     */
     485                 : /************************************************************************/
     486                 : 
     487             379 : void VSIInstallLargeFileHandler()
     488                 : 
     489                 : {
     490             379 :     VSIFileManager::InstallHandler( "", new VSIUnixStdioFilesystemHandler );
     491             379 : }
     492                 : 
     493                 : #endif /* ndef WIN32 */

Generated by: LCOV version 1.7