LCOV - code coverage report
Current view: directory - port - cpl_vsil.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 140 120 85.7 %
Date: 2012-04-28 Functions: 31 27 87.1 %

       1                 : /******************************************************************************
       2                 :  * $Id: cpl_vsil.cpp 23506 2011-12-10 13:43:59Z rouault $
       3                 :  *
       4                 :  * Project:  VSI Virtual File System
       5                 :  * Purpose:  Implementation VSI*L File API and other file system access
       6                 :  *           methods going through file virtualization.
       7                 :  * Author:   Frank Warmerdam, warmerdam@pobox.com
       8                 :  *
       9                 :  ******************************************************************************
      10                 :  * Copyright (c) 2005, Frank Warmerdam <warmerdam@pobox.com>
      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
      23                 :  * OR 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                 : #include "cpl_vsi_virtual.h"
      32                 : #include "cpl_string.h"
      33                 : #include <string>
      34                 : 
      35                 : CPL_CVSID("$Id: cpl_vsil.cpp 23506 2011-12-10 13:43:59Z rouault $");
      36                 : 
      37                 : /************************************************************************/
      38                 : /*                             VSIReadDir()                             */
      39                 : /************************************************************************/
      40                 : 
      41                 : /**
      42                 :  * \brief Read names in a directory.
      43                 :  *
      44                 :  * This function abstracts access to directory contains.  It returns a
      45                 :  * list of strings containing the names of files, and directories in this
      46                 :  * directory.  The resulting string list becomes the responsibility of the
      47                 :  * application and should be freed with CSLDestroy() when no longer needed.
      48                 :  *
      49                 :  * Note that no error is issued via CPLError() if the directory path is
      50                 :  * invalid, though NULL is returned.
      51                 :  * 
      52                 :  * This function used to be known as CPLReadDir(), but the old name is now 
      53                 :  * deprecated. 
      54                 :  *
      55                 :  * @param pszPath the relative, or absolute path of a directory to read.  
      56                 :  * UTF-8 encoded.
      57                 :  * @return The list of entries in the directory, or NULL if the directory
      58                 :  * doesn't exist.  Filenames are returned in UTF-8 encoding.
      59                 :  */
      60                 : 
      61           22506 : char **VSIReadDir(const char *pszPath)
      62                 : {
      63                 :     VSIFilesystemHandler *poFSHandler = 
      64           22506 :         VSIFileManager::GetHandler( pszPath );
      65                 : 
      66           22506 :     return poFSHandler->ReadDir( pszPath );
      67                 : }
      68                 : 
      69                 : /************************************************************************/
      70                 : /*                             CPLReadDir()                             */
      71                 : /*                                                                      */
      72                 : /*      This is present only to provide ABI compatability with older    */
      73                 : /*      versions.                                                       */
      74                 : /************************************************************************/
      75                 : #undef CPLReadDir
      76                 : 
      77                 : CPL_C_START
      78                 : char CPL_DLL **CPLReadDir( const char *pszPath );
      79                 : CPL_C_END
      80                 : 
      81               0 : char **CPLReadDir( const char *pszPath )
      82                 : {
      83               0 :     return VSIReadDir(pszPath);
      84                 : }
      85                 : 
      86                 : /************************************************************************/
      87                 : /*                              VSIMkdir()                              */
      88                 : /************************************************************************/
      89                 : 
      90                 : /**
      91                 :  * \brief Create a directory. 
      92                 :  * 
      93                 :  * Create a new directory with the indicated mode.  The mode is ignored
      94                 :  * on some platforms.  A reasonable default mode value would be 0666.
      95                 :  * This method goes through the VSIFileHandler virtualization and may
      96                 :  * work on unusual filesystems such as in memory.
      97                 :  *
      98                 :  * Analog of the POSIX mkdir() function.
      99                 :  *
     100                 :  * @param pszPathname the path to the directory to create. UTF-8 encoded.
     101                 :  * @param mode the permissions mode.
     102                 :  *
     103                 :  * @return 0 on success or -1 on an error.
     104                 :  */
     105                 : 
     106             236 : int VSIMkdir( const char *pszPathname, long mode )
     107                 : 
     108                 : {
     109                 :     VSIFilesystemHandler *poFSHandler = 
     110             236 :         VSIFileManager::GetHandler( pszPathname );
     111                 : 
     112             236 :     return poFSHandler->Mkdir( pszPathname, mode );
     113                 : }
     114                 : 
     115                 : /************************************************************************/
     116                 : /*                             VSIUnlink()                              */
     117                 : /*************************a***********************************************/
     118                 : 
     119                 : /**
     120                 :  * \brief Delete a file.
     121                 :  * 
     122                 :  * Deletes a file object from the file system. 
     123                 :  * 
     124                 :  * This method goes through the VSIFileHandler virtualization and may
     125                 :  * work on unusual filesystems such as in memory.
     126                 :  *
     127                 :  * Analog of the POSIX unlink() function.
     128                 :  *
     129                 :  * @param pszFilename the path of the file to be deleted. UTF-8 encoded.
     130                 :  *
     131                 :  * @return 0 on success or -1 on an error.
     132                 :  */
     133                 : 
     134           17164 : int VSIUnlink( const char * pszFilename )
     135                 : 
     136                 : {
     137                 :     VSIFilesystemHandler *poFSHandler = 
     138           17164 :         VSIFileManager::GetHandler( pszFilename );
     139                 : 
     140           17164 :     return poFSHandler->Unlink( pszFilename );
     141                 : }
     142                 : 
     143                 : /************************************************************************/
     144                 : /*                             VSIRename()                              */
     145                 : /************************************************************************/
     146                 : 
     147                 : /**
     148                 :  * \brief Rename a file.
     149                 :  * 
     150                 :  * Renames a file object in the file system.  It should be possible
     151                 :  * to rename a file onto a new filesystem, but it is safest if this 
     152                 :  * function is only used to rename files that remain in the same directory.
     153                 :  * 
     154                 :  * This method goes through the VSIFileHandler virtualization and may
     155                 :  * work on unusual filesystems such as in memory.
     156                 :  *
     157                 :  * Analog of the POSIX rename() function.
     158                 :  *
     159                 :  * @param oldpath the name of the file to be renamed.  UTF-8 encoded.
     160                 :  * @param newpath the name the file should be given.  UTF-8 encoded.
     161                 :  *
     162                 :  * @return 0 on success or -1 on an error.
     163                 :  */
     164                 : 
     165              28 : int VSIRename( const char * oldpath, const char * newpath )
     166                 : 
     167                 : {
     168                 :     VSIFilesystemHandler *poFSHandler = 
     169              28 :         VSIFileManager::GetHandler( oldpath );
     170                 : 
     171              28 :     return poFSHandler->Rename( oldpath, newpath );
     172                 : }
     173                 : 
     174                 : /************************************************************************/
     175                 : /*                              VSIRmdir()                              */
     176                 : /************************************************************************/
     177                 : 
     178                 : /**
     179                 :  * \brief Delete a directory.
     180                 :  * 
     181                 :  * Deletes a directory object from the file system.  On some systems
     182                 :  * the directory must be empty before it can be deleted.
     183                 :  * 
     184                 :  * This method goes through the VSIFileHandler virtualization and may
     185                 :  * work on unusual filesystems such as in memory.
     186                 :  *
     187                 :  * Analog of the POSIX rmdir() function.
     188                 :  *
     189                 :  * @param pszDirname the path of the directory to be deleted.  UTF-8 encoded.
     190                 :  *
     191                 :  * @return 0 on success or -1 on an error.
     192                 :  */
     193                 : 
     194             634 : int VSIRmdir( const char * pszDirname )
     195                 : 
     196                 : {
     197                 :     VSIFilesystemHandler *poFSHandler = 
     198             634 :         VSIFileManager::GetHandler( pszDirname );
     199                 : 
     200             634 :     return poFSHandler->Rmdir( pszDirname );
     201                 : }
     202                 : 
     203                 : /************************************************************************/
     204                 : /*                              VSIStatL()                              */
     205                 : /************************************************************************/
     206                 : 
     207                 : /**
     208                 :  * \brief Get filesystem object info.
     209                 :  * 
     210                 :  * Fetches status information about a filesystem object (file, directory, etc).
     211                 :  * The returned information is placed in the VSIStatBufL structure.   For
     212                 :  * portability only the st_size (size in bytes), and st_mode (file type). 
     213                 :  * This method is similar to VSIStat(), but will work on large files on 
     214                 :  * systems where this requires special calls. 
     215                 :  * 
     216                 :  * This method goes through the VSIFileHandler virtualization and may
     217                 :  * work on unusual filesystems such as in memory.
     218                 :  *
     219                 :  * Analog of the POSIX stat() function.
     220                 :  *
     221                 :  * @param pszFilename the path of the filesystem object to be queried.  UTF-8 encoded.
     222                 :  * @param psStatBuf the structure to load with information. 
     223                 :  *
     224                 :  * @return 0 on success or -1 on an error.
     225                 :  */
     226                 : 
     227           19686 : int VSIStatL( const char * pszFilename, VSIStatBufL *psStatBuf )
     228                 : 
     229                 : {
     230           19686 :     return VSIStatExL(pszFilename, psStatBuf, 0);
     231                 : }
     232                 : 
     233                 : 
     234                 : /************************************************************************/
     235                 : /*                            VSIStatExL()                              */
     236                 : /************************************************************************/
     237                 : 
     238                 : /**
     239                 :  * \brief Get filesystem object info.
     240                 :  *
     241                 :  * Fetches status information about a filesystem object (file, directory, etc).
     242                 :  * The returned information is placed in the VSIStatBufL structure.   For
     243                 :  * portability only the st_size (size in bytes), and st_mode (file type).
     244                 :  * This method is similar to VSIStat(), but will work on large files on
     245                 :  * systems where this requires special calls.
     246                 :  *
     247                 :  * This method goes through the VSIFileHandler virtualization and may
     248                 :  * work on unusual filesystems such as in memory.
     249                 :  *
     250                 :  * Analog of the POSIX stat() function, with an extra parameter to specify
     251                 :  * which information is needed, which offers a potential for speed optimizations
     252                 :  * on specialized and potentially slow virtual filesystem objects (/vsigzip/, /vsicurl/)
     253                 :  *
     254                 :  * @param pszFilename the path of the filesystem object to be queried.  UTF-8 encoded.
     255                 :  * @param psStatBuf the structure to load with information.
     256                 :  * @param nFlags 0 to get all information, or VSI_STAT_EXISTS_FLAG, VSI_STAT_NATURE_FLAG or
     257                 :  *                  VSI_STAT_SIZE_FLAG, or a combination of those to get partial info.
     258                 :  *
     259                 :  * @return 0 on success or -1 on an error.
     260                 :  *
     261                 :  * @since GDAL 1.8.0
     262                 :  */
     263                 : 
     264          110936 : int VSIStatExL( const char * pszFilename, VSIStatBufL *psStatBuf, int nFlags )
     265                 : 
     266                 : {
     267                 :     char    szAltPath[4];
     268                 :     /* enable to work on "C:" as if it were "C:\" */
     269          110936 :     if( strlen(pszFilename) == 2 && pszFilename[1] == ':' )
     270                 :     {
     271               0 :         szAltPath[0] = pszFilename[0];
     272               0 :         szAltPath[1] = pszFilename[1];
     273               0 :         szAltPath[2] = '\\';
     274               0 :         szAltPath[3] = '\0';
     275                 : 
     276               0 :         pszFilename = szAltPath;
     277                 :     }
     278                 : 
     279                 :     VSIFilesystemHandler *poFSHandler =
     280          110936 :         VSIFileManager::GetHandler( pszFilename );
     281                 : 
     282          110936 :     if (nFlags == 0)
     283           19686 :         nFlags = VSI_STAT_EXISTS_FLAG | VSI_STAT_NATURE_FLAG | VSI_STAT_SIZE_FLAG;
     284                 : 
     285          110936 :     return poFSHandler->Stat( pszFilename, psStatBuf, nFlags );
     286                 : }
     287                 : 
     288                 : /************************************************************************/
     289                 : /*                       VSIIsCaseSensitiveFS()                         */
     290                 : /************************************************************************/
     291                 : 
     292                 : /**
     293                 :  * \brief Returns if the filenames of the filesystem are case sensitive.
     294                 :  *
     295                 :  * This method retrieves to which filesystem belongs the passed filename
     296                 :  * and return TRUE if the filenames of that filesystem are case sensitive.
     297                 :  *
     298                 :  * Currently, this will return FALSE only for Windows real filenames. Other
     299                 :  * VSI virtual filesystems are case sensitive.
     300                 :  *
     301                 :  * This methods avoid ugly #ifndef WIN32 / #endif code, that is wrong when
     302                 :  * dealing with virtual filenames.
     303                 :  *
     304                 :  * @param pszFilename the path of the filesystem object to be tested.  UTF-8 encoded.
     305                 :  *
     306                 :  * @return TRUE if the filenames of the filesystem are case sensitive.
     307                 :  *
     308                 :  * @since GDAL 1.8.0
     309                 :  */
     310           21156 : int VSIIsCaseSensitiveFS( const char * pszFilename )
     311                 : {
     312                 :     VSIFilesystemHandler *poFSHandler =
     313           21156 :         VSIFileManager::GetHandler( pszFilename );
     314                 :         
     315           21156 :     return poFSHandler->IsCaseSensitive( pszFilename );
     316                 : }
     317                 : 
     318                 : /************************************************************************/
     319                 : /*                             VSIFOpenL()                              */
     320                 : /************************************************************************/
     321                 : 
     322                 : /**
     323                 :  * \brief Open file.
     324                 :  *
     325                 :  * This function opens a file with the desired access.  Large files (larger
     326                 :  * than 2GB) should be supported.  Binary access is always implied and
     327                 :  * the "b" does not need to be included in the pszAccess string.
     328                 :  *
     329                 :  * Note that the "VSILFILE *" returned since GDAL 1.8.0 by this function is 
     330                 :  * *NOT* a standard C library FILE *, and cannot be used with any functions 
     331                 :  * other than the "VSI*L" family of functions.  They aren't "real" FILE objects.
     332                 :  *
     333                 :  * On windows it is possible to define the configuration option 
     334                 :  * GDAL_FILE_IS_UTF8 to have pszFilename treated as being in the local
     335                 :  * encoding instead of UTF-8, retoring the pre-1.8.0 behavior of VSIFOpenL().
     336                 :  *
     337                 :  * This method goes through the VSIFileHandler virtualization and may
     338                 :  * work on unusual filesystems such as in memory.
     339                 :  *
     340                 :  * Analog of the POSIX fopen() function.
     341                 :  *
     342                 :  * @param pszFilename the file to open.  UTF-8 encoded.
     343                 :  * @param pszAccess access requested (ie. "r", "r+", "w".  
     344                 :  *
     345                 :  * @return NULL on failure, or the file handle.
     346                 :  */
     347                 : 
     348          174067 : VSILFILE *VSIFOpenL( const char * pszFilename, const char * pszAccess )
     349                 : 
     350                 : {
     351                 :     VSIFilesystemHandler *poFSHandler = 
     352          174067 :         VSIFileManager::GetHandler( pszFilename );
     353                 :         
     354          174067 :     VSILFILE* fp = (VSILFILE *) poFSHandler->Open( pszFilename, pszAccess );
     355                 : 
     356                 :     VSIDebug3( "VSIFOpenL(%s,%s) = %p", pszFilename, pszAccess, fp );
     357                 :         
     358          174067 :     return fp;
     359                 : }
     360                 : 
     361                 : /************************************************************************/
     362                 : /*                             VSIFCloseL()                             */
     363                 : /************************************************************************/
     364                 : 
     365                 : /**
     366                 :  * \brief Close file.
     367                 :  *
     368                 :  * This function closes the indicated file.
     369                 :  *
     370                 :  * This method goes through the VSIFileHandler virtualization and may
     371                 :  * work on unusual filesystems such as in memory.
     372                 :  *
     373                 :  * Analog of the POSIX fclose() function.
     374                 :  *
     375                 :  * @param fp file handle opened with VSIFOpenL().
     376                 :  *
     377                 :  * @return 0 on success or -1 on failure.
     378                 :  */
     379                 : 
     380          122585 : int VSIFCloseL( VSILFILE * fp )
     381                 : 
     382                 : {
     383          122585 :     VSIVirtualHandle *poFileHandle = (VSIVirtualHandle *) fp;
     384                 :     
     385                 :     VSIDebug1( "VSICloseL(%p)", fp );
     386                 :     
     387          122585 :     int nResult = poFileHandle->Close();
     388                 :     
     389          122585 :     delete poFileHandle;
     390                 : 
     391          122585 :     return nResult;
     392                 : }
     393                 : 
     394                 : /************************************************************************/
     395                 : /*                             VSIFSeekL()                              */
     396                 : /************************************************************************/
     397                 : 
     398                 : /**
     399                 :  * \brief Seek to requested offset.
     400                 :  *
     401                 :  * Seek to the desired offset (nOffset) in the indicated file. 
     402                 :  *
     403                 :  * This method goes through the VSIFileHandler virtualization and may
     404                 :  * work on unusual filesystems such as in memory.
     405                 :  *
     406                 :  * Analog of the POSIX fseek() call.
     407                 :  *
     408                 :  * @param fp file handle opened with VSIFOpenL(). 
     409                 :  * @param nOffset offset in bytes.
     410                 :  * @param nWhence one of SEEK_SET, SEEK_CUR or SEEK_END.
     411                 :  *
     412                 :  * @return 0 on success or -1 one failure.
     413                 :  */
     414                 : 
     415         6345037 : int VSIFSeekL( VSILFILE * fp, vsi_l_offset nOffset, int nWhence )
     416                 : 
     417                 : {
     418         6345037 :     VSIVirtualHandle *poFileHandle = (VSIVirtualHandle *) fp;
     419                 :     
     420         6345037 :     return poFileHandle->Seek( nOffset, nWhence );
     421                 : }
     422                 : 
     423                 : /************************************************************************/
     424                 : /*                             VSIFTellL()                              */
     425                 : /************************************************************************/
     426                 : 
     427                 : /**
     428                 :  * \brief Tell current file offset.
     429                 :  *
     430                 :  * Returns the current file read/write offset in bytes from the beginning of
     431                 :  * the file. 
     432                 :  *
     433                 :  * This method goes through the VSIFileHandler virtualization and may
     434                 :  * work on unusual filesystems such as in memory.
     435                 :  *
     436                 :  * Analog of the POSIX ftell() call.
     437                 :  *
     438                 :  * @param fp file handle opened with VSIFOpenL(). 
     439                 :  *
     440                 :  * @return file offset in bytes.
     441                 :  */
     442                 : 
     443         2029761 : vsi_l_offset VSIFTellL( VSILFILE * fp )
     444                 : 
     445                 : {
     446         2029761 :     VSIVirtualHandle *poFileHandle = (VSIVirtualHandle *) fp;
     447                 :     
     448         2029761 :     return poFileHandle->Tell();
     449                 : }
     450                 : 
     451                 : /************************************************************************/
     452                 : /*                             VSIRewindL()                             */
     453                 : /************************************************************************/
     454                 : 
     455             966 : void VSIRewindL( VSILFILE * fp )
     456                 : 
     457                 : {
     458             966 :     VSIFSeekL( fp, 0, SEEK_SET );
     459             966 : }
     460                 : 
     461                 : /************************************************************************/
     462                 : /*                             VSIFFlushL()                             */
     463                 : /************************************************************************/
     464                 : 
     465                 : /**
     466                 :  * \brief Flush pending writes to disk.
     467                 :  *
     468                 :  * For files in write or update mode and on filesystem types where it is
     469                 :  * applicable, all pending output on the file is flushed to the physical disk.
     470                 :  *
     471                 :  * This method goes through the VSIFileHandler virtualization and may
     472                 :  * work on unusual filesystems such as in memory.
     473                 :  *
     474                 :  * Analog of the POSIX fflush() call.
     475                 :  *
     476                 :  * @param fp file handle opened with VSIFOpenL(). 
     477                 :  *
     478                 :  * @return 0 on success or -1 on error.
     479                 :  */
     480                 : 
     481            8418 : int VSIFFlushL( VSILFILE * fp )
     482                 : 
     483                 : {
     484            8418 :     VSIVirtualHandle *poFileHandle = (VSIVirtualHandle *) fp;
     485                 :     
     486            8418 :     return poFileHandle->Flush();
     487                 : }
     488                 : 
     489                 : /************************************************************************/
     490                 : /*                             VSIFReadL()                              */
     491                 : /************************************************************************/
     492                 : 
     493                 : /**
     494                 :  * \brief Read bytes from file.
     495                 :  *
     496                 :  * Reads nCount objects of nSize bytes from the indicated file at the
     497                 :  * current offset into the indicated buffer.
     498                 :  *
     499                 :  * This method goes through the VSIFileHandler virtualization and may
     500                 :  * work on unusual filesystems such as in memory.
     501                 :  *
     502                 :  * Analog of the POSIX fread() call.
     503                 :  *
     504                 :  * @param pBuffer the buffer into which the data should be read (at least
     505                 :  * nCount * nSize bytes in size. 
     506                 :  * @param nSize size of objects to read in bytes.
     507                 :  * @param nCount number of objects to read.
     508                 :  * @param fp file handle opened with VSIFOpenL(). 
     509                 :  *
     510                 :  * @return number of objects successfully read. 
     511                 :  */
     512                 : 
     513        13423306 : size_t VSIFReadL( void * pBuffer, size_t nSize, size_t nCount, VSILFILE * fp )
     514                 : 
     515                 : {
     516        13423306 :     VSIVirtualHandle *poFileHandle = (VSIVirtualHandle *) fp;
     517                 :     
     518        13423306 :     return poFileHandle->Read( pBuffer, nSize, nCount );
     519                 : }
     520                 : 
     521                 : 
     522                 : /************************************************************************/
     523                 : /*                       VSIFReadMultiRangeL()                          */
     524                 : /************************************************************************/
     525                 : 
     526                 : /**
     527                 :  * \brief Read several ranges of bytes from file.
     528                 :  *
     529                 :  * Reads nRanges objects of panSizes[i] bytes from the indicated file at the
     530                 :  * offset panOffsets[i] into the buffer ppData[i].
     531                 :  *
     532                 :  * Ranges must be sorted in ascending start offset, and must not overlap each
     533                 :  * other.
     534                 :  *
     535                 :  * This method goes through the VSIFileHandler virtualization and may
     536                 :  * work on unusual filesystems such as in memory or /vsicurl/.
     537                 :  *
     538                 :  * @param nRanges number of ranges to read.
     539                 :  * @param ppData array of nRanges buffer into which the data should be read
     540                 :  *               (ppData[i] must be at list panSizes[i] bytes).
     541                 :  * @param panOffsets array of nRanges offsets at which the data should be read.
     542                 :  * @param panSizes array of nRanges sizes of objects to read (in bytes).
     543                 :  * @param fp file handle opened with VSIFOpenL().
     544                 :  *
     545                 :  * @return 0 in case of success, -1 otherwise.
     546                 :  * @since GDAL 1.9.0
     547                 :  */
     548                 : 
     549               2 : int VSIFReadMultiRangeL( int nRanges, void ** ppData,
     550                 :                          const vsi_l_offset* panOffsets,
     551                 :                          const size_t* panSizes, VSILFILE * fp )
     552                 : {
     553               2 :     VSIVirtualHandle *poFileHandle = (VSIVirtualHandle *) fp;
     554                 : 
     555               2 :     return poFileHandle->ReadMultiRange( nRanges, ppData, panOffsets, panSizes );
     556                 : }
     557                 : 
     558                 : /************************************************************************/
     559                 : /*                             VSIFWriteL()                             */
     560                 : /************************************************************************/
     561                 : 
     562                 : /**
     563                 :  * \brief Write bytes to file.
     564                 :  *
     565                 :  * Writess nCount objects of nSize bytes to the indicated file at the
     566                 :  * current offset into the indicated buffer.
     567                 :  *
     568                 :  * This method goes through the VSIFileHandler virtualization and may
     569                 :  * work on unusual filesystems such as in memory.
     570                 :  *
     571                 :  * Analog of the POSIX fwrite() call.
     572                 :  *
     573                 :  * @param pBuffer the buffer from which the data should be written (at least
     574                 :  * nCount * nSize bytes in size. 
     575                 :  * @param nSize size of objects to read in bytes.
     576                 :  * @param nCount number of objects to read.
     577                 :  * @param fp file handle opened with VSIFOpenL(). 
     578                 :  *
     579                 :  * @return number of objects successfully written.
     580                 :  */
     581                 : 
     582         4793550 : size_t VSIFWriteL( const void *pBuffer, size_t nSize, size_t nCount, VSILFILE *fp )
     583                 : 
     584                 : {
     585         4793550 :     VSIVirtualHandle *poFileHandle = (VSIVirtualHandle *) fp;
     586                 :     
     587         4793550 :     return poFileHandle->Write( pBuffer, nSize, nCount );
     588                 : }
     589                 : 
     590                 : /************************************************************************/
     591                 : /*                              VSIFEofL()                              */
     592                 : /************************************************************************/
     593                 : 
     594                 : /**
     595                 :  * \brief Test for end of file.
     596                 :  *
     597                 :  * Returns TRUE (non-zero) if an end-of-file condition occured during the
     598                 :  * previous read operation. The end-of-file flag is cleared by a successfull
     599                 :  * VSIFSeekL() call.
     600                 :  *
     601                 :  * This method goes through the VSIFileHandler virtualization and may
     602                 :  * work on unusual filesystems such as in memory.
     603                 :  *
     604                 :  * Analog of the POSIX feof() call.
     605                 :  *
     606                 :  * @param fp file handle opened with VSIFOpenL(). 
     607                 :  *
     608                 :  * @return TRUE if at EOF else FALSE.
     609                 :  */
     610                 : 
     611          183932 : int VSIFEofL( VSILFILE * fp )
     612                 : 
     613                 : {
     614          183932 :     VSIVirtualHandle *poFileHandle = (VSIVirtualHandle *) fp;
     615                 :     
     616          183932 :     return poFileHandle->Eof();
     617                 : }
     618                 : 
     619                 : /************************************************************************/
     620                 : /*                            VSIFTruncateL()                           */
     621                 : /************************************************************************/
     622                 : 
     623                 : /**
     624                 :  * \brief Truncate/expand the file to the specified size
     625                 : 
     626                 :  * This method goes through the VSIFileHandler virtualization and may
     627                 :  * work on unusual filesystems such as in memory.
     628                 :  *
     629                 :  * Analog of the POSIX ftruncate() call.
     630                 :  *
     631                 :  * @param fp file handle opened with VSIFOpenL().
     632                 :  * @param nNewSize new size in bytes.
     633                 :  *
     634                 :  * @return 0 on success
     635                 :  * @since GDAL 1.9.0
     636                 :  */
     637                 : 
     638             120 : int VSIFTruncateL( VSILFILE * fp, vsi_l_offset nNewSize )
     639                 : 
     640                 : {
     641             120 :     VSIVirtualHandle *poFileHandle = (VSIVirtualHandle *) fp;
     642                 : 
     643             120 :     return poFileHandle->Truncate(nNewSize);
     644                 : }
     645                 : 
     646                 : /************************************************************************/
     647                 : /*                            VSIFPrintfL()                             */
     648                 : /************************************************************************/
     649                 : 
     650                 : /**
     651                 :  * \brief Formatted write to file.
     652                 :  *
     653                 :  * Provides fprintf() style formatted output to a VSI*L file.  This formats
     654                 :  * an internal buffer which is written using VSIFWriteL(). 
     655                 :  *
     656                 :  * Analog of the POSIX fprintf() call.
     657                 :  *
     658                 :  * @param fp file handle opened with VSIFOpenL(). 
     659                 :  * @param pszFormat the printf style format string. 
     660                 :  * 
     661                 :  * @return the number of bytes written or -1 on an error.
     662                 :  */
     663                 : 
     664           39906 : int VSIFPrintfL( VSILFILE *fp, const char *pszFormat, ... )
     665                 : 
     666                 : {
     667                 :     va_list args;
     668           39906 :     CPLString osResult;
     669                 : 
     670           39906 :     va_start( args, pszFormat );
     671           39906 :     osResult.vPrintf( pszFormat, args );
     672           39906 :     va_end( args );
     673                 : 
     674           39906 :     return VSIFWriteL( osResult.c_str(), 1, osResult.length(), fp );
     675                 : }
     676                 : 
     677                 : /************************************************************************/
     678                 : /*                              VSIFPutcL()                              */
     679                 : /************************************************************************/
     680                 : 
     681             340 : int VSIFPutcL( int nChar, VSILFILE * fp )
     682                 : 
     683                 : {
     684             340 :     unsigned char cChar = (unsigned char)nChar;
     685             340 :     return VSIFWriteL(&cChar, 1, 1, fp);
     686                 : }
     687                 : 
     688                 : /************************************************************************/
     689                 : /* ==================================================================== */
     690                 : /*                           VSIFileManager()                           */
     691                 : /* ==================================================================== */
     692                 : /************************************************************************/
     693                 : 
     694                 : /*
     695                 : ** Notes on Multithreading:
     696                 : **
     697                 : ** The VSIFileManager maintains a list of file type handlers (mem, large
     698                 : ** file, etc).  It should be thread safe as long as all the handlers are
     699                 : ** instantiated before multiple threads begin to operate. 
     700                 : **/
     701                 : 
     702                 : /************************************************************************/
     703                 : /*                           VSIFileManager()                           */
     704                 : /************************************************************************/
     705                 : 
     706            1341 : VSIFileManager::VSIFileManager()
     707                 : 
     708                 : {
     709            1341 :     poDefaultHandler = NULL;
     710            1341 : }
     711                 : 
     712                 : /************************************************************************/
     713                 : /*                          ~VSIFileManager()                           */
     714                 : /************************************************************************/
     715                 : 
     716            1297 : VSIFileManager::~VSIFileManager()
     717                 : {
     718            1297 :     std::map<std::string,VSIFilesystemHandler*>::const_iterator iter;
     719                 : 
     720           14267 :     for( iter = oHandlers.begin();
     721                 :          iter != oHandlers.end();
     722                 :          ++iter )
     723                 :     {
     724           12970 :         delete iter->second;
     725                 :     }
     726                 : 
     727            1297 :     delete poDefaultHandler;
     728            1297 : }
     729                 : 
     730                 : 
     731                 : /************************************************************************/
     732                 : /*                                Get()                                 */
     733                 : /************************************************************************/
     734                 : 
     735                 : static VSIFileManager *poManager = NULL;
     736                 : 
     737          364068 : VSIFileManager *VSIFileManager::Get()
     738                 : 
     739                 : {
     740                 :     
     741          364068 :     if( poManager == NULL )
     742                 :     {
     743            1341 :         poManager = new VSIFileManager;
     744            1341 :         VSIInstallLargeFileHandler();
     745            1341 :         VSIInstallSubFileHandler();
     746            1341 :         VSIInstallMemFileHandler();
     747                 : #ifdef HAVE_LIBZ
     748            1341 :         VSIInstallGZipFileHandler();
     749            1341 :         VSIInstallZipFileHandler();
     750                 : #endif
     751                 : #ifdef HAVE_CURL
     752            1341 :         VSIInstallCurlFileHandler();
     753                 : #endif
     754            1341 :         VSIInstallStdinHandler();
     755            1341 :         VSIInstallStdoutHandler();
     756            1341 :         VSIInstallSparseFileHandler();
     757            1341 :         VSIInstallTarFileHandler();
     758                 :     }
     759                 :     
     760          364068 :     return poManager;
     761                 : }
     762                 : 
     763                 : /************************************************************************/
     764                 : /*                             GetHandler()                             */
     765                 : /************************************************************************/
     766                 : 
     767          349317 : VSIFilesystemHandler *VSIFileManager::GetHandler( const char *pszPath )
     768                 : 
     769                 : {
     770          349317 :     VSIFileManager *poThis = Get();
     771          349317 :     std::map<std::string,VSIFilesystemHandler*>::const_iterator iter;
     772          349317 :     int nPathLen = strlen(pszPath);
     773                 : 
     774         3278943 :     for( iter = poThis->oHandlers.begin();
     775                 :          iter != poThis->oHandlers.end();
     776                 :          ++iter )
     777                 :     {
     778         3001594 :         const char* pszIterKey = iter->first.c_str();
     779         3001594 :         int nIterKeyLen = iter->first.size();
     780         3001594 :         if( strncmp(pszPath,pszIterKey,nIterKeyLen) == 0 )
     781           70906 :             return iter->second;
     782                 : 
     783                 :         /* "/vsimem\foo" should be handled as "/vsimem/foo" */
     784         8075242 :         if (nIterKeyLen && nPathLen > nIterKeyLen &&
     785         2572277 :             pszIterKey[nIterKeyLen-1] == '/' &&
     786         2572277 :             pszPath[nIterKeyLen-1] == '\\' &&
     787                 :             strncmp(pszPath,pszIterKey,nIterKeyLen-1) == 0 )
     788               6 :             return iter->second;
     789                 : 
     790                 :         /* /vsimem should be treated as a match for /vsimem/ */
     791         2930682 :         if( nPathLen == nIterKeyLen - 1
     792                 :             && strncmp(pszPath,pszIterKey,nIterKeyLen-1) == 0 )
     793            1056 :             return iter->second;
     794                 :     }
     795                 :     
     796          277349 :     return poThis->poDefaultHandler;
     797                 : }
     798                 : 
     799                 : /************************************************************************/
     800                 : /*                           InstallHandler()                           */
     801                 : /************************************************************************/
     802                 : 
     803           14751 : void VSIFileManager::InstallHandler( const std::string& osPrefix,
     804                 :                                      VSIFilesystemHandler *poHandler )
     805                 : 
     806                 : {
     807           14751 :     if( osPrefix == "" )
     808            1341 :         Get()->poDefaultHandler = poHandler;
     809                 :     else
     810           13410 :         Get()->oHandlers[osPrefix] = poHandler;
     811           14751 : }
     812                 : 
     813                 : /************************************************************************/
     814                 : /*                       VSICleanupFileManager()                        */
     815                 : /************************************************************************/
     816                 : 
     817            1974 : void VSICleanupFileManager()
     818                 : 
     819                 : {
     820            1974 :     if( poManager )
     821                 :     {
     822            1297 :         delete poManager;
     823            1297 :         poManager = NULL;
     824                 :     }
     825            1974 : }
     826                 : 
     827                 : /************************************************************************/
     828                 : /*                           ReadMultiRange()                           */
     829                 : /************************************************************************/
     830                 : 
     831               0 : int VSIVirtualHandle::ReadMultiRange( int nRanges, void ** ppData,
     832                 :                                       const vsi_l_offset* panOffsets,
     833                 :                                       const size_t* panSizes )
     834                 : {
     835               0 :     int nRet = 0;
     836               0 :     vsi_l_offset nCurOffset = Tell();
     837               0 :     for(int i=0;i<nRanges;i++)
     838                 :     {
     839               0 :         if (Seek(panOffsets[i], SEEK_SET) < 0)
     840                 :         {
     841               0 :             nRet = -1;
     842               0 :             break;
     843                 :         }
     844                 : 
     845               0 :         size_t nRead = Read(ppData[i], 1, panSizes[i]);
     846               0 :         if (panSizes[i] != nRead)
     847                 :         {
     848               0 :             nRet = -1;
     849               0 :             break;
     850                 :         }
     851                 :     }
     852                 : 
     853               0 :     Seek(nCurOffset, SEEK_SET);
     854                 : 
     855               0 :     return nRet;
     856                 : }

Generated by: LCOV version 1.7