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.10 2002/04/16 13:11:48 warmerda 00027 * updated 00027 * 00028 * Revision 1.8 2001/07/18 04:04:30 warmerda 00029 * added CPL_CVSID 00030 * 00031 * Revision 1.7 2000/08/29 21:09:15 warmerda 00032 * added logic to push INST_DATA on data file search stack 00033 * 00034 * Revision 1.6 2000/04/22 12:25:41 warmerda 00035 * Documented AutoLoadDrivers(). 00036 * 00037 * Revision 1.5 2000/04/04 23:44:29 warmerda 00038 * added AutoLoadDrivers() to GDALDriverManager 00039 * 00040 * Revision 1.4 2000/03/06 02:21:39 warmerda 00041 * added GDALRegisterDriver func 00042 * 00043 * Revision 1.3 1999/10/21 13:24:08 warmerda 00044 * Added documentation and C callable functions. 00045 * 00046 * Revision 1.2 1998/12/31 18:53:33 warmerda 00047 * Add GDALGetDriverByName 00048 * 00049 * Revision 1.1 1998/12/03 18:32:01 warmerda 00050 * New 00051 * 00052 */ 00053 00054 #include "gdal_priv.h" 00055 #include "cpl_string.h" 00056 00057 CPL_CVSID("$Id: gdaldrivermanager_cpp-source.html,v 1.10 2002/04/16 13:11:48 warmerda Exp $"); 00058 00059 /************************************************************************/ 00060 /* ==================================================================== */ 00061 /* GDALDriverManager */ 00062 /* ==================================================================== */ 00063 /************************************************************************/ 00064 00065 static GDALDriverManager *poDM = NULL; 00066 00067 /************************************************************************/ 00068 /* GetGDALDriverManager() */ 00069 /* */ 00070 /* A freestanding function to get the only instance of the */ 00071 /* GDALDriverManager. */ 00072 /************************************************************************/ 00073 00084 GDALDriverManager *GetGDALDriverManager() 00085 00086 { 00087 if( poDM == NULL ) 00088 new GDALDriverManager(); 00089 00090 return( poDM ); 00091 } 00092 00093 /************************************************************************/ 00094 /* GDALDriverManager() */ 00095 /************************************************************************/ 00096 00097 GDALDriverManager::GDALDriverManager() 00098 00099 { 00100 nDrivers = 0; 00101 papoDrivers = NULL; 00102 pszHome = CPLStrdup(""); 00103 00104 CPLAssert( poDM == NULL ); 00105 poDM = this; 00106 00107 #ifdef INST_DATA 00108 CPLPushFinderLocation( INST_DATA ); 00109 #endif 00110 } 00111 00112 /************************************************************************/ 00113 /* ~GDALDriverManager() */ 00114 /* */ 00115 /* Eventually this should also likely clean up all open */ 00116 /* datasets. Or perhaps the drivers that own them should do */ 00117 /* that in their destructor? */ 00118 /************************************************************************/ 00119 00120 GDALDriverManager::~GDALDriverManager() 00121 00122 { 00123 /* -------------------------------------------------------------------- */ 00124 /* Destroy the existing drivers. */ 00125 /* -------------------------------------------------------------------- */ 00126 while( GetDriverCount() > 0 ) 00127 { 00128 GDALDriver *poDriver = GetDriver(0); 00129 00130 DeregisterDriver(poDriver); 00131 delete poDriver; 00132 } 00133 00134 /* -------------------------------------------------------------------- */ 00135 /* Cleanup local memory. */ 00136 /* -------------------------------------------------------------------- */ 00137 VSIFree( papoDrivers ); 00138 VSIFree( pszHome ); 00139 } 00140 00141 /************************************************************************/ 00142 /* GetDriverCount() */ 00143 /************************************************************************/ 00144 00153 int GDALDriverManager::GetDriverCount() 00154 00155 { 00156 return( nDrivers ); 00157 } 00158 00159 /************************************************************************/ 00160 /* GDALGetDriverCount() */ 00161 /************************************************************************/ 00162 00163 int GDALGetDriverCount() 00164 00165 { 00166 return GetGDALDriverManager()->GetDriverCount(); 00167 } 00168 00169 /************************************************************************/ 00170 /* GetDriver() */ 00171 /************************************************************************/ 00172 00183 GDALDriver * GDALDriverManager::GetDriver( int iDriver ) 00184 00185 { 00186 if( iDriver < 0 || iDriver >= nDrivers ) 00187 return NULL; 00188 else 00189 return papoDrivers[iDriver]; 00190 } 00191 00192 /************************************************************************/ 00193 /* GDALGetDriver() */ 00194 /************************************************************************/ 00195 00196 GDALDriverH GDALGetDriver( int iDriver ) 00197 00198 { 00199 return (GDALDriverH) GetGDALDriverManager()->GetDriver(iDriver); 00200 } 00201 00202 /************************************************************************/ 00203 /* RegisterDriver() */ 00204 /************************************************************************/ 00205 00225 int GDALDriverManager::RegisterDriver( GDALDriver * poDriver ) 00226 00227 { 00228 /* -------------------------------------------------------------------- */ 00229 /* If it is already registered, just return the existing */ 00230 /* index. */ 00231 /* -------------------------------------------------------------------- */ 00232 if( GetDriverByName( poDriver->pszShortName ) != NULL ) 00233 { 00234 int i; 00235 00236 for( i = 0; i < nDrivers; i++ ) 00237 { 00238 if( papoDrivers[i] == poDriver ) 00239 return i; 00240 } 00241 00242 CPLAssert( FALSE ); 00243 } 00244 00245 /* -------------------------------------------------------------------- */ 00246 /* Otherwise grow the list to hold the new entry. */ 00247 /* -------------------------------------------------------------------- */ 00248 papoDrivers = (GDALDriver **) 00249 VSIRealloc(papoDrivers, sizeof(GDALDriver *) * (nDrivers+1)); 00250 00251 papoDrivers[nDrivers] = poDriver; 00252 nDrivers++; 00253 00254 return( nDrivers - 1 ); 00255 } 00256 00257 /************************************************************************/ 00258 /* GDALRegisterDriver() */ 00259 /************************************************************************/ 00260 00261 int GDALRegisterDriver( GDALDriverH hDriver ) 00262 00263 { 00264 return GetGDALDriverManager()->RegisterDriver( (GDALDriver *) hDriver ); 00265 } 00266 00267 00268 /************************************************************************/ 00269 /* DeregisterDriver() */ 00270 /************************************************************************/ 00271 00282 void GDALDriverManager::DeregisterDriver( GDALDriver * poDriver ) 00283 00284 { 00285 int i; 00286 00287 for( i = 0; i < nDrivers; i++ ) 00288 { 00289 if( papoDrivers[i] == poDriver ) 00290 break; 00291 } 00292 00293 if( i == nDrivers ) 00294 return; 00295 00296 while( i < nDrivers-1 ) 00297 { 00298 papoDrivers[i] = papoDrivers[i+1]; 00299 i++; 00300 } 00301 nDrivers--; 00302 } 00303 00304 /************************************************************************/ 00305 /* GDALDeregisterDriver() */ 00306 /************************************************************************/ 00307 00308 void GDALDeregisterDriver( GDALDriverH hDriver ) 00309 00310 { 00311 GetGDALDriverManager()->DeregisterDriver( (GDALDriver *) hDriver ); 00312 } 00313 00314 00315 /************************************************************************/ 00316 /* GetDriverByName() */ 00317 /************************************************************************/ 00318 00329 GDALDriver * GDALDriverManager::GetDriverByName( const char * pszName ) 00330 00331 { 00332 int i; 00333 00334 for( i = 0; i < nDrivers; i++ ) 00335 { 00336 if( EQUAL(papoDrivers[i]->pszShortName, pszName) ) 00337 return papoDrivers[i]; 00338 } 00339 00340 return NULL; 00341 } 00342 00343 /************************************************************************/ 00344 /* GDALGetDriverByName() */ 00345 /************************************************************************/ 00346 00347 GDALDriverH GDALGetDriverByName( const char * pszName ) 00348 00349 { 00350 return( GetGDALDriverManager()->GetDriverByName( pszName ) ); 00351 } 00352 00353 /************************************************************************/ 00354 /* GetHome() */ 00355 /************************************************************************/ 00356 00357 const char *GDALDriverManager::GetHome() 00358 00359 { 00360 return pszHome; 00361 } 00362 00363 /************************************************************************/ 00364 /* SetHome() */ 00365 /************************************************************************/ 00366 00367 void GDALDriverManager::SetHome( const char * pszNewHome ) 00368 00369 { 00370 CPLFree( pszHome ); 00371 pszHome = CPLStrdup(pszNewHome); 00372 } 00373 00374 /************************************************************************/ 00375 /* AutoLoadDrivers() */ 00376 /************************************************************************/ 00377 00395 void GDALDriverManager::AutoLoadDrivers() 00396 00397 { 00398 char **papszSearchPath = NULL; 00399 00400 /* -------------------------------------------------------------------- */ 00401 /* Where should we look for stuff? */ 00402 /* -------------------------------------------------------------------- */ 00403 if( getenv( "GDAL_DRIVER_PATH" ) != NULL ) 00404 { 00405 #ifdef WIN32 00406 papszSearchPath = 00407 CSLTokenizeStringComplex( getenv( "GDAL_DRIVER_PATH" ), ";", 00408 TRUE, FALSE ); 00409 #else 00410 papszSearchPath = 00411 CSLTokenizeStringComplex( getenv( "GDAL_DRIVER_PATH" ), ":", 00412 TRUE, FALSE ); 00413 #endif 00414 } 00415 else 00416 { 00417 papszSearchPath = CSLAddString( papszSearchPath, "/usr/local/lib" ); 00418 00419 if( strlen(GetHome()) > 0 ) 00420 { 00421 papszSearchPath = CSLAddString( papszSearchPath, 00422 CPLFormFilename( GetHome(), "lib", NULL ) ); 00423 } 00424 } 00425 00426 /* -------------------------------------------------------------------- */ 00427 /* Scan each directory looking for files starting with gdal_ */ 00428 /* -------------------------------------------------------------------- */ 00429 for( int iDir = 0; iDir < CSLCount(papszSearchPath); iDir++ ) 00430 { 00431 char **papszFiles = CPLReadDir( papszSearchPath[iDir] ); 00432 00433 for( int iFile = 0; iFile < CSLCount(papszFiles); iFile++ ) 00434 { 00435 char *pszFuncName; 00436 const char *pszFilename; 00437 void *pRegister; 00438 00439 if( !EQUALN(papszFiles[iFile],"gdal_",5) ) 00440 continue; 00441 00442 pszFuncName = (char *) CPLCalloc(strlen(papszFiles[iFile])+20,1); 00443 sprintf( pszFuncName, "GDALRegister_%s", 00444 CPLGetBasename(papszFiles[iFile]) + 5 ); 00445 00446 pszFilename = 00447 CPLFormFilename( papszSearchPath[iDir], 00448 papszFiles[iFile], NULL ); 00449 00450 pRegister = CPLGetSymbol( pszFilename, pszFuncName ); 00451 if( pRegister == NULL ) 00452 { 00453 strcpy( pszFuncName, "GDALRegisterMe" ); 00454 pRegister = CPLGetSymbol( pszFilename, pszFuncName ); 00455 } 00456 00457 if( pRegister != NULL ) 00458 { 00459 CPLDebug( "GDAL", "Auto register %s using %s\n", 00460 pszFilename, pszFuncName ); 00461 00462 ((void (*)()) pRegister)(); 00463 } 00464 00465 CPLFree( pszFuncName ); 00466 } 00467 00468 CSLDestroy( papszFiles ); 00469 } 00470 00471 CSLDestroy( papszSearchPath ); 00472 }