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