LCOV - code coverage report
Current view: directory - ogr/ogrsf_frmts/generic - ogrsfdriverregistrar.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 235 187 79.6 %
Date: 2010-01-09 Functions: 22 20 90.9 %

       1                 : /******************************************************************************
       2                 :  * $Id: ogrsfdriverregistrar.cpp 18462 2010-01-07 19:31:11Z rouault $
       3                 :  *
       4                 :  * Project:  OpenGIS Simple Features Reference Implementation
       5                 :  * Purpose:  The OGRSFDriverRegistrar class implementation.
       6                 :  * Author:   Frank Warmerdam, warmerdam@pobox.com
       7                 :  *
       8                 :  ******************************************************************************
       9                 :  * Copyright (c) 1999,  Les Technologies SoftMap Inc.
      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 "ogrsf_frmts.h"
      31                 : #include "ogr_api.h"
      32                 : #include "ogr_p.h"
      33                 : #include "cpl_multiproc.h"
      34                 : 
      35                 : CPL_CVSID("$Id: ogrsfdriverregistrar.cpp 18462 2010-01-07 19:31:11Z rouault $");
      36                 : 
      37                 : static void *hDRMutex = NULL;
      38                 : static OGRSFDriverRegistrar * volatile poRegistrar = NULL;
      39                 : 
      40                 : static const char *pszUpdatableINST_DATA = 
      41                 : "__INST_DATA_TARGET:                                                                                                                                      ";
      42                 : /************************************************************************/
      43                 : /*                         OGRSFDriverRegistrar                         */
      44                 : /************************************************************************/
      45                 : 
      46                 : /**
      47                 :  * \brief Constructor
      48                 :  *
      49                 :  * Normally the driver registrar is constucted by the 
      50                 :  * OGRSFDriverRegistrar::GetRegistrar() accessor which ensures singleton
      51                 :  * status.  
      52                 :  */
      53                 : 
      54              64 : OGRSFDriverRegistrar::OGRSFDriverRegistrar()
      55                 : 
      56                 : {
      57                 :     CPLAssert( poRegistrar == NULL );
      58              64 :     nDrivers = 0;
      59              64 :     papoDrivers = NULL;
      60                 : 
      61              64 :     nOpenDSCount = 0;
      62              64 :     papszOpenDSRawName = NULL;
      63              64 :     papoOpenDS = NULL;
      64              64 :     papoOpenDSDriver = NULL;
      65              64 :     panOpenDSPID = NULL;
      66                 : 
      67                 : /* -------------------------------------------------------------------- */
      68                 : /*      We want to push a location to search for data files             */
      69                 : /*      supporting GDAL/OGR such as EPSG csv files, S-57 definition     */
      70                 : /*      files, and so forth.  The static pszUpdateableINST_DATA         */
      71                 : /*      string can be updated within the shared library or              */
      72                 : /*      executable during an install to point installed data            */
      73                 : /*      directory.  If it isn't burned in here then we use the          */
      74                 : /*      INST_DATA macro (setup at configure time) if                    */
      75                 : /*      available. Otherwise we don't push anything and we hope         */
      76                 : /*      other mechanisms such as environment variables will have        */
      77                 : /*      been employed.                                                  */
      78                 : /* -------------------------------------------------------------------- */
      79              64 :     if( CPLGetConfigOption( "GDAL_DATA", NULL ) != NULL )
      80                 :     {
      81              64 :         CPLPushFinderLocation( CPLGetConfigOption( "GDAL_DATA", NULL ) );
      82                 :     }
      83               0 :     else if( pszUpdatableINST_DATA[19] != ' ' )
      84                 :     {
      85               0 :         CPLPushFinderLocation( pszUpdatableINST_DATA + 19 );
      86                 :     }
      87                 :     else
      88                 :     {
      89                 : #ifdef INST_DATA
      90               0 :         CPLPushFinderLocation( INST_DATA );
      91                 : #endif
      92                 :     }
      93              64 : }
      94                 : 
      95                 : /************************************************************************/
      96                 : /*                       ~OGRSFDriverRegistrar()                        */
      97                 : /************************************************************************/
      98                 : 
      99              48 : OGRSFDriverRegistrar::~OGRSFDriverRegistrar()
     100                 : 
     101                 : {
     102            1488 :     for( int i = 0; i < nDrivers; i++ )
     103                 :     {
     104            1440 :         delete papoDrivers[i];
     105                 :     }
     106                 : 
     107              48 :     CPLFree( papoDrivers );
     108              48 :     papoDrivers = NULL;
     109                 : 
     110              48 :     poRegistrar = NULL;
     111              48 : }
     112                 : 
     113                 : /************************************************************************/
     114                 : /*                           OGRCleanupAll()                            */
     115                 : /************************************************************************/
     116                 : 
     117                 : /**
     118                 :  * \brief Cleanup all OGR related resources. 
     119                 :  *
     120                 :  * This function will destroy the OGRSFDriverRegistrar along with all registered
     121                 :  * drivers, and then cleanup long lived OSR (OGRSpatialReference) and CPL
     122                 :  * resources.  This may be called in an application when OGR services are
     123                 :  * no longer needed.  It is not normally required, but by freeing all
     124                 :  * dynamically allocated memory it can make memory leak testing easier.
     125                 :  * 
     126                 :  * In addition to destroying the OGRDriverRegistrar, this function also calls:
     127                 :  * - OSRCleanup()
     128                 :  * - CPLFinderClean()
     129                 :  * - VSICleanupFileManager()
     130                 :  * - CPLFreeConfig()
     131                 :  * - CPLCleanupTLS()
     132                 :  */
     133             292 : void OGRCleanupAll()
     134                 : 
     135                 : {
     136                 :     {
     137                 :         // We don't want to hold the mutex while CPL level mutex services
     138                 :         // are being destroyed ... just long enough to avoid conflict while
     139                 :         // cleaning up OGR and OSR services.
     140             292 :         CPLMutexHolderD( &hDRMutex );
     141                 :     
     142             292 :         if( poRegistrar != NULL )
     143              48 :             delete poRegistrar;
     144             292 :         OSRCleanup();
     145                 :     }
     146                 : 
     147             292 :     CPLFinderClean();
     148             292 :     VSICleanupFileManager();
     149             292 :     CPLFreeConfig();
     150             292 :     CPLCleanupTLS();
     151             292 : }
     152                 : 
     153                 : 
     154                 : /************************************************************************/
     155                 : /*                            GetRegistrar()                            */
     156                 : /************************************************************************/
     157                 : 
     158                 : /**
     159                 :  * \brief Fetch registrar.
     160                 :  *
     161                 :  * This static method should be used to fetch the singleton 
     162                 :  * registrar.  It will create a registrar if there is not already
     163                 :  * one in existance.
     164                 :  *
     165                 :  * @return the current driver registrar.
     166                 :  */
     167                 : 
     168            3039 : OGRSFDriverRegistrar *OGRSFDriverRegistrar::GetRegistrar()
     169                 : 
     170                 : {
     171            3039 :     if( poRegistrar == NULL )
     172                 :     {
     173              64 :         CPLMutexHolderD( &hDRMutex );
     174                 : 
     175              64 :         if( poRegistrar == NULL )
     176              64 :             poRegistrar = new OGRSFDriverRegistrar();
     177                 :     }
     178                 :    
     179                 :     CPLAssert( NULL != poRegistrar );
     180            3039 :     return poRegistrar;
     181                 : }
     182                 : 
     183                 : /************************************************************************/
     184                 : /*                                Open()                                */
     185                 : /************************************************************************/
     186                 : 
     187             336 : OGRDataSource *OGRSFDriverRegistrar::Open( const char * pszName,
     188                 :                                            int bUpdate,
     189                 :                                            OGRSFDriver ** ppoDriver )
     190                 : 
     191                 : {
     192                 :     OGRDataSource       *poDS;
     193                 : 
     194             336 :     if( ppoDriver != NULL )
     195              22 :         *ppoDriver = NULL;
     196                 : 
     197             336 :     GetRegistrar();
     198                 :     
     199             336 :     CPLErrorReset();
     200                 : 
     201             336 :     CPLAcquireMutex( hDRMutex, 0.1 );
     202                 : 
     203            3492 :     for( int iDriver = 0; iDriver < poRegistrar->nDrivers; iDriver++ )
     204                 :     {
     205            3488 :         OGRSFDriver *poDriver = poRegistrar->papoDrivers[iDriver];
     206                 : 
     207            3488 :         CPLReleaseMutex( hDRMutex );
     208                 : 
     209            3488 :         poDS = poDriver->Open( pszName, bUpdate );
     210            3488 :         if( poDS != NULL )
     211                 :         {
     212             331 :             if( ppoDriver != NULL )
     213              22 :                 *ppoDriver = poDriver;
     214                 : 
     215             331 :             poDS->Reference();
     216             331 :             if( poDS->GetDriver() == NULL )
     217             331 :                 poDS->m_poDriver = poDriver;
     218                 : 
     219                 :             CPLDebug( "OGR", "OGROpen(%s/%p) succeeded as %s.", 
     220             331 :                       pszName, poDS, poDS->GetDriver()->GetName() );
     221                 :             
     222             331 :             return poDS;
     223                 :         }
     224                 : 
     225            3157 :         if( CPLGetLastErrorType() == CE_Failure )
     226               1 :             return NULL;
     227                 : 
     228            3156 :         CPLAcquireMutex( hDRMutex, 0.1 );
     229                 :     }
     230                 : 
     231               4 :     CPLReleaseMutex( hDRMutex );
     232                 : 
     233               4 :     CPLDebug( "OGR", "OGROpen(%s) failed.", pszName );
     234                 :             
     235               4 :     return NULL;
     236                 : }
     237                 : 
     238                 : /************************************************************************/
     239                 : /*                              OGROpen()                               */
     240                 : /************************************************************************/
     241                 : 
     242             260 : OGRDataSourceH OGROpen( const char *pszName, int bUpdate,
     243                 :                         OGRSFDriverH *pahDriverList )
     244                 : 
     245                 : {
     246             260 :     VALIDATE_POINTER1( pszName, "OGROpen", NULL );
     247                 : 
     248             260 :     if (poRegistrar)
     249                 :         return (OGRDataSourceH) 
     250                 :             poRegistrar->Open( pszName, bUpdate, 
     251             260 :                                (OGRSFDriver **) pahDriverList );
     252                 : 
     253               0 :     return NULL;
     254                 : }
     255                 : 
     256                 : /************************************************************************/
     257                 : /*                             OpenShared()                             */
     258                 : /************************************************************************/
     259                 : 
     260                 : OGRDataSource *
     261              22 : OGRSFDriverRegistrar::OpenShared( const char * pszName, int bUpdate,
     262                 :                                   OGRSFDriver ** ppoDriver )
     263                 : 
     264                 : {
     265                 :     OGRDataSource       *poDS;
     266                 : 
     267              22 :     if( ppoDriver != NULL )
     268               0 :         *ppoDriver = NULL;
     269                 : 
     270              22 :     CPLErrorReset();
     271                 : 
     272                 : /* -------------------------------------------------------------------- */
     273                 : /*      First try finding an existing open dataset matching exactly     */
     274                 : /*      on the original datasource raw name used to open the            */
     275                 : /*      datasource.                                                     */
     276                 : /*                                                                      */
     277                 : /*      NOTE: It is an error, but currently we ignore the bUpdate,      */
     278                 : /*      and return whatever is open even if it is read-only and the     */
     279                 : /*      application requested update access.                            */
     280                 : /* -------------------------------------------------------------------- */
     281                 :     {
     282                 :         int iDS;
     283              22 :         CPLMutexHolderD( &hDRMutex );
     284              22 :         GIntBig nThisPID = CPLGetPID();
     285                 :         
     286              31 :         for( iDS = 0; iDS < nOpenDSCount; iDS++ )
     287                 :         {
     288              23 :             poDS = papoOpenDS[iDS];
     289                 :             
     290              37 :             if( strcmp( pszName, papszOpenDSRawName[iDS]) == 0 
     291              14 :                 && nThisPID == panOpenDSPID[iDS] )
     292                 :             {
     293              14 :                 poDS->Reference();
     294                 :                 
     295              14 :                 if( ppoDriver != NULL )
     296               0 :                     *ppoDriver = papoOpenDSDriver[iDS];
     297              14 :                 return poDS;
     298                 :             }
     299                 :         }
     300                 : 
     301                 : /* -------------------------------------------------------------------- */
     302                 : /*      If that doesn't match, try matching on the name returned by     */
     303                 : /*      the datasource itself.                                          */
     304                 : /* -------------------------------------------------------------------- */
     305              11 :         for( iDS = 0; iDS < nOpenDSCount; iDS++ )
     306                 :         {
     307               3 :             poDS = papoOpenDS[iDS];
     308                 :             
     309               3 :             if( strcmp( pszName, poDS->GetName()) == 0 
     310               0 :                 && nThisPID == panOpenDSPID[iDS] )
     311                 :             {
     312               0 :                 poDS->Reference();
     313                 :                 
     314               0 :                 if( ppoDriver != NULL )
     315               0 :                     *ppoDriver = papoOpenDSDriver[iDS];
     316               0 :                 return poDS;
     317                 :             }
     318               0 :         }
     319                 :     }
     320                 : 
     321                 : /* -------------------------------------------------------------------- */
     322                 : /*      We don't have the datasource.  Open it normally.                */
     323                 : /* -------------------------------------------------------------------- */
     324               8 :     OGRSFDriver *poTempDriver = NULL;
     325                 : 
     326               8 :     poDS = Open( pszName, bUpdate, &poTempDriver );
     327                 : 
     328               8 :     if( poDS == NULL )
     329               0 :         return poDS;
     330                 : 
     331                 : /* -------------------------------------------------------------------- */
     332                 : /*      We don't have this datasource already.  Grow our list to        */
     333                 : /*      hold the new datasource.                                        */
     334                 : /* -------------------------------------------------------------------- */
     335                 :     {
     336               8 :         CPLMutexHolderD( &hDRMutex );
     337                 : 
     338                 :         papszOpenDSRawName = (char **) 
     339               8 :             CPLRealloc( papszOpenDSRawName, sizeof(char*) * (nOpenDSCount+1) );
     340                 :     
     341                 :         papoOpenDS = (OGRDataSource **) 
     342               8 :             CPLRealloc( papoOpenDS, sizeof(char*) * (nOpenDSCount+1) );
     343                 :     
     344                 :         papoOpenDSDriver = (OGRSFDriver **) 
     345               8 :             CPLRealloc( papoOpenDSDriver, sizeof(char*) * (nOpenDSCount+1) );
     346                 : 
     347                 :         panOpenDSPID = (GIntBig *) 
     348               8 :             CPLRealloc( panOpenDSPID, sizeof(GIntBig) * (nOpenDSCount+1) );
     349                 : 
     350               8 :         papszOpenDSRawName[nOpenDSCount] = CPLStrdup( pszName );
     351               8 :         papoOpenDS[nOpenDSCount] = poDS;
     352               8 :         papoOpenDSDriver[nOpenDSCount] = poTempDriver;
     353               8 :         panOpenDSPID[nOpenDSCount] = CPLGetPID();
     354                 : 
     355               8 :         nOpenDSCount++;
     356                 :     }
     357                 : 
     358               8 :     if( ppoDriver != NULL )
     359               0 :         *ppoDriver = poTempDriver;
     360                 : 
     361               8 :     return poDS;
     362                 : }
     363                 : 
     364                 : /************************************************************************/
     365                 : /*                           OGROpenShared()                            */
     366                 : /************************************************************************/
     367                 : 
     368              15 : OGRDataSourceH OGROpenShared( const char *pszName, int bUpdate,
     369                 :                               OGRSFDriverH *pahDriverList )
     370                 : 
     371                 : {
     372              15 :     VALIDATE_POINTER1( pszName, "OGROpenShared", NULL );
     373                 : 
     374              15 :     OGRSFDriverRegistrar::GetRegistrar();
     375                 :     return (OGRDataSourceH)
     376                 :         poRegistrar->OpenShared( pszName, bUpdate, 
     377              15 :                                  (OGRSFDriver **) pahDriverList );
     378                 : }
     379                 : 
     380                 : /************************************************************************/
     381                 : /*                         ReleaseDataSource()                          */
     382                 : /************************************************************************/
     383                 : 
     384             384 : OGRErr OGRSFDriverRegistrar::ReleaseDataSource( OGRDataSource * poDS )
     385                 : 
     386                 : {
     387                 :     {
     388             384 :         CPLMutexHolderD( &hDRMutex );
     389                 : 
     390                 :         int iDS;
     391                 : 
     392             404 :         for( iDS = 0; iDS < nOpenDSCount; iDS++ )
     393                 :         {
     394              38 :             if( poDS == papoOpenDS[iDS] )
     395              18 :                 break;
     396                 :         }
     397                 : 
     398             384 :         if( iDS == nOpenDSCount )
     399                 :         {
     400                 :             CPLDebug( "OGR", 
     401                 :                       "ReleaseDataSource(%s/%p) on unshared datasource!\n"
     402                 :                       "Deleting directly.", 
     403             366 :                       poDS->GetName(), poDS );
     404             366 :             delete poDS;
     405             366 :             return OGRERR_FAILURE;
     406                 :         }
     407                 : 
     408              18 :         if( poDS->GetRefCount() > 0 )
     409              18 :             poDS->Dereference();
     410                 : 
     411              18 :         if( poDS->GetRefCount() > 0 )
     412                 :         {
     413                 :             CPLDebug( "OGR", 
     414                 :                       "ReleaseDataSource(%s/%p) ... just dereferencing.",
     415              10 :                       poDS->GetName(), poDS );
     416              10 :             return OGRERR_NONE;
     417                 :         }
     418                 : 
     419               8 :         if( poDS->GetSummaryRefCount() > 0 )
     420                 :         {
     421                 :             CPLDebug( "OGR", 
     422                 :                       "OGRSFDriverRegistrar::ReleaseDataSource(%s)\n"
     423                 :                       "Datasource reference count is now zero, but some layers\n"
     424                 :                       "are still referenced ... not closing datasource.",
     425               0 :                       poDS->GetName() );
     426               0 :             return OGRERR_FAILURE;
     427                 :         }
     428                 : 
     429                 : /* -------------------------------------------------------------------- */
     430                 : /*      We really want to close this file, and remove it from the       */
     431                 : /*      shared list.                                                    */
     432                 : /* -------------------------------------------------------------------- */
     433                 :         CPLDebug( "OGR", 
     434                 :                   "ReleaseDataSource(%s/%p) dereferenced and now destroying.",
     435               8 :                   poDS->GetName(), poDS );
     436                 : 
     437               8 :         CPLFree( papszOpenDSRawName[iDS] );
     438                 :         memmove( papszOpenDSRawName + iDS, papszOpenDSRawName + iDS + 1, 
     439               8 :                  sizeof(char *) * (nOpenDSCount - iDS - 1) );
     440                 :         memmove( papoOpenDS + iDS, papoOpenDS + iDS + 1, 
     441               8 :                  sizeof(char *) * (nOpenDSCount - iDS - 1) );
     442                 :         memmove( papoOpenDSDriver + iDS, papoOpenDSDriver + iDS + 1, 
     443               8 :                  sizeof(char *) * (nOpenDSCount - iDS - 1) );
     444                 :         memmove( panOpenDSPID + iDS, panOpenDSPID + iDS + 1, 
     445               8 :                  sizeof(GIntBig) * (nOpenDSCount - iDS - 1) );
     446                 : 
     447               8 :         nOpenDSCount--;
     448                 : 
     449               8 :         if( nOpenDSCount == 0 )
     450                 :         {
     451               5 :             CPLFree( papszOpenDSRawName );
     452               5 :             papszOpenDSRawName = NULL;
     453               5 :             CPLFree( papoOpenDS );
     454               5 :             papoOpenDS = NULL;
     455               5 :             CPLFree( papoOpenDSDriver );
     456               5 :             papoOpenDSDriver = NULL;
     457               5 :             CPLFree( panOpenDSPID );
     458               5 :             panOpenDSPID = NULL;
     459               0 :         }
     460                 :     }
     461                 : 
     462                 : /* -------------------------------------------------------------------- */
     463                 : /*      We are careful to only do the delete poDS after adjusting       */
     464                 : /*      the table, as if it is a virtual dataset, other removals may    */
     465                 : /*      happen in the meantime.  We are also careful to do this         */
     466                 : /*      outside the mutex protected loop as destroying a dataset can    */
     467                 : /*      take quite a while.                                             */
     468                 : /* -------------------------------------------------------------------- */
     469               8 :     delete poDS;
     470                 : 
     471               8 :     return OGRERR_NONE;
     472                 : }
     473                 : 
     474                 : /************************************************************************/
     475                 : /*                        OGRReleaseDataSource()                        */
     476                 : /************************************************************************/
     477                 : 
     478             373 : OGRErr OGRReleaseDataSource( OGRDataSourceH hDS )
     479                 : 
     480                 : {
     481             373 :     VALIDATE_POINTER1( hDS, "OGRReleaseDataSource", OGRERR_INVALID_HANDLE );
     482                 : 
     483             373 :     OGRSFDriverRegistrar::GetRegistrar();
     484             373 :     return poRegistrar->ReleaseDataSource((OGRDataSource *) hDS);
     485                 : }
     486                 : 
     487                 : /************************************************************************/
     488                 : /*                         OGRGetOpenDSCount()                          */
     489                 : /************************************************************************/
     490                 : 
     491               5 : int OGRGetOpenDSCount()
     492                 : 
     493                 : {
     494               5 :     OGRSFDriverRegistrar::GetRegistrar();
     495               5 :     return poRegistrar->GetOpenDSCount();
     496                 : }
     497                 : 
     498                 : /************************************************************************/
     499                 : /*                             GetOpenDS()                              */
     500                 : /************************************************************************/
     501                 : 
     502               1 : OGRDataSource *OGRSFDriverRegistrar::GetOpenDS( int iDS )
     503                 : 
     504                 : {
     505               1 :     CPLMutexHolderD( &hDRMutex );
     506                 : 
     507               1 :     if( iDS < 0 || iDS >= nOpenDSCount )
     508               0 :         return NULL;
     509                 :     else
     510               1 :         return papoOpenDS[iDS];
     511                 : }
     512                 : 
     513                 : /************************************************************************/
     514                 : /*                            OGRGetOpenDS()                            */
     515                 : /************************************************************************/
     516                 : 
     517               1 : OGRDataSourceH OGRGetOpenDS( int iDS )
     518                 : 
     519                 : {
     520               1 :     OGRSFDriverRegistrar::GetRegistrar();
     521               1 :     return (OGRDataSourceH) poRegistrar->GetOpenDS( iDS );
     522                 : }
     523                 : 
     524                 : /************************************************************************/
     525                 : /*                           RegisterDriver()                           */
     526                 : /************************************************************************/
     527                 : 
     528            1920 : void OGRSFDriverRegistrar::RegisterDriver( OGRSFDriver * poDriver )
     529                 : 
     530                 : {
     531            1920 :     CPLMutexHolderD( &hDRMutex );
     532                 :     int         iDriver;
     533                 : 
     534                 : /* -------------------------------------------------------------------- */
     535                 : /*      It has no effect to register a driver more than once.           */
     536                 : /* -------------------------------------------------------------------- */
     537           29760 :     for( iDriver = 0; iDriver < nDrivers; iDriver++ )
     538                 :     {
     539           27840 :         if( poDriver == papoDrivers[iDriver] )
     540                 :             return;
     541                 : 
     542                 :         /* Same name but different pointer. Likely a second call to OGRRegisterAll() */
     543                 :         /* We delete the new driver */
     544           27840 :         if (EQUAL(poDriver->GetName(), papoDrivers[iDriver]->GetName()))
     545                 :         {
     546               0 :             delete poDriver;
     547                 :             return;
     548                 :         }
     549                 :     }
     550                 : 
     551                 : /* -------------------------------------------------------------------- */
     552                 : /*      Skip and destroy drivers in the black list.                     */
     553                 : /* -------------------------------------------------------------------- */
     554                 :     char** papszSkipDrivers =
     555            1920 :             CSLTokenizeStringComplex(CPLGetConfigOption("OGR_SKIP", ""), ",", FALSE, FALSE);
     556            1920 :     char** iter = papszSkipDrivers;
     557            3840 :     while(*iter)
     558                 :     {
     559               0 :         if (strcmp(*iter, poDriver->GetName()) == 0)
     560                 :         {
     561               0 :             CSLDestroy(papszSkipDrivers);
     562               0 :             delete poDriver;
     563                 :             return;
     564                 :         }
     565               0 :         iter ++;
     566                 :     }
     567            1920 :     CSLDestroy(papszSkipDrivers);
     568                 : 
     569                 : /* -------------------------------------------------------------------- */
     570                 : /*      Add to the end of the driver list.                              */
     571                 : /* -------------------------------------------------------------------- */
     572                 :     papoDrivers = (OGRSFDriver **)
     573            1920 :         CPLRealloc( papoDrivers, (nDrivers+1) * sizeof(void*) );
     574                 : 
     575            1920 :     papoDrivers[nDrivers++] = poDriver;
     576                 : }
     577                 : 
     578                 : /************************************************************************/
     579                 : /*                         OGRRegisterDriver()                          */
     580                 : /************************************************************************/
     581                 : 
     582               0 : void OGRRegisterDriver( OGRSFDriverH hDriver )
     583                 : 
     584                 : {
     585               0 :     VALIDATE_POINTER0( hDriver, "OGRRegisterDriver" );
     586                 : 
     587                 :     OGRSFDriverRegistrar::GetRegistrar()->RegisterDriver( 
     588               0 :         (OGRSFDriver *) hDriver );
     589                 : }
     590                 : 
     591                 : /************************************************************************/
     592                 : /*                           GetDriverCount()                           */
     593                 : /************************************************************************/
     594                 : 
     595             131 : int OGRSFDriverRegistrar::GetDriverCount()
     596                 : 
     597                 : {
     598             131 :     return nDrivers;
     599                 : }
     600                 : 
     601                 : /************************************************************************/
     602                 : /*                         OGRGetDriverCount()                          */
     603                 : /************************************************************************/
     604                 : 
     605              20 : int OGRGetDriverCount()
     606                 : 
     607                 : {
     608              20 :     if (poRegistrar)
     609              19 :         return poRegistrar->GetDriverCount();
     610                 : 
     611               1 :     return 0;
     612                 : }
     613                 : 
     614                 : /************************************************************************/
     615                 : /*                             GetDriver()                              */
     616                 : /************************************************************************/
     617                 : 
     618             112 : OGRSFDriver *OGRSFDriverRegistrar::GetDriver( int iDriver )
     619                 : 
     620                 : {
     621             112 :     CPLMutexHolderD( &hDRMutex );
     622                 : 
     623             112 :     if( iDriver < 0 || iDriver >= nDrivers )
     624               0 :         return NULL;
     625                 :     else
     626             112 :         return papoDrivers[iDriver];
     627                 : }
     628                 : 
     629                 : /************************************************************************/
     630                 : /*                            OGRGetDriver()                            */
     631                 : /************************************************************************/
     632                 : 
     633               0 : OGRSFDriverH OGRGetDriver( int iDriver )
     634                 : 
     635                 : {
     636               0 :     VALIDATE_POINTER1( poRegistrar, "OGRGetDriver", NULL );
     637                 : 
     638               0 :     return (OGRSFDriverH) poRegistrar->GetDriver( iDriver );
     639                 : }
     640                 : 
     641                 : /************************************************************************/
     642                 : /*                          GetDriverByName()                           */
     643                 : /************************************************************************/
     644                 : 
     645             179 : OGRSFDriver *OGRSFDriverRegistrar::GetDriverByName( const char * pszName )
     646                 : 
     647                 : {
     648             179 :     CPLMutexHolderD( &hDRMutex );
     649                 : 
     650            1477 :     for( int i = 0; i < nDrivers; i++ )
     651                 :     {
     652            4416 :         if( papoDrivers[i] != NULL 
     653            2944 :             && EQUAL(papoDrivers[i]->GetName(),pszName) )
     654             174 :             return papoDrivers[i];
     655                 :     }
     656                 : 
     657               5 :     return NULL;
     658                 : }
     659                 : 
     660                 : /************************************************************************/
     661                 : /*                         OGRGetDriverByName()                         */
     662                 : /************************************************************************/
     663                 : 
     664             179 : OGRSFDriverH OGRGetDriverByName( const char *pszName )
     665                 : 
     666                 : {
     667             179 :     VALIDATE_POINTER1( pszName, "OGRGetDriverByName", NULL );
     668                 : 
     669                 :     return (OGRSFDriverH) 
     670             179 :         OGRSFDriverRegistrar::GetRegistrar()->GetDriverByName( pszName );
     671                 : }
     672                 : 
     673                 : /************************************************************************/
     674                 : /*                          AutoLoadDrivers()                           */
     675                 : /************************************************************************/
     676                 : 
     677                 : /**
     678                 :  * \brief Auto-load GDAL drivers from shared libraries.
     679                 :  *
     680                 :  * This function will automatically load drivers from shared libraries.  It
     681                 :  * searches the "driver path" for .so (or .dll) files that start with the
     682                 :  * prefix "ogr_X.so".  It then tries to load them and then tries to call
     683                 :  * a function within them called RegisterOGRX() where the 'X' is the same 
     684                 :  * as the remainder of the shared library basename, or failing that to 
     685                 :  * call GDALRegisterMe().  
     686                 :  *
     687                 :  * There are a few rules for the driver path.  If the GDAL_DRIVER_PATH 
     688                 :  * environment variable it set, it is taken to be a list of directories to 
     689                 :  * search separated by colons on unix, or semi-colons on Windows.  
     690                 :  *
     691                 :  * If that is not set the following defaults are used:
     692                 :  *
     693                 :  * <ul>
     694                 :  * <li> Linux/Unix: <prefix>/lib/gdalplugins is searched or 
     695                 :  * /usr/local/lib/gdalplugins if the install prefix is not known.
     696                 :  * <li> MacOSX: <prefix>/PlugIns is searched, or /usr/local/lib/gdalplugins if
     697                 :  * the install prefix is not known.  Also, the framework directory
     698                 :  * /Library/Application Support/GDAL/PlugIns is searched.
     699                 :  * <li> Win32: <prefix>/lib/gdalplugins if the prefix is known (normally it 
     700                 :  * is not), otherwise the gdalplugins subdirectory of the directory containing
     701                 :  * the currently running executable is used. 
     702                 :  * </ul>
     703                 :  */
     704                 : 
     705              64 : void OGRSFDriverRegistrar::AutoLoadDrivers()
     706                 : 
     707                 : {
     708              64 :     char     **papszSearchPath = NULL;
     709                 :     const char *pszGDAL_DRIVER_PATH = 
     710              64 :         CPLGetConfigOption( "OGR_DRIVER_PATH", NULL );
     711                 : 
     712              64 :     if( pszGDAL_DRIVER_PATH == NULL )
     713                 :         pszGDAL_DRIVER_PATH = 
     714              64 :             CPLGetConfigOption( "GDAL_DRIVER_PATH", NULL );
     715                 : 
     716                 : /* -------------------------------------------------------------------- */
     717                 : /*      Where should we look for stuff?                                 */
     718                 : /* -------------------------------------------------------------------- */
     719              64 :     if( pszGDAL_DRIVER_PATH != NULL )
     720                 :     {
     721                 : #ifdef WIN32
     722                 :         papszSearchPath = 
     723                 :             CSLTokenizeStringComplex( pszGDAL_DRIVER_PATH, ";", TRUE, FALSE );
     724                 : #else
     725                 :         papszSearchPath = 
     726               0 :             CSLTokenizeStringComplex( pszGDAL_DRIVER_PATH, ":", TRUE, FALSE );
     727                 : #endif
     728                 :     }
     729                 :     else
     730                 :     {
     731                 : #ifdef GDAL_PREFIX
     732                 :         papszSearchPath = CSLAddString( papszSearchPath,
     733                 :     #ifdef MACOSX_FRAMEWORK
     734                 :                                         GDAL_PREFIX "/PlugIns");
     735                 :     #else
     736              64 :                                         GDAL_PREFIX "/lib/gdalplugins" );
     737                 :     #endif
     738                 : #else
     739                 :         char szExecPath[1024];
     740                 : 
     741                 :         if( CPLGetExecPath( szExecPath, sizeof(szExecPath) ) )
     742                 :         {
     743                 :             char szPluginDir[sizeof(szExecPath)+50];
     744                 :             strcpy( szPluginDir, CPLGetDirname( szExecPath ) );
     745                 :             strcat( szPluginDir, "\\gdalplugins\\" );
     746                 :             papszSearchPath = CSLAddString( papszSearchPath, szPluginDir );
     747                 :         }
     748                 :         else
     749                 :         {
     750                 :             papszSearchPath = CSLAddString( papszSearchPath, 
     751                 :                                             "/usr/local/lib/gdalplugins" );
     752                 :         }
     753                 : #endif 
     754                 : 
     755                 : #ifdef MACOSX_FRAMEWORK
     756                 :         papszSearchPath = CSLAddString( papszSearchPath, 
     757                 :                                         "/Library/Application Support/GDAL/PlugIns" );
     758                 : #endif
     759                 : 
     760                 :     }
     761                 : 
     762                 : /* -------------------------------------------------------------------- */
     763                 : /*      Scan each directory looking for files starting with gdal_       */
     764                 : /* -------------------------------------------------------------------- */
     765             128 :     for( int iDir = 0; iDir < CSLCount(papszSearchPath); iDir++ )
     766                 :     {
     767              64 :         char  **papszFiles = CPLReadDir( papszSearchPath[iDir] );
     768                 : 
     769              64 :         for( int iFile = 0; iFile < CSLCount(papszFiles); iFile++ )
     770                 :         {
     771                 :             char   *pszFuncName;
     772                 :             const char *pszFilename;
     773               0 :             const char *pszExtension = CPLGetExtension( papszFiles[iFile] );
     774                 :             void   *pRegister;
     775                 : 
     776               0 :             if( !EQUALN(papszFiles[iFile],"ogr_",4) )
     777               0 :                 continue;
     778                 : 
     779               0 :             if( !EQUAL(pszExtension,"dll") 
     780                 :                 && !EQUAL(pszExtension,"so") 
     781                 :                 && !EQUAL(pszExtension,"dylib") )
     782               0 :                 continue;
     783                 : 
     784               0 :             pszFuncName = (char *) CPLCalloc(strlen(papszFiles[iFile])+20,1);
     785                 :             sprintf( pszFuncName, "RegisterOGR%s", 
     786               0 :                      CPLGetBasename(papszFiles[iFile]) + 4 );
     787                 :             
     788                 :             pszFilename = 
     789               0 :                 CPLFormFilename( papszSearchPath[iDir], 
     790               0 :                                  papszFiles[iFile], NULL );
     791                 : 
     792               0 :             pRegister = CPLGetSymbol( pszFilename, pszFuncName );
     793               0 :             if( pRegister == NULL )
     794                 :             {
     795               0 :                 strcpy( pszFuncName, "GDALRegisterMe" );
     796               0 :                 pRegister = CPLGetSymbol( pszFilename, pszFuncName );
     797                 :             }
     798                 :             
     799               0 :             if( pRegister != NULL )
     800                 :             {
     801                 :                 CPLDebug( "OGR", "Auto register %s using %s.", 
     802               0 :                           pszFilename, pszFuncName );
     803                 : 
     804               0 :                 ((void (*)()) pRegister)();
     805                 :             }
     806                 : 
     807               0 :             CPLFree( pszFuncName );
     808                 :         }
     809                 : 
     810              64 :         CSLDestroy( papszFiles );
     811                 :     }
     812                 : 
     813              64 :     CSLDestroy( papszSearchPath );
     814              64 : }
     815                 : 

Generated by: LCOV version 1.7