Main Page   Class Hierarchy   Compound List   File List   Compound Members   File Members   Related Pages  

gdaldrivermanager.cpp

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 }

Generated at Sat Dec 21 14:01:59 2002 for GDAL by doxygen1.2.3-20001105 written by Dimitri van Heesch, © 1997-2000