LCOV - code coverage report
Current view: directory - ogr/ogrsf_frmts/generic - ogrsfdriverregistrar.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 266 227 85.3 %
Date: 2011-12-18 Functions: 26 23 88.5 %

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

Generated by: LCOV version 1.7