00001 /******************************************************************************
00002 * Copyright (c) 1998, Frank Warmerdam
00003 *
00004 * Permission is hereby granted, free of charge, to any person obtaining a
00005 * copy of this software and associated documentation files (the "Software"),
00006 * to deal in the Software without restriction, including without limitation
00007 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
00008 * and/or sell copies of the Software, and to permit persons to whom the
00009 * Software is furnished to do so, subject to the following conditions:
00010 *
00011 * The above copyright notice and this permission notice shall be included
00012 * in all copies or substantial portions of the Software.
00013 *
00014 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
00015 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00016 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
00017 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
00018 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
00019 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
00020 * DEALINGS IN THE SOFTWARE.
00021 ******************************************************************************
00022 *
00023 * gdaldrivermanager.cpp
00024 *
00025 * The GDALDriverManager class from gdal_priv.h.
00026 *
00027 * $Log: gdaldrivermanager_cpp-source.html,v $
00027 * Revision 1.13 2002/12/21 19:13:13 warmerda
00027 * updated
00027 *
00028 * Revision 1.14 2002/12/03 04:41:41 warmerda
00029 * call CPLFinderClean() to cleanup memory
00030 *
00031 * Revision 1.13 2002/10/21 18:05:42 warmerda
00032 * added AutoSkipDrivers() method on driver manager
00033 *
00034 * Revision 1.12 2002/09/04 06:52:35 warmerda
00035 * added GDALDestroyDriverManager
00036 *
00037 * Revision 1.11 2002/07/09 20:33:12 warmerda
00038 * expand tabs
00039 *
00040 * Revision 1.10 2002/06/12 21:13:27 warmerda
00041 * use metadata based driver info
00042 *
00043 * Revision 1.9 2002/05/14 21:38:32 warmerda
00044 * make INST_DATA overidable with binary patch
00045 *
00046 * Revision 1.8 2001/07/18 04:04:30 warmerda
00047 * added CPL_CVSID
00048 *
00049 * Revision 1.7 2000/08/29 21:09:15 warmerda
00050 * added logic to push INST_DATA on data file search stack
00051 *
00052 * Revision 1.6 2000/04/22 12:25:41 warmerda
00053 * Documented AutoLoadDrivers().
00054 *
00055 * Revision 1.5 2000/04/04 23:44:29 warmerda
00056 * added AutoLoadDrivers() to GDALDriverManager
00057 *
00058 * Revision 1.4 2000/03/06 02:21:39 warmerda
00059 * added GDALRegisterDriver func
00060 *
00061 * Revision 1.3 1999/10/21 13:24:08 warmerda
00062 * Added documentation and C callable functions.
00063 *
00064 * Revision 1.2 1998/12/31 18:53:33 warmerda
00065 * Add GDALGetDriverByName
00066 *
00067 * Revision 1.1 1998/12/03 18:32:01 warmerda
00068 * New
00069 *
00070 */
00071
00072 #include "gdal_priv.h"
00073 #include "cpl_string.h"
00074
00075 CPL_CVSID("$Id: gdaldrivermanager_cpp-source.html,v 1.13 2002/12/21 19:13:13 warmerda Exp $");
00076
00077 static char *pszUpdatableINST_DATA =
00078 "__INST_DATA_TARGET: ";
00079
00080 /************************************************************************/
00081 /* ==================================================================== */
00082 /* GDALDriverManager */
00083 /* ==================================================================== */
00084 /************************************************************************/
00085
00086 static GDALDriverManager *poDM = NULL;
00087
00088 /************************************************************************/
00089 /* GetGDALDriverManager() */
00090 /* */
00091 /* A freestanding function to get the only instance of the */
00092 /* GDALDriverManager. */
00093 /************************************************************************/
00094
00105 GDALDriverManager *GetGDALDriverManager()
00106
00107 {
00108 if( poDM == NULL )
00109 new GDALDriverManager();
00110
00111 return( poDM );
00112 }
00113
00114 /************************************************************************/
00115 /* GDALDriverManager() */
00116 /************************************************************************/
00117
00118 GDALDriverManager::GDALDriverManager()
00119
00120 {
00121 nDrivers = 0;
00122 papoDrivers = NULL;
00123 pszHome = CPLStrdup("");
00124
00125 CPLAssert( poDM == NULL );
00126 poDM = this;
00127
00128 /* -------------------------------------------------------------------- */
00129 /* We want to push a location to search for data files */
00130 /* supporting GDAL/OGR such as EPSG csv files, S-57 definition */
00131 /* files, and so forth. The static pszUpdateableINST_DATA */
00132 /* string can be updated within the shared library or */
00133 /* executable during an install to point installed data */
00134 /* directory. If it isn't burned in here then we use the */
00135 /* INST_DATA macro (setup at configure time) if */
00136 /* available. Otherwise we don't push anything and we hope */
00137 /* other mechanisms such as environment variables will have */
00138 /* been employed. */
00139 /* -------------------------------------------------------------------- */
00140 if( pszUpdatableINST_DATA[19] != ' ' )
00141 {
00142 CPLPushFinderLocation( pszUpdatableINST_DATA + 19 );
00143 }
00144 else
00145 {
00146 #ifdef INST_DATA
00147 CPLPushFinderLocation( INST_DATA );
00148 #endif
00149 }
00150 }
00151
00152 /************************************************************************/
00153 /* ~GDALDriverManager() */
00154 /* */
00155 /* Eventually this should also likely clean up all open */
00156 /* datasets. Or perhaps the drivers that own them should do */
00157 /* that in their destructor? */
00158 /************************************************************************/
00159
00160 GDALDriverManager::~GDALDriverManager()
00161
00162 {
00163 /* -------------------------------------------------------------------- */
00164 /* Destroy the existing drivers. */
00165 /* -------------------------------------------------------------------- */
00166 while( GetDriverCount() > 0 )
00167 {
00168 GDALDriver *poDriver = GetDriver(0);
00169
00170 DeregisterDriver(poDriver);
00171 delete poDriver;
00172 }
00173
00174 /* -------------------------------------------------------------------- */
00175 /* Cleanup local memory. */
00176 /* -------------------------------------------------------------------- */
00177 VSIFree( papoDrivers );
00178 VSIFree( pszHome );
00179
00180 /* -------------------------------------------------------------------- */
00181 /* Blow away all the finder hints paths. We really shouldn't */
00182 /* be doing all of them, but it is currently hard to keep track */
00183 /* of those that actually belong to us. */
00184 /* -------------------------------------------------------------------- */
00185 CPLFinderClean();
00186
00187 /* -------------------------------------------------------------------- */
00188 /* Ensure the global driver manager pointer is NULLed out. */
00189 /* -------------------------------------------------------------------- */
00190 if( poDM == this )
00191 poDM = NULL;
00192 }
00193
00194 /************************************************************************/
00195 /* GetDriverCount() */
00196 /************************************************************************/
00197
00206 int GDALDriverManager::GetDriverCount()
00207
00208 {
00209 return( nDrivers );
00210 }
00211
00212 /************************************************************************/
00213 /* GDALGetDriverCount() */
00214 /************************************************************************/
00215
00216 int GDALGetDriverCount()
00217
00218 {
00219 return GetGDALDriverManager()->GetDriverCount();
00220 }
00221
00222 /************************************************************************/
00223 /* GetDriver() */
00224 /************************************************************************/
00225
00236 GDALDriver * GDALDriverManager::GetDriver( int iDriver )
00237
00238 {
00239 if( iDriver < 0 || iDriver >= nDrivers )
00240 return NULL;
00241 else
00242 return papoDrivers[iDriver];
00243 }
00244
00245 /************************************************************************/
00246 /* GDALGetDriver() */
00247 /************************************************************************/
00248
00249 GDALDriverH GDALGetDriver( int iDriver )
00250
00251 {
00252 return (GDALDriverH) GetGDALDriverManager()->GetDriver(iDriver);
00253 }
00254
00255 /************************************************************************/
00256 /* RegisterDriver() */
00257 /************************************************************************/
00258
00278 int GDALDriverManager::RegisterDriver( GDALDriver * poDriver )
00279
00280 {
00281 /* -------------------------------------------------------------------- */
00282 /* If it is already registered, just return the existing */
00283 /* index. */
00284 /* -------------------------------------------------------------------- */
00285 if( GetDriverByName( poDriver->GetDescription() ) != NULL )
00286 {
00287 int i;
00288
00289 for( i = 0; i < nDrivers; i++ )
00290 {
00291 if( papoDrivers[i] == poDriver )
00292 return i;
00293 }
00294
00295 CPLAssert( FALSE );
00296 }
00297
00298 /* -------------------------------------------------------------------- */
00299 /* Otherwise grow the list to hold the new entry. */
00300 /* -------------------------------------------------------------------- */
00301 papoDrivers = (GDALDriver **)
00302 VSIRealloc(papoDrivers, sizeof(GDALDriver *) * (nDrivers+1));
00303
00304 papoDrivers[nDrivers] = poDriver;
00305 nDrivers++;
00306
00307 if( poDriver->pfnCreate != NULL )
00308 poDriver->SetMetadataItem( GDAL_DCAP_CREATE, "YES" );
00309
00310 if( poDriver->pfnCreateCopy != NULL )
00311 poDriver->SetMetadataItem( GDAL_DCAP_CREATECOPY, "YES" );
00312
00313 return( nDrivers - 1 );
00314 }
00315
00316 /************************************************************************/
00317 /* GDALRegisterDriver() */
00318 /************************************************************************/
00319
00320 int GDALRegisterDriver( GDALDriverH hDriver )
00321
00322 {
00323 return GetGDALDriverManager()->RegisterDriver( (GDALDriver *) hDriver );
00324 }
00325
00326
00327 /************************************************************************/
00328 /* DeregisterDriver() */
00329 /************************************************************************/
00330
00341 void GDALDriverManager::DeregisterDriver( GDALDriver * poDriver )
00342
00343 {
00344 int i;
00345
00346 for( i = 0; i < nDrivers; i++ )
00347 {
00348 if( papoDrivers[i] == poDriver )
00349 break;
00350 }
00351
00352 if( i == nDrivers )
00353 return;
00354
00355 while( i < nDrivers-1 )
00356 {
00357 papoDrivers[i] = papoDrivers[i+1];
00358 i++;
00359 }
00360 nDrivers--;
00361 }
00362
00363 /************************************************************************/
00364 /* GDALDeregisterDriver() */
00365 /************************************************************************/
00366
00367 void GDALDeregisterDriver( GDALDriverH hDriver )
00368
00369 {
00370 GetGDALDriverManager()->DeregisterDriver( (GDALDriver *) hDriver );
00371 }
00372
00373
00374 /************************************************************************/
00375 /* GetDriverByName() */
00376 /************************************************************************/
00377
00388 GDALDriver * GDALDriverManager::GetDriverByName( const char * pszName )
00389
00390 {
00391 int i;
00392
00393 for( i = 0; i < nDrivers; i++ )
00394 {
00395 if( EQUAL(papoDrivers[i]->GetDescription(), pszName) )
00396 return papoDrivers[i];
00397 }
00398
00399 return NULL;
00400 }
00401
00402 /************************************************************************/
00403 /* GDALGetDriverByName() */
00404 /************************************************************************/
00405
00406 GDALDriverH GDALGetDriverByName( const char * pszName )
00407
00408 {
00409 return( GetGDALDriverManager()->GetDriverByName( pszName ) );
00410 }
00411
00412 /************************************************************************/
00413 /* GetHome() */
00414 /************************************************************************/
00415
00416 const char *GDALDriverManager::GetHome()
00417
00418 {
00419 return pszHome;
00420 }
00421
00422 /************************************************************************/
00423 /* SetHome() */
00424 /************************************************************************/
00425
00426 void GDALDriverManager::SetHome( const char * pszNewHome )
00427
00428 {
00429 CPLFree( pszHome );
00430 pszHome = CPLStrdup(pszNewHome);
00431 }
00432
00433 /************************************************************************/
00434 /* AutoSkipDrivers() */
00435 /************************************************************************/
00436
00449 void GDALDriverManager::AutoSkipDrivers()
00450
00451 {
00452 if( getenv( "GDAL_SKIP" ) == NULL )
00453 return;
00454
00455 char **papszList = CSLTokenizeString( getenv("GDAL_SKIP") );
00456
00457 for( int i = 0; i < CSLCount(papszList); i++ )
00458 {
00459 GDALDriver *poDriver = GetDriverByName( papszList[i] );
00460
00461 if( poDriver == NULL )
00462 CPLError( CE_Warning, CPLE_AppDefined,
00463 "Unable to find driver %s to unload from GDAL_SKIP environment variable.",
00464 papszList[i] );
00465 else
00466 {
00467 CPLDebug( "GDAL", "AutoSkipDriver(%s)", papszList[i] );
00468 DeregisterDriver( poDriver );
00469 delete poDriver;
00470 }
00471
00472 }
00473
00474 CSLDestroy( papszList );
00475 }
00476
00477 /************************************************************************/
00478 /* AutoLoadDrivers() */
00479 /************************************************************************/
00480
00498 void GDALDriverManager::AutoLoadDrivers()
00499
00500 {
00501 char **papszSearchPath = NULL;
00502
00503 /* -------------------------------------------------------------------- */
00504 /* Where should we look for stuff? */
00505 /* -------------------------------------------------------------------- */
00506 if( getenv( "GDAL_DRIVER_PATH" ) != NULL )
00507 {
00508 #ifdef WIN32
00509 papszSearchPath =
00510 CSLTokenizeStringComplex( getenv( "GDAL_DRIVER_PATH" ), ";",
00511 TRUE, FALSE );
00512 #else
00513 papszSearchPath =
00514 CSLTokenizeStringComplex( getenv( "GDAL_DRIVER_PATH" ), ":",
00515 TRUE, FALSE );
00516 #endif
00517 }
00518 else
00519 {
00520 papszSearchPath = CSLAddString( papszSearchPath, "/usr/local/lib" );
00521
00522 if( strlen(GetHome()) > 0 )
00523 {
00524 papszSearchPath = CSLAddString( papszSearchPath,
00525 CPLFormFilename( GetHome(), "lib", NULL ) );
00526 }
00527 }
00528
00529 /* -------------------------------------------------------------------- */
00530 /* Scan each directory looking for files starting with gdal_ */
00531 /* -------------------------------------------------------------------- */
00532 for( int iDir = 0; iDir < CSLCount(papszSearchPath); iDir++ )
00533 {
00534 char **papszFiles = CPLReadDir( papszSearchPath[iDir] );
00535
00536 for( int iFile = 0; iFile < CSLCount(papszFiles); iFile++ )
00537 {
00538 char *pszFuncName;
00539 const char *pszFilename;
00540 void *pRegister;
00541
00542 if( !EQUALN(papszFiles[iFile],"gdal_",5) )
00543 continue;
00544
00545 pszFuncName = (char *) CPLCalloc(strlen(papszFiles[iFile])+20,1);
00546 sprintf( pszFuncName, "GDALRegister_%s",
00547 CPLGetBasename(papszFiles[iFile]) + 5 );
00548
00549 pszFilename =
00550 CPLFormFilename( papszSearchPath[iDir],
00551 papszFiles[iFile], NULL );
00552
00553 pRegister = CPLGetSymbol( pszFilename, pszFuncName );
00554 if( pRegister == NULL )
00555 {
00556 strcpy( pszFuncName, "GDALRegisterMe" );
00557 pRegister = CPLGetSymbol( pszFilename, pszFuncName );
00558 }
00559
00560 if( pRegister != NULL )
00561 {
00562 CPLDebug( "GDAL", "Auto register %s using %s\n",
00563 pszFilename, pszFuncName );
00564
00565 ((void (*)()) pRegister)();
00566 }
00567
00568 CPLFree( pszFuncName );
00569 }
00570
00571 CSLDestroy( papszFiles );
00572 }
00573
00574 CSLDestroy( papszSearchPath );
00575 }
00576
00577 /************************************************************************/
00578 /* GDALDestroyDriverManager() */
00579 /************************************************************************/
00580
00587 void GDALDestroyDriverManager( void )
00588
00589 {
00590 if( poDM != NULL )
00591 delete poDM;
00592 }
1.2.3-20001105 written by Dimitri van Heesch,
© 1997-2000