LCOV - code coverage report
Current view: directory - gcore - gdaldrivermanager.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 165 130 78.8 %
Date: 2011-12-18 Functions: 21 17 81.0 %

       1                 : /******************************************************************************
       2                 :  * $Id: gdaldrivermanager.cpp 23175 2011-10-04 21:28:28Z rouault $
       3                 :  *
       4                 :  * Project:  GDAL Core
       5                 :  * Purpose:  Implementation of GDALDriverManager class.
       6                 :  * Author:   Frank Warmerdam, warmerdam@pobox.com
       7                 :  *
       8                 :  ******************************************************************************
       9                 :  * Copyright (c) 1998, Frank Warmerdam
      10                 :  *
      11                 :  * Permission is hereby granted, free of charge, to any person obtaining a
      12                 :  * copy of this software and associated documentation files (the "Software"),
      13                 :  * to deal in the Software without restriction, including without limitation
      14                 :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      15                 :  * and/or sell copies of the Software, and to permit persons to whom the
      16                 :  * Software is furnished to do so, subject to the following conditions:
      17                 :  *
      18                 :  * The above copyright notice and this permission notice shall be included
      19                 :  * in all copies or substantial portions of the Software.
      20                 :  *
      21                 :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
      22                 :  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      23                 :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
      24                 :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      25                 :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      26                 :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      27                 :  * DEALINGS IN THE SOFTWARE.
      28                 :  ****************************************************************************/
      29                 : 
      30                 : #include "gdal_priv.h"
      31                 : #include "cpl_string.h"
      32                 : #include "cpl_multiproc.h"
      33                 : #include "ogr_srs_api.h"
      34                 : #include "cpl_multiproc.h"
      35                 : #include "gdal_pam.h"
      36                 : 
      37                 : CPL_CVSID("$Id: gdaldrivermanager.cpp 23175 2011-10-04 21:28:28Z rouault $");
      38                 : 
      39                 : static const char *pszUpdatableINST_DATA = 
      40                 : "__INST_DATA_TARGET:                                                                                                                                      ";
      41                 : 
      42                 : /************************************************************************/
      43                 : /* ==================================================================== */
      44                 : /*                           GDALDriverManager                          */
      45                 : /* ==================================================================== */
      46                 : /************************************************************************/
      47                 : 
      48                 : static volatile GDALDriverManager        *poDM = NULL;
      49                 : static void *hDMMutex = NULL;
      50                 : 
      51                 : /************************************************************************/
      52                 : /*                        GetGDALDriverManager()                        */
      53                 : /*                                                                      */
      54                 : /*      A freestanding function to get the only instance of the         */
      55                 : /*      GDALDriverManager.                                              */
      56                 : /************************************************************************/
      57                 : 
      58                 : /**
      59                 :  * \brief Fetch the global GDAL driver manager.
      60                 :  *
      61                 :  * This function fetches the pointer to the singleton global driver manager.
      62                 :  * If the driver manager doesn't exist it is automatically created.
      63                 :  *
      64                 :  * @return pointer to the global driver manager.  This should not be able
      65                 :  * to fail.
      66                 :  */
      67                 : 
      68          162214 : GDALDriverManager * GetGDALDriverManager()
      69                 : 
      70                 : {
      71          162214 :     if( poDM == NULL )
      72                 :     {
      73             537 :         CPLMutexHolderD( &hDMMutex );
      74                 : 
      75             537 :         if( poDM == NULL )
      76             537 :             poDM = new GDALDriverManager();
      77                 :     }
      78                 : 
      79          162214 :     CPLAssert( NULL != poDM );
      80                 : 
      81          162214 :     return const_cast<GDALDriverManager *>( poDM );
      82                 : }
      83                 : 
      84                 : /************************************************************************/
      85                 : /*                         GDALDriverManager()                          */
      86                 : /************************************************************************/
      87                 : 
      88             537 : GDALDriverManager::GDALDriverManager()
      89                 : 
      90                 : {
      91             537 :     nDrivers = 0;
      92             537 :     papoDrivers = NULL;
      93             537 :     pszHome = CPLStrdup("");
      94                 : 
      95             537 :     CPLAssert( poDM == NULL );
      96                 : 
      97                 : /* -------------------------------------------------------------------- */
      98                 : /*      We want to push a location to search for data files             */
      99                 : /*      supporting GDAL/OGR such as EPSG csv files, S-57 definition     */
     100                 : /*      files, and so forth.  The static pszUpdateableINST_DATA         */
     101                 : /*      string can be updated within the shared library or              */
     102                 : /*      executable during an install to point installed data            */
     103                 : /*      directory.  If it isn't burned in here then we use the          */
     104                 : /*      INST_DATA macro (setup at configure time) if                    */
     105                 : /*      available. Otherwise we don't push anything and we hope         */
     106                 : /*      other mechanisms such as environment variables will have        */
     107                 : /*      been employed.                                                  */
     108                 : /* -------------------------------------------------------------------- */
     109             537 :     if( CPLGetConfigOption( "GDAL_DATA", NULL ) != NULL )
     110                 :     {
     111                 :         // this one is picked up automatically by finder initialization.
     112                 :     }
     113               0 :     else if( pszUpdatableINST_DATA[19] != ' ' )
     114                 :     {
     115               0 :         CPLPushFinderLocation( pszUpdatableINST_DATA + 19 );
     116                 :     }
     117                 :     else
     118                 :     {
     119                 : #ifdef INST_DATA
     120               0 :         CPLPushFinderLocation( INST_DATA );
     121                 : #endif
     122                 :     }
     123             537 : }
     124                 : 
     125                 : /************************************************************************/
     126                 : /*                         ~GDALDriverManager()                         */
     127                 : /************************************************************************/
     128                 : 
     129                 : void GDALDatasetPoolPreventDestroy(); /* keep that in sync with gdalproxypool.cpp */
     130                 : void GDALDatasetPoolForceDestroy(); /* keep that in sync with gdalproxypool.cpp */
     131                 : 
     132             522 : GDALDriverManager::~GDALDriverManager()
     133                 : 
     134                 : {
     135                 : /* -------------------------------------------------------------------- */
     136                 : /*      Cleanup any open datasets.                                      */
     137                 : /* -------------------------------------------------------------------- */
     138                 :     int i, nDSCount;
     139                 :     GDALDataset **papoDSList;
     140                 : 
     141                 :     /* First begin by requesting each reamining dataset to drop any reference */
     142                 :     /* to other datasets */
     143                 :     int bHasDroppedRef;
     144                 : 
     145                 :     /* We have to prevent the destroying of the dataset pool during this first */
     146                 :     /* phase, otherwise it cause crashes with a VRT B referencing a VRT A, and if */
     147                 :     /* CloseDependentDatasets() is called first on VRT A. */
     148                 :     /* If we didn't do this nasty trick, due to the refCountOfDisableRefCount */
     149                 :     /* mechanism that cheats the real refcount of the dataset pool, we might */
     150                 :     /* destroy the dataset pool too early, leading the VRT A to */
     151                 :     /* destroy itself indirectly ... Ok, I am aware this explanation does */
     152                 :     /* not make any sense unless you try it under a debugger ... */
     153                 :     /* When people just manipulate "top-level" dataset handles, we luckily */
     154                 :     /* don't need this horrible hack, but GetOpenDatasets() expose "low-level" */
     155                 :     /* datasets, which defeat some "design" of the proxy pool */
     156             522 :     GDALDatasetPoolPreventDestroy();
     157                 : 
     158             522 :     do
     159                 :     {
     160             522 :         papoDSList = GDALDataset::GetOpenDatasets(&nDSCount);
     161                 :         /* If a dataset has dropped a reference, the list might have become */
     162                 :         /* invalid, so go out of the loop and try again with the new valid */
     163                 :         /* list */
     164             522 :         bHasDroppedRef = FALSE;
     165             524 :         for(i=0;i<nDSCount && !bHasDroppedRef;i++)
     166                 :         {
     167                 :             //CPLDebug("GDAL", "Call CloseDependentDatasets() on %s",
     168                 :             //      papoDSList[i]->GetDescription() );
     169               2 :             bHasDroppedRef = papoDSList[i]->CloseDependentDatasets();
     170                 :         }
     171                 :     } while(bHasDroppedRef);
     172                 : 
     173                 :     /* Now let's destroy the dataset pool. Nobody shoud use it afterwards */
     174                 :     /* if people have well released their dependent datasets above */
     175             522 :     GDALDatasetPoolForceDestroy();
     176                 : 
     177                 :     /* Now close the stand-alone datasets */
     178             522 :     papoDSList = GDALDataset::GetOpenDatasets(&nDSCount);
     179             524 :     for(i=0;i<nDSCount;i++)
     180                 :     {
     181                 :         CPLDebug( "GDAL", "force close of %s in GDALDriverManager cleanup.",
     182               2 :                   papoDSList[i]->GetDescription() );
     183                 :         /* Destroy with delete operator rather than GDALClose() to force deletion of */
     184                 :         /* datasets with multiple reference count */
     185                 :         /* We could also iterate while GetOpenDatasets() returns a non NULL list */
     186               2 :         delete papoDSList[i];
     187                 :     }
     188                 : 
     189                 : /* -------------------------------------------------------------------- */
     190                 : /*      Destroy the existing drivers.                                   */
     191                 : /* -------------------------------------------------------------------- */
     192           65249 :     while( GetDriverCount() > 0 )
     193                 :     {
     194           64205 :         GDALDriver      *poDriver = GetDriver(0);
     195                 : 
     196           64205 :         DeregisterDriver(poDriver);
     197           64205 :         delete poDriver;
     198                 :     }
     199                 : 
     200                 : /* -------------------------------------------------------------------- */
     201                 : /*      Cleanup local memory.                                           */
     202                 : /* -------------------------------------------------------------------- */
     203             522 :     VSIFree( papoDrivers );
     204             522 :     VSIFree( pszHome );
     205                 : 
     206                 : /* -------------------------------------------------------------------- */
     207                 : /*      Cleanup any Proxy related memory.                               */
     208                 : /* -------------------------------------------------------------------- */
     209             522 :     PamCleanProxyDB();
     210                 : 
     211                 : /* -------------------------------------------------------------------- */
     212                 : /*      Blow away all the finder hints paths.  We really shouldn't      */
     213                 : /*      be doing all of them, but it is currently hard to keep track    */
     214                 : /*      of those that actually belong to us.                            */
     215                 : /* -------------------------------------------------------------------- */
     216             522 :     CPLFinderClean();
     217             522 :     CPLFreeConfig();
     218                 : 
     219                 : /* -------------------------------------------------------------------- */
     220                 : /*      Cleanup any memory allocated by the OGRSpatialReference         */
     221                 : /*      related subsystem.                                              */
     222                 : /* -------------------------------------------------------------------- */
     223             522 :     OSRCleanup();
     224                 : 
     225                 : /* -------------------------------------------------------------------- */
     226                 : /*      Cleanup VSIFileManager.                                         */
     227                 : /* -------------------------------------------------------------------- */
     228             522 :     VSICleanupFileManager();
     229                 : 
     230                 : /* -------------------------------------------------------------------- */
     231                 : /*      Cleanup thread local storage ... I hope the program is all      */
     232                 : /*      done with GDAL/OGR!                                             */
     233                 : /* -------------------------------------------------------------------- */
     234             522 :     CPLCleanupTLS();
     235                 : 
     236                 : /* -------------------------------------------------------------------- */
     237                 : /*      Cleanup our mutex.                                              */
     238                 : /* -------------------------------------------------------------------- */
     239             522 :     if( hDMMutex )
     240                 :     {
     241             522 :         CPLDestroyMutex( hDMMutex );
     242             522 :         hDMMutex = NULL;
     243                 :     }
     244                 : 
     245                 : /* -------------------------------------------------------------------- */
     246                 : /*      Ensure the global driver manager pointer is NULLed out.         */
     247                 : /* -------------------------------------------------------------------- */
     248             522 :     if( poDM == this )
     249             522 :         poDM = NULL;
     250             522 : }
     251                 : 
     252                 : /************************************************************************/
     253                 : /*                           GetDriverCount()                           */
     254                 : /************************************************************************/
     255                 : 
     256                 : /**
     257                 :  * \brief Fetch the number of registered drivers.
     258                 :  *
     259                 :  * This C analog to this is GDALGetDriverCount().
     260                 :  *
     261                 :  * @return the number of registered drivers.
     262                 :  */
     263                 : 
     264         1515810 : int GDALDriverManager::GetDriverCount()
     265                 : 
     266                 : {
     267         1515810 :     return( nDrivers );
     268                 : }
     269                 : 
     270                 : /************************************************************************/
     271                 : /*                         GDALGetDriverCount()                         */
     272                 : /************************************************************************/
     273                 : 
     274                 : /**
     275                 :  * \brief Fetch the number of registered drivers.
     276                 :  *
     277                 :  * @see GDALDriverManager::GetDriverCount()
     278                 :  */
     279                 : 
     280             371 : int CPL_STDCALL GDALGetDriverCount()
     281                 : 
     282                 : {
     283             371 :     return GetGDALDriverManager()->GetDriverCount();
     284                 : }
     285                 : 
     286                 : /************************************************************************/
     287                 : /*                             GetDriver()                              */
     288                 : /************************************************************************/
     289                 : 
     290                 : /**
     291                 :  * \brief Fetch driver by index.
     292                 :  *
     293                 :  * This C analog to this is GDALGetDriver().
     294                 :  *
     295                 :  * @param iDriver the driver index from 0 to GetDriverCount()-1.
     296                 :  *
     297                 :  * @return the driver identified by the index or NULL if the index is invalid
     298                 :  */
     299                 : 
     300         1507582 : GDALDriver * GDALDriverManager::GetDriver( int iDriver )
     301                 : 
     302                 : {
     303         1507582 :     CPLMutexHolderD( &hDMMutex );
     304                 : 
     305         1507582 :     if( iDriver < 0 || iDriver >= nDrivers )
     306               0 :         return NULL;
     307                 :     else
     308         1507582 :         return papoDrivers[iDriver];
     309                 : }
     310                 : 
     311                 : /************************************************************************/
     312                 : /*                           GDALGetDriver()                            */
     313                 : /************************************************************************/
     314                 : 
     315                 : /**
     316                 :  * \brief Fetch driver by index.
     317                 :  *
     318                 :  * @see GDALDriverManager::GetDriver()
     319                 :  */
     320                 : 
     321            3051 : GDALDriverH CPL_STDCALL GDALGetDriver( int iDriver )
     322                 : 
     323                 : {
     324            3051 :     return (GDALDriverH) GetGDALDriverManager()->GetDriver(iDriver);
     325                 : }
     326                 : 
     327                 : /************************************************************************/
     328                 : /*                           RegisterDriver()                           */
     329                 : /************************************************************************/
     330                 : 
     331                 : /**
     332                 :  * \brief Register a driver for use.
     333                 :  *
     334                 :  * The C analog is GDALRegisterDriver().
     335                 :  *
     336                 :  * Normally this method is used by format specific C callable registration
     337                 :  * entry points such as GDALRegister_GTiff() rather than being called
     338                 :  * directly by application level code.
     339                 :  *
     340                 :  * If this driver (based on the object pointer, not short name) is already
     341                 :  * registered, then no change is made, and the index of the existing driver
     342                 :  * is returned.  Otherwise the driver list is extended, and the new driver
     343                 :  * is added at the end.
     344                 :  *
     345                 :  * @param poDriver the driver to register.
     346                 :  *
     347                 :  * @return the index of the new installed driver.
     348                 :  */
     349                 : 
     350           66127 : int GDALDriverManager::RegisterDriver( GDALDriver * poDriver )
     351                 : 
     352                 : {
     353           66127 :     CPLMutexHolderD( &hDMMutex );
     354                 : 
     355                 : /* -------------------------------------------------------------------- */
     356                 : /*      If it is already registered, just return the existing           */
     357                 : /*      index.                                                          */
     358                 : /* -------------------------------------------------------------------- */
     359           66127 :     if( GetDriverByName( poDriver->GetDescription() ) != NULL )
     360                 :     {
     361                 :         int             i;
     362                 : 
     363             363 :         for( i = 0; i < nDrivers; i++ )
     364                 :         {
     365             363 :             if( papoDrivers[i] == poDriver )
     366                 :             {
     367               3 :                 return i;
     368                 :             }
     369                 :         }
     370                 : 
     371               0 :         CPLAssert( FALSE );
     372                 :     }
     373                 :     
     374                 : /* -------------------------------------------------------------------- */
     375                 : /*      Otherwise grow the list to hold the new entry.                  */
     376                 : /* -------------------------------------------------------------------- */
     377                 :     papoDrivers = (GDALDriver **)
     378           66124 :         VSIRealloc(papoDrivers, sizeof(GDALDriver *) * (nDrivers+1));
     379                 : 
     380           66124 :     papoDrivers[nDrivers] = poDriver;
     381           66124 :     nDrivers++;
     382                 : 
     383           66124 :     if( poDriver->pfnCreate != NULL )
     384           18811 :         poDriver->SetMetadataItem( GDAL_DCAP_CREATE, "YES" );
     385                 :     
     386           66124 :     if( poDriver->pfnCreateCopy != NULL )
     387           21533 :         poDriver->SetMetadataItem( GDAL_DCAP_CREATECOPY, "YES" );
     388                 : 
     389           66124 :     int iResult = nDrivers - 1;
     390                 : 
     391           66124 :     return iResult;
     392                 : }
     393                 : 
     394                 : /************************************************************************/
     395                 : /*                         GDALRegisterDriver()                         */
     396                 : /************************************************************************/
     397                 : 
     398                 : /**
     399                 :  * \brief Register a driver for use.
     400                 :  *
     401                 :  * @see GDALDriverManager::GetRegisterDriver()
     402                 :  */
     403                 : 
     404              75 : int CPL_STDCALL GDALRegisterDriver( GDALDriverH hDriver )
     405                 : 
     406                 : {
     407              75 :     VALIDATE_POINTER1( hDriver, "GDALRegisterDriver", 0 );
     408                 : 
     409              75 :     return GetGDALDriverManager()->RegisterDriver( (GDALDriver *) hDriver );
     410                 : }
     411                 : 
     412                 : 
     413                 : /************************************************************************/
     414                 : /*                          DeregisterDriver()                          */
     415                 : /************************************************************************/
     416                 : 
     417                 : /**
     418                 :  * \brief Deregister the passed driver.
     419                 :  *
     420                 :  * If the driver isn't found no change is made.
     421                 :  *
     422                 :  * The C analog is GDALDeregisterDriver().
     423                 :  *
     424                 :  * @param poDriver the driver to deregister.
     425                 :  */
     426                 : 
     427           64279 : void GDALDriverManager::DeregisterDriver( GDALDriver * poDriver )
     428                 : 
     429                 : {
     430                 :     int         i;
     431           64279 :     CPLMutexHolderD( &hDMMutex );
     432                 : 
     433           72602 :     for( i = 0; i < nDrivers; i++ )
     434                 :     {
     435           72602 :         if( papoDrivers[i] == poDriver )
     436           64279 :             break;
     437                 :     }
     438                 : 
     439           64279 :     if( i == nDrivers )
     440                 :         return;
     441                 : 
     442         4045711 :     while( i < nDrivers-1 )
     443                 :     {
     444         3917153 :         papoDrivers[i] = papoDrivers[i+1];
     445         3917153 :         i++;
     446                 :     }
     447           64279 :     nDrivers--;
     448                 : }
     449                 : 
     450                 : /************************************************************************/
     451                 : /*                        GDALDeregisterDriver()                        */
     452                 : /************************************************************************/
     453                 : 
     454                 : /**
     455                 :  * \brief Deregister the passed driver.
     456                 :  *
     457                 :  * @see GDALDriverManager::GetDeregisterDriver()
     458                 :  */
     459                 : 
     460              72 : void CPL_STDCALL GDALDeregisterDriver( GDALDriverH hDriver )
     461                 : 
     462                 : {
     463              72 :     VALIDATE_POINTER0( hDriver, "GDALDeregisterDriver" );
     464                 : 
     465              72 :     GetGDALDriverManager()->DeregisterDriver( (GDALDriver *) hDriver );
     466                 : }
     467                 : 
     468                 : 
     469                 : /************************************************************************/
     470                 : /*                          GetDriverByName()                           */
     471                 : /************************************************************************/
     472                 : 
     473                 : /**
     474                 :  * \brief Fetch a driver based on the short name.
     475                 :  *
     476                 :  * The C analog is the GDALGetDriverByName() function.
     477                 :  *
     478                 :  * @param pszName the short name, such as GTiff, being searched for.
     479                 :  *
     480                 :  * @return the identified driver, or NULL if no match is found.
     481                 :  */
     482                 : 
     483          139817 : GDALDriver * GDALDriverManager::GetDriverByName( const char * pszName )
     484                 : 
     485                 : {
     486                 :     int         i;
     487                 : 
     488          139817 :     CPLMutexHolderD( &hDMMutex );
     489                 : 
     490         8470818 :     for( i = 0; i < nDrivers; i++ )
     491                 :     {
     492         8338603 :         if( EQUAL(papoDrivers[i]->GetDescription(), pszName) )
     493            7602 :             return papoDrivers[i];
     494                 :     }
     495                 : 
     496          132215 :     return NULL;
     497                 : }
     498                 : 
     499                 : /************************************************************************/
     500                 : /*                        GDALGetDriverByName()                         */
     501                 : /************************************************************************/
     502                 : 
     503                 : /**
     504                 :  * \brief Fetch a driver based on the short name.
     505                 :  *
     506                 :  * @see GDALDriverManager::GetDriverByName()
     507                 :  */
     508                 : 
     509           73639 : GDALDriverH CPL_STDCALL GDALGetDriverByName( const char * pszName )
     510                 : 
     511                 : {
     512           73639 :     VALIDATE_POINTER1( pszName, "GDALGetDriverByName", NULL );
     513                 : 
     514           73639 :     return( GetGDALDriverManager()->GetDriverByName( pszName ) );
     515                 : }
     516                 : 
     517                 : /************************************************************************/
     518                 : /*                              GetHome()                               */
     519                 : /************************************************************************/
     520                 : 
     521             558 : const char *GDALDriverManager::GetHome()
     522                 : 
     523                 : {
     524             558 :     return pszHome;
     525                 : }
     526                 : 
     527                 : /************************************************************************/
     528                 : /*                              SetHome()                               */
     529                 : /************************************************************************/
     530                 : 
     531               0 : void GDALDriverManager::SetHome( const char * pszNewHome )
     532                 : 
     533                 : {
     534               0 :     CPLMutexHolderD( &hDMMutex );
     535                 : 
     536               0 :     CPLFree( pszHome );
     537               0 :     pszHome = CPLStrdup(pszNewHome);
     538               0 : }
     539                 : 
     540                 : /************************************************************************/
     541                 : /*                          AutoSkipDrivers()                           */
     542                 : /************************************************************************/
     543                 : 
     544                 : /**
     545                 :  * \brief This method unload undesirable drivers.
     546                 :  *
     547                 :  * All drivers specified in the space delimited list in the GDAL_SKIP 
     548                 :  * environment variable) will be deregistered and destroyed.  This method 
     549                 :  * should normally be called after registration of standard drivers to allow 
     550                 :  * the user a way of unloading undesired drivers.  The GDALAllRegister()
     551                 :  * function already invokes AutoSkipDrivers() at the end, so if that functions
     552                 :  * is called, it should not be necessary to call this method from application
     553                 :  * code. 
     554                 :  */
     555                 : 
     556             558 : void GDALDriverManager::AutoSkipDrivers()
     557                 : 
     558                 : {
     559             558 :     if( CPLGetConfigOption( "GDAL_SKIP", NULL ) == NULL )
     560             557 :         return;
     561                 : 
     562               1 :     char **papszList = CSLTokenizeString( CPLGetConfigOption("GDAL_SKIP","") );
     563                 : 
     564               4 :     for( int i = 0; i < CSLCount(papszList); i++ )
     565                 :     {
     566               3 :         GDALDriver *poDriver = GetDriverByName( papszList[i] );
     567                 : 
     568               3 :         if( poDriver == NULL )
     569                 :             CPLError( CE_Warning, CPLE_AppDefined, 
     570                 :                       "Unable to find driver %s to unload from GDAL_SKIP environment variable.", 
     571               1 :                       papszList[i] );
     572                 :         else
     573                 :         {
     574               2 :             CPLDebug( "GDAL", "AutoSkipDriver(%s)", papszList[i] );
     575               2 :             DeregisterDriver( poDriver );
     576               2 :             delete poDriver;
     577                 :         }
     578                 :     }
     579                 : 
     580               1 :     CSLDestroy( papszList );
     581                 : }
     582                 : 
     583                 : /************************************************************************/
     584                 : /*                          AutoLoadDrivers()                           */
     585                 : /************************************************************************/
     586                 : 
     587                 : /**
     588                 :  * \brief Auto-load GDAL drivers from shared libraries.
     589                 :  *
     590                 :  * This function will automatically load drivers from shared libraries.  It
     591                 :  * searches the "driver path" for .so (or .dll) files that start with the
     592                 :  * prefix "gdal_X.so".  It then tries to load them and then tries to call a
     593                 :  * function within them called GDALRegister_X() where the 'X' is the same as
     594                 :  * the remainder of the shared library basename ('X' is case sensitive), or
     595                 :  * failing that to call GDALRegisterMe().
     596                 :  *
     597                 :  * There are a few rules for the driver path.  If the GDAL_DRIVER_PATH
     598                 :  * environment variable it set, it is taken to be a list of directories to
     599                 :  * search separated by colons on UNIX, or semi-colons on Windows.  Otherwise
     600                 :  * the /usr/local/lib/gdalplugins directory, and (if known) the
     601                 :  * lib/gdalplugins subdirectory of the gdal home directory are searched on
     602                 :  * UNIX and $(BINDIR)\gdalplugins on Windows.
     603                 :  */
     604                 : 
     605             558 : void GDALDriverManager::AutoLoadDrivers()
     606                 : 
     607                 : {
     608             558 :     char     **papszSearchPath = NULL;
     609                 :     const char *pszGDAL_DRIVER_PATH = 
     610             558 :         CPLGetConfigOption( "GDAL_DRIVER_PATH", NULL );
     611                 : 
     612                 : /* -------------------------------------------------------------------- */
     613                 : /*      Where should we look for stuff?                                 */
     614                 : /* -------------------------------------------------------------------- */
     615             558 :     if( pszGDAL_DRIVER_PATH != NULL )
     616                 :     {
     617                 : #ifdef WIN32
     618                 :         papszSearchPath = 
     619                 :             CSLTokenizeStringComplex( pszGDAL_DRIVER_PATH, ";", TRUE, FALSE );
     620                 : #else
     621                 :         papszSearchPath = 
     622               0 :             CSLTokenizeStringComplex( pszGDAL_DRIVER_PATH, ":", TRUE, FALSE );
     623                 : #endif
     624                 :     }
     625                 :     else
     626                 :     {
     627                 : #ifdef GDAL_PREFIX
     628                 :         papszSearchPath = CSLAddString( papszSearchPath, 
     629                 :     #ifdef MACOSX_FRAMEWORK
     630                 :                                         GDAL_PREFIX "/PlugIns");
     631                 :     #else
     632             558 :                                         GDAL_PREFIX "/lib/gdalplugins" );
     633                 :     #endif
     634                 : #else
     635                 :         char szExecPath[1024];
     636                 : 
     637                 :         if( CPLGetExecPath( szExecPath, sizeof(szExecPath) ) )
     638                 :         {
     639                 :             char szPluginDir[sizeof(szExecPath)+50];
     640                 :             strcpy( szPluginDir, CPLGetDirname( szExecPath ) );
     641                 :             strcat( szPluginDir, "\\gdalplugins" );
     642                 :             papszSearchPath = CSLAddString( papszSearchPath, szPluginDir );
     643                 :         }
     644                 :         else
     645                 :         {
     646                 :             papszSearchPath = CSLAddString( papszSearchPath, 
     647                 :                                             "/usr/local/lib/gdalplugins" );
     648                 :         }
     649                 : #endif
     650                 : 
     651                 :    #ifdef MACOSX_FRAMEWORK
     652                 :    #define num2str(x) str(x)
     653                 :    #define str(x) #x 
     654                 :      papszSearchPath = CSLAddString( papszSearchPath, 
     655                 :                                      "/Library/Application Support/GDAL/"
     656                 :                                      num2str(GDAL_VERSION_MAJOR) "."  
     657                 :                                      num2str(GDAL_VERSION_MINOR) "/PlugIns" );
     658                 :    #endif
     659                 : 
     660                 : 
     661             558 :         if( strlen(GetHome()) > 0 )
     662                 :         {
     663                 :             papszSearchPath = CSLAddString( papszSearchPath, 
     664                 :                                   CPLFormFilename( GetHome(),
     665                 :     #ifdef MACOSX_FRAMEWORK 
     666                 :                                      "/Library/Application Support/GDAL/"
     667                 :                                      num2str(GDAL_VERSION_MAJOR) "."  
     668                 :                                      num2str(GDAL_VERSION_MINOR) "/PlugIns", NULL ) );
     669                 :     #else
     670               0 :                                                     "lib/gdalplugins", NULL ) );
     671                 :     #endif                                           
     672                 :         }
     673                 :     }
     674                 : 
     675                 : /* -------------------------------------------------------------------- */
     676                 : /*      Format the ABI version specific subdirectory to look in.        */
     677                 : /* -------------------------------------------------------------------- */
     678             558 :     CPLString osABIVersion;
     679                 : 
     680             558 :     osABIVersion.Printf( "%d.%d", GDAL_VERSION_MAJOR, GDAL_VERSION_MINOR );
     681                 : 
     682                 : /* -------------------------------------------------------------------- */
     683                 : /*      Scan each directory looking for files starting with gdal_       */
     684                 : /* -------------------------------------------------------------------- */
     685            1116 :     for( int iDir = 0; iDir < CSLCount(papszSearchPath); iDir++ )
     686                 :     {
     687             558 :         char **papszFiles = NULL;
     688                 :         VSIStatBufL sStatBuf;
     689                 :         CPLString osABISpecificDir =
     690             558 :             CPLFormFilename( papszSearchPath[iDir], osABIVersion, NULL );
     691                 :         
     692             558 :         if( VSIStatL( osABISpecificDir, &sStatBuf ) != 0 )
     693             558 :             osABISpecificDir = papszSearchPath[iDir];
     694                 : 
     695             558 :         papszFiles = CPLReadDir( osABISpecificDir );
     696                 : 
     697             558 :         for( int iFile = 0; iFile < CSLCount(papszFiles); iFile++ )
     698                 :         {
     699                 :             char   *pszFuncName;
     700                 :             const char *pszFilename;
     701               0 :             const char *pszExtension = CPLGetExtension( papszFiles[iFile] );
     702                 :             void   *pRegister;
     703                 : 
     704               0 :             if( !EQUALN(papszFiles[iFile],"gdal_",5) )
     705               0 :                 continue;
     706                 : 
     707               0 :             if( !EQUAL(pszExtension,"dll") 
     708                 :                 && !EQUAL(pszExtension,"so") 
     709                 :                 && !EQUAL(pszExtension,"dylib") )
     710               0 :                 continue;
     711                 : 
     712               0 :             pszFuncName = (char *) CPLCalloc(strlen(papszFiles[iFile])+20,1);
     713                 :             sprintf( pszFuncName, "GDALRegister_%s", 
     714               0 :                      CPLGetBasename(papszFiles[iFile]) + 5 );
     715                 :             
     716                 :             pszFilename = 
     717                 :                 CPLFormFilename( osABISpecificDir, 
     718               0 :                                  papszFiles[iFile], NULL );
     719                 : 
     720               0 :             CPLErrorReset();
     721               0 :             CPLPushErrorHandler(CPLQuietErrorHandler);
     722               0 :             pRegister = CPLGetSymbol( pszFilename, pszFuncName );
     723               0 :             CPLPopErrorHandler();
     724               0 :             if( pRegister == NULL )
     725                 :             {
     726               0 :                 CPLString osLastErrorMsg(CPLGetLastErrorMsg());
     727               0 :                 strcpy( pszFuncName, "GDALRegisterMe" );
     728               0 :                 pRegister = CPLGetSymbol( pszFilename, pszFuncName );
     729               0 :                 if( pRegister == NULL )
     730                 :                 {
     731                 :                     CPLError( CE_Failure, CPLE_AppDefined,
     732               0 :                               "%s", osLastErrorMsg.c_str() );
     733               0 :                 }
     734                 :             }
     735                 :             
     736               0 :             if( pRegister != NULL )
     737                 :             {
     738                 :                 CPLDebug( "GDAL", "Auto register %s using %s.", 
     739               0 :                           pszFilename, pszFuncName );
     740                 : 
     741               0 :                 ((void (*)()) pRegister)();
     742                 :             }
     743                 : 
     744               0 :             CPLFree( pszFuncName );
     745                 :         }
     746                 : 
     747             558 :         CSLDestroy( papszFiles );
     748                 :     }
     749                 : 
     750             558 :     CSLDestroy( papszSearchPath );
     751             558 : }
     752                 : 
     753                 : /************************************************************************/
     754                 : /*                      GDALDestroyDriverManager()                      */
     755                 : /************************************************************************/
     756                 : 
     757                 : /**
     758                 :  * \brief Destroy the driver manager.
     759                 :  *
     760                 :  * Incidently unloads all managed drivers.
     761                 :  *
     762                 :  * NOTE: This function is not thread safe.  It should not be called while
     763                 :  * other threads are actively using GDAL. 
     764                 :  */
     765                 : 
     766             522 : void CPL_STDCALL GDALDestroyDriverManager( void )
     767                 : 
     768                 : {
     769                 :     // THREADSAFETY: We would like to lock the mutex here, but it 
     770                 :     // needs to be reacquired within the destructor during driver
     771                 :     // deregistration.
     772             522 :     if( poDM != NULL )
     773             522 :         delete poDM;
     774             522 : }
     775                 : 
     776                 : 

Generated by: LCOV version 1.7