X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=blobdiff_plain;f=lib%2FcpPlugins%2FInterface.cxx;h=8b5e106e5791c29d697ab123f414c56359248818;hb=ebbbc4c90ed0e4814d360686e8d4b6aab509914c;hp=58e468d29e114cc2b802a22fab6cb1b8f90d07f2;hpb=b5691a406e0f87d9f051cdd5877a4dfb299764a5;p=cpPlugins.git diff --git a/lib/cpPlugins/Interface.cxx b/lib/cpPlugins/Interface.cxx index 58e468d..8b5e106 100644 --- a/lib/cpPlugins/Interface.cxx +++ b/lib/cpPlugins/Interface.cxx @@ -6,11 +6,13 @@ # include #endif // cpPlugins_SYS_WINDOWS #include +#include // ------------------------------------------------------------------------- cpPlugins::Interface:: Interface( ) { + this->UpdatePaths( ); } // ------------------------------------------------------------------------- @@ -29,64 +31,102 @@ GetFilters( ) } // ------------------------------------------------------------------------- -bool cpPlugins::Interface:: -LoadConfiguration( const std::string& filename ) +void cpPlugins::Interface:: +UpdatePaths( ) { - std::ifstream in( filename.c_str( ) ); - if( !in ) - return( false ); + // Load environment configuration + this->m_Paths.clear( ); + char* p = std::getenv( cpPlugins_PATHS ); + if( p != NULL ) + cpPlugins::TokenizeString( this->m_Paths, p, cpPlugins_SEPARATOR ); + this->m_Paths.push_back( "." ); +} - this->UnloadAll( ); - std::string line; - while( std::getline( in, line ) ) +// ------------------------------------------------------------------------- +void cpPlugins::Interface:: +GuessAccesiblePlugins( ) +{ + for( auto i = this->m_Paths.begin( ); i != this->m_Paths.end( ); ++i ) + try { this->LoadPluginDir( *i ); } catch( ... ) { } +} + +// ------------------------------------------------------------------------- +void cpPlugins::Interface:: +LoadPlugin( const std::string& name ) +{ + std::stringstream str; + str << cpPlugins_LIB_PREFIX << name << "." << cpPlugins_LIB_EXT; + std::string base_name = str.str( ); + bool found = false; + for( auto i = this->m_Paths.begin( ); i != this->m_Paths.end( ); ++i ) { + std::string filename = *i; + if( i->back( ) != '/' ) + filename += std::string( "/" ); + filename += base_name; try { - this->LoadPluginFile( line ); + this->LoadPluginFile( filename ); + found = true; } catch( ... ) { - // Do nothing - } // yrt - } // elihw - return( true ); + } // rof + if( !found ) + throw std::runtime_error( + std::string( "cpPlugins::Interface: Plugins library \"" ) + + name + + std::string( "\" not found." ) + ); } // ------------------------------------------------------------------------- -bool cpPlugins::Interface:: -SaveConfiguration( const std::string& filename ) const +void cpPlugins::Interface:: +LoadPluginDir( const std::string& dirname ) { - std::ofstream out( filename.c_str( ) ); - if( !out ) - return( false ); - auto dIt = this->m_DynLibraries.begin( ); - for( ; dIt != this->m_DynLibraries.end( ); ++dIt ) - out << dIt->first << std::endl; - out.close( ); - return( true ); + DIR* dir; + struct dirent* ent; + if( ( dir = opendir( dirname.c_str( ) ) ) != NULL ) + { + while( ( ent = readdir( dir ) ) != NULL ) + { + try + { + this->LoadPluginFile( + dirname + + std::string( "/" ) + + ent->d_name + ); + } + catch( ... ) { } + + } // elihw + closedir( dir ); + } + else + throw std::runtime_error( + std::string( "cpPlugins::Interface: Could not load directory " ) + + std::string( "\"" ) + dirname + std::string( "\"" ) + ); } // ------------------------------------------------------------------------- void cpPlugins::Interface:: LoadPluginFile( const std::string& filename ) { - // Open library with its canonical path name - auto canonical_fn = cpPlugins::PathHelper::CanonicalPath( filename ); - if( canonical_fn == "" ) + // Canonical filename + auto canonical = cpPlugins::CanonicalPath( filename ); + if( canonical == "" ) throw std::runtime_error( std::string( "cpPlugins::Interface: Library \"" ) + filename + std::string( "\" does not exist." ) ); - // Check if it was already loaded - if( this->m_DynLibraries.find( canonical_fn ) != this->m_DynLibraries.end( ) ) - return; - - // Ok, try to load the library - void* hnd = Self::_DLOpen( canonical_fn ); + // Try to load the library + void* hnd = Self::_DLOpen( canonical ); if( hnd == NULL ) throw std::runtime_error( std::string( "cpPlugins::Interface: Could not load library \"" ) + @@ -94,6 +134,13 @@ LoadPluginFile( const std::string& filename ) std::string( "\"" ) ); + // Get plugin name + std::string pl_name = Self::_DLGetName( hnd ); + + // Check if it was already loaded + if( this->m_DynLibraries.find( pl_name ) != this->m_DynLibraries.end( ) ) + return; + // Load filters TFilters filters = Self::_DLGetFilters( hnd ); @@ -122,7 +169,7 @@ LoadPluginFile( const std::string& filename ) if( creator != NULL ) { this->m_DynFilters[ catIt->first][ *clsIt ] = - TDynFunc( canonical_fn, creator ); + TDynFunc( pl_name, creator ); this->m_Filters[ catIt->first ].insert( *clsIt ); save_handler = true; @@ -136,42 +183,11 @@ LoadPluginFile( const std::string& filename ) // Keep dynlib handler, if needed if( save_handler ) - this->m_DynLibraries[ canonical_fn ] = hnd; + this->m_DynLibraries[ pl_name ] = TDynFileInfo( canonical, hnd ); else Self::_DLClose( hnd ); } -// ------------------------------------------------------------------------- -unsigned int cpPlugins::Interface:: -LoadPluginDir( const std::string& dirname ) -{ - DIR* dir; - struct dirent* ent; - unsigned int count = 0; - if( ( dir = opendir( dirname.c_str( ) ) ) != NULL ) - { - while( ( ent = readdir( dir ) ) != NULL ) - { - try - { - this->LoadPluginFile( ent->d_name ); - count++; - } - catch( ... ) - { - // Ignore errors - } // yrt - } // elihw - closedir( dir ); - } - else - throw std::runtime_error( - std::string( "cpPlugins::Interface: Could not load directory " ) + - std::string( "\"" ) + dirname + std::string( "\"" ) - ); - return( count ); -} - // ------------------------------------------------------------------------- void cpPlugins::Interface:: UnloadAll( ) @@ -181,7 +197,7 @@ UnloadAll( ) d != this->m_DynLibraries.end( ); ++d ) - Self::_DLClose( d->second ); + Self::_DLClose( d->second.second ); this->m_DynLibraries.clear( ); this->m_DynFilters.clear( ); this->m_Filters.clear( ); @@ -206,6 +222,48 @@ Create( const std::string& category, const std::string& name ) return( filter ); } +// ------------------------------------------------------------------------- +std::string cpPlugins::Interface:: +GetPluginName( const std::string& category, const std::string& name ) const +{ + std::string plugin = ""; + auto catIt = this->m_DynFilters.find( category ); + if( catIt != this->m_DynFilters.end( ) ) + { + auto clsIt = catIt->second.find( name ); + if( clsIt != catIt->second.end( ) ) + plugin = clsIt->second.first; + + } // fi + return( plugin ); +} + +// ------------------------------------------------------------------------- +std::string cpPlugins::Interface:: +GetPluginName( const ProcessObject* obj ) const +{ + if( obj != NULL ) + return( + this->GetPluginName( + obj->GetClassCategory( ), + obj->GetClassName( ) + ) + ); + else + return( "" ); +} + +// ------------------------------------------------------------------------- +std::set< std::string > cpPlugins::Interface:: +GetPlugins( ) const +{ + std::set< std::string > res; + auto i = this->m_DynLibraries.begin( ); + for( ; i != this->m_DynLibraries.end( ); ++i ) + res.insert( i->first ); + return( res ); +} + // ------------------------------------------------------------------------- void* cpPlugins::Interface:: _DLOpen( const std::string& fname ) @@ -220,6 +278,29 @@ _DLOpen( const std::string& fname ) return( hnd ); } +// ------------------------------------------------------------------------- +const char* cpPlugins::Interface:: +_DLGetName( void* hnd ) +{ + // Get descriptors + typedef const char* ( *f_t )( ); + f_t f = NULL; +#ifdef cpPlugins_SYS_WINDOWS + f = ( f_t )( ::GetProcAddress( ( HMODULE )hnd, "cpPlugins_Name" ) ); +#else // cpPlugins_SYS_WINDOWS + f = ( f_t )( dlsym( hnd, "cpPlugins_Name" ) ); +#endif // cpPlugins_SYS_WINDOWS + if( f == NULL ) + { + Self::_DLClose( hnd ); + throw std::runtime_error( + "cpPlugins::Interface: Library not recognized as a cpPlugins library." + ); + + } // fi + return( f( ) ); +} + // ------------------------------------------------------------------------- cpPlugins::Interface:: TFilters cpPlugins::Interface:: @@ -237,7 +318,7 @@ _DLGetFilters( void* hnd ) { Self::_DLClose( hnd ); throw std::runtime_error( - "cpPlugins::Interface: Library not recognized as a cpPlugins library: " + "cpPlugins::Interface: Library not recognized as a cpPlugins library." ); } // fi