LCOV - code coverage report
Current view: directory - gcore - gdaldrivermanager.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 174 142 81.6 %
Date: 2013-03-30 Functions: 22 18 81.8 %

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

Generated by: LCOV version 1.7