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

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

Generated by: LCOV version 1.7