LCOV - code coverage report
Current view: directory - port - cpl_vsil.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 107 96 89.7 %
Date: 2010-01-09 Functions: 24 22 91.7 %

       1                 : /******************************************************************************
       2                 :  * $Id: cpl_vsil.cpp 17758 2009-10-05 17:19:23Z 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 17758 2009-10-05 17:19:23Z 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                 :  * @return The list of entries in the directory, or NULL if the directory
      57                 :  * doesn't exist.
      58                 :  */
      59                 : 
      60            5433 : char **VSIReadDir(const char *pszPath)
      61                 : {
      62                 :     VSIFilesystemHandler *poFSHandler = 
      63            5433 :         VSIFileManager::GetHandler( pszPath );
      64                 : 
      65            5433 :     return poFSHandler->ReadDir( pszPath );
      66                 : }
      67                 : 
      68                 : /************************************************************************/
      69                 : /*                             CPLReadDir()                             */
      70                 : /*                                                                      */
      71                 : /*      This is present only to provide ABI compatability with older    */
      72                 : /*      versions.                                                       */
      73                 : /************************************************************************/
      74                 : #undef CPLReadDir
      75                 : 
      76                 : CPL_C_START
      77                 : char CPL_DLL **CPLReadDir( const char *pszPath );
      78                 : CPL_C_END
      79                 : 
      80               0 : char **CPLReadDir( const char *pszPath )
      81                 : {
      82               0 :     return VSIReadDir(pszPath);
      83                 : }
      84                 : 
      85                 : /************************************************************************/
      86                 : /*                              VSIMkdir()                              */
      87                 : /************************************************************************/
      88                 : 
      89                 : /**
      90                 :  * \brief Create a directory. 
      91                 :  * 
      92                 :  * Create a new directory with the indicated mode.  The mode is ignored
      93                 :  * on some platforms.  A reasonable default mode value would be 0666.
      94                 :  * This method goes through the VSIFileHandler virtualization and may
      95                 :  * work on unusual filesystems such as in memory.
      96                 :  *
      97                 :  * Analog of the POSIX mkdir() function.
      98                 :  *
      99                 :  * @param pszPathname the path to the directory to create. 
     100                 :  * @param mode the permissions mode.
     101                 :  *
     102                 :  * @return 0 on success or -1 on an error.
     103                 :  */
     104                 : 
     105              21 : int VSIMkdir( const char *pszPathname, long mode )
     106                 : 
     107                 : {
     108                 :     VSIFilesystemHandler *poFSHandler = 
     109              21 :         VSIFileManager::GetHandler( pszPathname );
     110                 : 
     111              21 :     return poFSHandler->Mkdir( pszPathname, mode );
     112                 : }
     113                 : 
     114                 : /************************************************************************/
     115                 : /*                             VSIUnlink()                              */
     116                 : /*************************a***********************************************/
     117                 : 
     118                 : /**
     119                 :  * \brief Delete a file.
     120                 :  * 
     121                 :  * Deletes a file object from the file system. 
     122                 :  * 
     123                 :  * This method goes through the VSIFileHandler virtualization and may
     124                 :  * work on unusual filesystems such as in memory.
     125                 :  *
     126                 :  * Analog of the POSIX unlink() function.
     127                 :  *
     128                 :  * @param pszFilename the path of the file to be deleted.
     129                 :  *
     130                 :  * @return 0 on success or -1 on an error.
     131                 :  */
     132                 : 
     133            1847 : int VSIUnlink( const char * pszFilename )
     134                 : 
     135                 : {
     136                 :     VSIFilesystemHandler *poFSHandler = 
     137            1847 :         VSIFileManager::GetHandler( pszFilename );
     138                 : 
     139            1847 :     return poFSHandler->Unlink( pszFilename );
     140                 : }
     141                 : 
     142                 : /************************************************************************/
     143                 : /*                             VSIRename()                              */
     144                 : /************************************************************************/
     145                 : 
     146                 : /**
     147                 :  * \brief Rename a file.
     148                 :  * 
     149                 :  * Renames a file object in the file system.  It should be possible
     150                 :  * to rename a file onto a new filesystem, but it is safest if this 
     151                 :  * function is only used to rename files that remain in the same directory.
     152                 :  * 
     153                 :  * This method goes through the VSIFileHandler virtualization and may
     154                 :  * work on unusual filesystems such as in memory.
     155                 :  *
     156                 :  * Analog of the POSIX rename() function.
     157                 :  *
     158                 :  * @param oldpath the name of the file to be renamed.
     159                 :  * @param newpath the name the file should be given. 
     160                 :  *
     161                 :  * @return 0 on success or -1 on an error.
     162                 :  */
     163                 : 
     164               9 : int VSIRename( const char * oldpath, const char * newpath )
     165                 : 
     166                 : {
     167                 :     VSIFilesystemHandler *poFSHandler = 
     168               9 :         VSIFileManager::GetHandler( oldpath );
     169                 : 
     170               9 :     return poFSHandler->Rename( oldpath, newpath );
     171                 : }
     172                 : 
     173                 : /************************************************************************/
     174                 : /*                              VSIRmdir()                              */
     175                 : /************************************************************************/
     176                 : 
     177                 : /**
     178                 :  * \brief Delete a directory.
     179                 :  * 
     180                 :  * Deletes a directory object from the file system.  On some systems
     181                 :  * the directory must be empty before it can be deleted.
     182                 :  * 
     183                 :  * This method goes through the VSIFileHandler virtualization and may
     184                 :  * work on unusual filesystems such as in memory.
     185                 :  *
     186                 :  * Analog of the POSIX rmdir() function.
     187                 :  *
     188                 :  * @param pszDirname the path of the directory to be deleted.
     189                 :  *
     190                 :  * @return 0 on success or -1 on an error.
     191                 :  */
     192                 : 
     193              10 : int VSIRmdir( const char * pszDirname )
     194                 : 
     195                 : {
     196                 :     VSIFilesystemHandler *poFSHandler = 
     197              10 :         VSIFileManager::GetHandler( pszDirname );
     198                 : 
     199              10 :     return poFSHandler->Rmdir( pszDirname );
     200                 : }
     201                 : 
     202                 : /************************************************************************/
     203                 : /*                              VSIStatL()                              */
     204                 : /************************************************************************/
     205                 : 
     206                 : /**
     207                 :  * \brief Get filesystem object info.
     208                 :  * 
     209                 :  * Fetches status information about a filesystem object (file, directory, etc).
     210                 :  * The returned information is placed in the VSIStatBufL structure.   For
     211                 :  * portability only the st_size (size in bytes), and st_mode (file type). 
     212                 :  * This method is similar to VSIStat(), but will work on large files on 
     213                 :  * systems where this requires special calls. 
     214                 :  * 
     215                 :  * This method goes through the VSIFileHandler virtualization and may
     216                 :  * work on unusual filesystems such as in memory.
     217                 :  *
     218                 :  * Analog of the POSIX stat() function.
     219                 :  *
     220                 :  * @param pszFilename the path of the filesystem object to be queried.
     221                 :  * @param psStatBuf the structure to load with information. 
     222                 :  *
     223                 :  * @return 0 on success or -1 on an error.
     224                 :  */
     225                 : 
     226           49936 : int VSIStatL( const char * pszFilename, VSIStatBufL *psStatBuf )
     227                 : 
     228                 : {
     229                 :     char    szAltPath[4];
     230                 :     /* enable to work on "C:" as if it were "C:\" */
     231           49936 :     if( strlen(pszFilename) == 2 && pszFilename[1] == ':' )
     232                 :     {
     233               0 :         szAltPath[0] = pszFilename[0];
     234               0 :         szAltPath[1] = pszFilename[1];
     235               0 :         szAltPath[2] = '\\';
     236               0 :         szAltPath[3] = '\0';
     237                 : 
     238               0 :         pszFilename = szAltPath;
     239                 :     }
     240                 : 
     241                 :     VSIFilesystemHandler *poFSHandler = 
     242           49936 :         VSIFileManager::GetHandler( pszFilename );
     243                 : 
     244           49936 :     return poFSHandler->Stat( pszFilename, psStatBuf );
     245                 : }
     246                 : 
     247                 : /************************************************************************/
     248                 : /*                             VSIFOpenL()                              */
     249                 : /************************************************************************/
     250                 : 
     251                 : /**
     252                 :  * \brief Open file.
     253                 :  *
     254                 :  * This function opens a file with the desired access.  Large files (larger
     255                 :  * than 2GB) should be supported.  Binary access is always implied and
     256                 :  * the "b" does not need to be included in the pszAccess string.
     257                 :  *
     258                 :  * Note that the "FILE *" returned by this function is not really a 
     259                 :  * standard C library FILE *, and cannot be used with any functions other
     260                 :  * than the "VSI*L" family of functions.  They aren't "real" FILE objects.
     261                 :  *
     262                 :  * This method goes through the VSIFileHandler virtualization and may
     263                 :  * work on unusual filesystems such as in memory.
     264                 :  *
     265                 :  * Analog of the POSIX fopen() function.
     266                 :  *
     267                 :  * @param pszFilename the file to open.
     268                 :  * @param pszAccess access requested (ie. "r", "r+", "w".  
     269                 :  *
     270                 :  * @return NULL on failure, or the file handle.
     271                 :  */
     272                 : 
     273           38938 : FILE *VSIFOpenL( const char * pszFilename, const char * pszAccess )
     274                 : 
     275                 : {
     276                 :     VSIFilesystemHandler *poFSHandler = 
     277           38938 :         VSIFileManager::GetHandler( pszFilename );
     278                 :         
     279           38938 :     FILE* fp = (FILE *) poFSHandler->Open( pszFilename, pszAccess );
     280                 : 
     281                 :     VSIDebug3( "VSIFOpenL(%s,%s) = %p", pszFilename, pszAccess, fp );
     282                 :         
     283           38938 :     return fp;
     284                 : }
     285                 : 
     286                 : /************************************************************************/
     287                 : /*                             VSIFCloseL()                             */
     288                 : /************************************************************************/
     289                 : 
     290                 : /**
     291                 :  * \brief Close file.
     292                 :  *
     293                 :  * This function closes the indicated file.
     294                 :  *
     295                 :  * This method goes through the VSIFileHandler virtualization and may
     296                 :  * work on unusual filesystems such as in memory.
     297                 :  *
     298                 :  * Analog of the POSIX fclose() function.
     299                 :  *
     300                 :  * @param fp file handle opened with VSIFOpenL().
     301                 :  *
     302                 :  * @return 0 on success or -1 on failure.
     303                 :  */
     304                 : 
     305           13964 : int VSIFCloseL( FILE * fp )
     306                 : 
     307                 : {
     308           13964 :     VSIVirtualHandle *poFileHandle = (VSIVirtualHandle *) fp;
     309                 :     
     310                 :     VSIDebug1( "VSICloseL(%p)", fp );
     311                 :     
     312           13964 :     int nResult = poFileHandle->Close();
     313                 :     
     314           13964 :     delete poFileHandle;
     315                 : 
     316           13964 :     return nResult;
     317                 : }
     318                 : 
     319                 : /************************************************************************/
     320                 : /*                             VSIFSeekL()                              */
     321                 : /************************************************************************/
     322                 : 
     323                 : /**
     324                 :  * \brief Seek to requested offset.
     325                 :  *
     326                 :  * Seek to the desired offset (nOffset) in the indicated file. 
     327                 :  *
     328                 :  * This method goes through the VSIFileHandler virtualization and may
     329                 :  * work on unusual filesystems such as in memory.
     330                 :  *
     331                 :  * Analog of the POSIX fseek() call.
     332                 :  *
     333                 :  * @param fp file handle opened with VSIFOpenL(). 
     334                 :  * @param nOffset offset in bytes.
     335                 :  * @param nWhence one of SEEK_SET, SEEK_CUR or SEEK_END.
     336                 :  *
     337                 :  * @return 0 on success or -1 one failure.
     338                 :  */
     339                 : 
     340          475699 : int VSIFSeekL( FILE * fp, vsi_l_offset nOffset, int nWhence )
     341                 : 
     342                 : {
     343          475699 :     VSIVirtualHandle *poFileHandle = (VSIVirtualHandle *) fp;
     344                 :     
     345          475699 :     return poFileHandle->Seek( nOffset, nWhence );
     346                 : }
     347                 : 
     348                 : /************************************************************************/
     349                 : /*                             VSIFTellL()                              */
     350                 : /************************************************************************/
     351                 : 
     352                 : /**
     353                 :  * \brief Tell current file offset.
     354                 :  *
     355                 :  * Returns the current file read/write offset in bytes from the beginning of
     356                 :  * the file. 
     357                 :  *
     358                 :  * This method goes through the VSIFileHandler virtualization and may
     359                 :  * work on unusual filesystems such as in memory.
     360                 :  *
     361                 :  * Analog of the POSIX ftell() call.
     362                 :  *
     363                 :  * @param fp file handle opened with VSIFOpenL(). 
     364                 :  *
     365                 :  * @return file offset in bytes.
     366                 :  */
     367                 : 
     368          585824 : vsi_l_offset VSIFTellL( FILE * fp )
     369                 : 
     370                 : {
     371          585824 :     VSIVirtualHandle *poFileHandle = (VSIVirtualHandle *) fp;
     372                 :     
     373          585824 :     return poFileHandle->Tell();
     374                 : }
     375                 : 
     376                 : /************************************************************************/
     377                 : /*                             VSIRewindL()                             */
     378                 : /************************************************************************/
     379                 : 
     380              59 : void VSIRewindL( FILE * fp )
     381                 : 
     382                 : {
     383              59 :     VSIFSeekL( fp, 0, SEEK_SET );
     384              59 : }
     385                 : 
     386                 : /************************************************************************/
     387                 : /*                             VSIFFlushL()                             */
     388                 : /************************************************************************/
     389                 : 
     390                 : /**
     391                 :  * \brief Flush pending writes to disk.
     392                 :  *
     393                 :  * For files in write or update mode and on filesystem types where it is
     394                 :  * applicable, all pending output on the file is flushed to the physical disk.
     395                 :  *
     396                 :  * This method goes through the VSIFileHandler virtualization and may
     397                 :  * work on unusual filesystems such as in memory.
     398                 :  *
     399                 :  * Analog of the POSIX fflush() call.
     400                 :  *
     401                 :  * @param fp file handle opened with VSIFOpenL(). 
     402                 :  *
     403                 :  * @return 0 on success or -1 on error.
     404                 :  */
     405                 : 
     406             527 : int VSIFFlushL( FILE * fp )
     407                 : 
     408                 : {
     409             527 :     VSIVirtualHandle *poFileHandle = (VSIVirtualHandle *) fp;
     410                 :     
     411             527 :     return poFileHandle->Flush();
     412                 : }
     413                 : 
     414                 : /************************************************************************/
     415                 : /*                             VSIFReadL()                              */
     416                 : /************************************************************************/
     417                 : 
     418                 : /**
     419                 :  * \brief Read bytes from file.
     420                 :  *
     421                 :  * Reads nCount objects of nSize bytes from the indicated file at the
     422                 :  * current offset into the indicated buffer.
     423                 :  *
     424                 :  * This method goes through the VSIFileHandler virtualization and may
     425                 :  * work on unusual filesystems such as in memory.
     426                 :  *
     427                 :  * Analog of the POSIX fread() call.
     428                 :  *
     429                 :  * @param pBuffer the buffer into which the data should be read (at least
     430                 :  * nCount * nSize bytes in size. 
     431                 :  * @param nSize size of objects to read in bytes.
     432                 :  * @param nCount number of objects to read.
     433                 :  * @param fp file handle opened with VSIFOpenL(). 
     434                 :  *
     435                 :  * @return number of objects successfully read. 
     436                 :  */
     437                 : 
     438         1289733 : size_t VSIFReadL( void * pBuffer, size_t nSize, size_t nCount, FILE * fp )
     439                 : 
     440                 : {
     441         1289733 :     VSIVirtualHandle *poFileHandle = (VSIVirtualHandle *) fp;
     442                 :     
     443         1289733 :     return poFileHandle->Read( pBuffer, nSize, nCount );
     444                 : }
     445                 : 
     446                 : /************************************************************************/
     447                 : /*                             VSIFWriteL()                             */
     448                 : /************************************************************************/
     449                 : 
     450                 : /**
     451                 :  * \brief Write bytes to file.
     452                 :  *
     453                 :  * Writess nCount objects of nSize bytes to the indicated file at the
     454                 :  * current offset into the indicated buffer.
     455                 :  *
     456                 :  * This method goes through the VSIFileHandler virtualization and may
     457                 :  * work on unusual filesystems such as in memory.
     458                 :  *
     459                 :  * Analog of the POSIX fwrite() call.
     460                 :  *
     461                 :  * @param pBuffer the buffer from which the data should be written (at least
     462                 :  * nCount * nSize bytes in size. 
     463                 :  * @param nSize size of objects to read in bytes.
     464                 :  * @param nCount number of objects to read.
     465                 :  * @param fp file handle opened with VSIFOpenL(). 
     466                 :  *
     467                 :  * @return number of objects successfully written.
     468                 :  */
     469                 : 
     470         1632903 : size_t VSIFWriteL( const void *pBuffer, size_t nSize, size_t nCount, FILE *fp )
     471                 : 
     472                 : {
     473         1632903 :     VSIVirtualHandle *poFileHandle = (VSIVirtualHandle *) fp;
     474                 :     
     475         1632903 :     return poFileHandle->Write( pBuffer, nSize, nCount );
     476                 : }
     477                 : 
     478                 : /************************************************************************/
     479                 : /*                              VSIFEofL()                              */
     480                 : /************************************************************************/
     481                 : 
     482                 : /**
     483                 :  * \brief Test for end of file.
     484                 :  *
     485                 :  * Returns TRUE (non-zero) if the file read/write offset is currently at the
     486                 :  * end of the file. 
     487                 :  *
     488                 :  * This method goes through the VSIFileHandler virtualization and may
     489                 :  * work on unusual filesystems such as in memory.
     490                 :  *
     491                 :  * Analog of the POSIX feof() call.
     492                 :  *
     493                 :  * @param fp file handle opened with VSIFOpenL(). 
     494                 :  *
     495                 :  * @return TRUE if at EOF else FALSE.
     496                 :  */
     497                 : 
     498           44819 : int VSIFEofL( FILE * fp )
     499                 : 
     500                 : {
     501           44819 :     VSIVirtualHandle *poFileHandle = (VSIVirtualHandle *) fp;
     502                 :     
     503           44819 :     return poFileHandle->Eof();
     504                 : }
     505                 : 
     506                 : /************************************************************************/
     507                 : /*                            VSIFPrintfL()                             */
     508                 : /************************************************************************/
     509                 : 
     510                 : /**
     511                 :  * \brief Formatted write to file.
     512                 :  *
     513                 :  * Provides fprintf() style formatted output to a VSI*L file.  This formats
     514                 :  * an internal buffer which is written using VSIFWriteL(). 
     515                 :  *
     516                 :  * Analog of the POSIX fprintf() call.
     517                 :  *
     518                 :  * @param fp file handle opened with VSIFOpenL(). 
     519                 :  * @param pszFormat the printf style format string. 
     520                 :  * 
     521                 :  * @return the number of bytes written or -1 on an error.
     522                 :  */
     523                 : 
     524            3430 : int VSIFPrintfL( FILE *fp, const char *pszFormat, ... )
     525                 : 
     526                 : {
     527                 :     va_list args;
     528            3430 :     CPLString osResult;
     529                 : 
     530            3430 :     va_start( args, pszFormat );
     531            3430 :     osResult.vPrintf( pszFormat, args );
     532            3430 :     va_end( args );
     533                 : 
     534            3430 :     return VSIFWriteL( osResult.c_str(), 1, osResult.length(), fp );
     535                 : }
     536                 : 
     537                 : /************************************************************************/
     538                 : /*                              VSIFPutcL()                              */
     539                 : /************************************************************************/
     540                 : 
     541               0 : int VSIFPutcL( int nChar, FILE * fp )
     542                 : 
     543                 : {
     544               0 :     unsigned char cChar = (unsigned char)nChar;
     545               0 :     return VSIFWriteL(&cChar, 1, 1, fp);
     546                 : }
     547                 : 
     548                 : /************************************************************************/
     549                 : /* ==================================================================== */
     550                 : /*                           VSIFileManager()                           */
     551                 : /* ==================================================================== */
     552                 : /************************************************************************/
     553                 : 
     554                 : /*
     555                 : ** Notes on Multithreading:
     556                 : **
     557                 : ** The VSIFileManager maintains a list of file type handlers (mem, large
     558                 : ** file, etc).  It should be thread safe as long as all the handlers are
     559                 : ** instantiated before multiple threads begin to operate. 
     560                 : **/
     561                 : 
     562                 : /************************************************************************/
     563                 : /*                           VSIFileManager()                           */
     564                 : /************************************************************************/
     565                 : 
     566             379 : VSIFileManager::VSIFileManager()
     567                 : 
     568                 : {
     569             379 :     poDefaultHandler = NULL;
     570             379 : }
     571                 : 
     572                 : /************************************************************************/
     573                 : /*                          ~VSIFileManager()                           */
     574                 : /************************************************************************/
     575                 : 
     576             363 : VSIFileManager::~VSIFileManager()
     577                 : {
     578             363 :     std::map<std::string,VSIFilesystemHandler*>::const_iterator iter;
     579                 : 
     580            1815 :     for( iter = oHandlers.begin();
     581                 :          iter != oHandlers.end();
     582                 :          iter++ )
     583                 :     {
     584            1452 :         delete iter->second;
     585                 :     }
     586                 : 
     587             363 :     delete poDefaultHandler;
     588             363 : }
     589                 : 
     590                 : 
     591                 : /************************************************************************/
     592                 : /*                                Get()                                 */
     593                 : /************************************************************************/
     594                 : 
     595                 : static VSIFileManager *poManager = NULL;
     596                 : 
     597           98305 : VSIFileManager *VSIFileManager::Get()
     598                 : 
     599                 : {
     600                 :     
     601           98305 :     if( poManager == NULL )
     602                 :     {
     603             379 :         poManager = new VSIFileManager;
     604             379 :         VSIInstallLargeFileHandler();
     605             379 :         VSIInstallSubFileHandler();
     606             379 :         VSIInstallMemFileHandler();
     607                 : #ifdef HAVE_LIBZ
     608             379 :         VSIInstallGZipFileHandler();
     609             379 :         VSIInstallZipFileHandler();
     610                 : #endif
     611                 :     }
     612                 :     
     613           98305 :     return poManager;
     614                 : }
     615                 : 
     616                 : /************************************************************************/
     617                 : /*                             GetHandler()                             */
     618                 : /************************************************************************/
     619                 : 
     620           96410 : VSIFilesystemHandler *VSIFileManager::GetHandler( const char *pszPath )
     621                 : 
     622                 : {
     623           96410 :     VSIFileManager *poThis = Get();
     624           96410 :     std::map<std::string,VSIFilesystemHandler*>::const_iterator iter;
     625           96410 :     int nPathLen = strlen(pszPath);
     626                 : 
     627          475627 :     for( iter = poThis->oHandlers.begin();
     628                 :          iter != poThis->oHandlers.end();
     629                 :          iter++ )
     630                 :     {
     631          381558 :         const char* pszIterKey = iter->first.c_str();
     632          381558 :         int nIterKeyLen = iter->first.size();
     633          381558 :         if( strncmp(pszPath,pszIterKey,nIterKeyLen) == 0 )
     634            2341 :             return iter->second;
     635                 : 
     636                 :         /* "/vsimem\foo" should be handled as "/vsimem/foo" */
     637         1037935 :         if (nIterKeyLen && nPathLen > nIterKeyLen &&
     638          329359 :             pszIterKey[nIterKeyLen-1] == '/' &&
     639          329359 :             pszPath[nIterKeyLen-1] == '\\' &&
     640                 :             strncmp(pszPath,pszIterKey,nIterKeyLen-1) == 0 )
     641               0 :             return iter->second;
     642                 :     }
     643                 :     
     644           94069 :     return poThis->poDefaultHandler;
     645                 : }
     646                 : 
     647                 : /************************************************************************/
     648                 : /*                           InstallHandler()                           */
     649                 : /************************************************************************/
     650                 : 
     651            1895 : void VSIFileManager::InstallHandler( const std::string& osPrefix,
     652                 :                                      VSIFilesystemHandler *poHandler )
     653                 : 
     654                 : {
     655            1895 :     if( osPrefix == "" )
     656             379 :         Get()->poDefaultHandler = poHandler;
     657                 :     else
     658            1516 :         Get()->oHandlers[osPrefix] = poHandler;
     659            1895 : }
     660                 : 
     661                 : /************************************************************************/
     662                 : /*                       VSICleanupFileManager()                        */
     663                 : /************************************************************************/
     664                 : 
     665             617 : void VSICleanupFileManager()
     666                 : 
     667                 : {
     668             617 :     if( poManager )
     669                 :     {
     670             363 :         delete poManager;
     671             363 :         poManager = NULL;
     672                 :     }
     673             617 : }

Generated by: LCOV version 1.7