#include #include #include #include #include #ifdef _WIN32 # define PLUGIN_PREFIX "" # define PLUGIN_EXT ".dll" #else // Linux # define PLUGIN_PREFIX "lib" # define PLUGIN_EXT ".so" #endif // _WIN32 #define PLUGIN_CONFIG_FILE "plugins.cfg" namespace cpPlugins { namespace Interface { struct PathSeparator { bool operator()( char c ) const { #ifdef _WIN32 return( c == '\\' || c == '/' ); #else // Linux like return( c == '/' ); #endif // _WIN32 } }; } // ecapseman } // ecapseman // ------------------------------------------------------------------------- cpPlugins::Interface::Interface:: Interface( ) { this->m_Pluma.acceptProviderType< ProcessObjectProvider >( ); } // ------------------------------------------------------------------------- cpPlugins::Interface::Interface:: ~Interface( ) { this->UnloadAll( ); } // ------------------------------------------------------------------------- bool cpPlugins::Interface::Interface:: LoadDefaultConfiguration( const std::string& path ) { std::ifstream file( PLUGIN_CONFIG_FILE ); if( file ) { char buffer[ 1000 ]; while( file.getline( buffer, 1000 ) ) { // std::string line( buffer ); std::istringstream line( buffer ); std::string name, folder; std::getline( line, name, '@' ); std::getline( line, folder, '@' ); std::stringstream path; path << folder << "/" << PLUGIN_PREFIX << name << PLUGIN_EXT; this->Load( path.str( ) ); } // elihw file.close( ); return( true ); } else return( false ); } // ------------------------------------------------------------------------- bool cpPlugins::Interface::Interface:: SaveDefaultConfiguration( const std::string& path ) { std::ofstream file( PLUGIN_CONFIG_FILE ); if( file ) { auto pIt = this->m_LoadedPlugins.begin( ); for( ; pIt != this->m_LoadedPlugins.end( ); ++pIt ) { auto fIt = pIt->second.begin( ); for( ; fIt != pIt->second.end( ); ++fIt ) file << *fIt << "@" << pIt->first << std::endl; } // rof file.close( ); return( true ); } else return( false ); } // ------------------------------------------------------------------------- cpPlugins::Interface::Interface:: TClasses& cpPlugins::Interface::Interface:: GetClasses( ) { return( this->m_Classes ); } // ------------------------------------------------------------------------- const cpPlugins::Interface::Interface:: TClasses& cpPlugins::Interface::Interface:: GetClasses( ) const { return( this->m_Classes ); } // ------------------------------------------------------------------------- cpPlugins::Interface::Interface:: TLoadedPlugins& cpPlugins::Interface::Interface:: GetLoadedPlugins( ) { return( this->m_LoadedPlugins ); } // ------------------------------------------------------------------------- const cpPlugins::Interface::Interface:: TLoadedPlugins& cpPlugins::Interface::Interface:: GetLoadedPlugins( ) const { return( this->m_LoadedPlugins ); } // ------------------------------------------------------------------------- cpPlugins::Interface::ProcessObject::Pointer cpPlugins::Interface::Interface:: CreateObject( const std::string& name ) const { cpPlugins::Interface::ProcessObject::Pointer po = NULL; auto catIt = this->m_Classes.begin( ); while( catIt != this->m_Classes.end( ) ) { auto classIt = catIt->second.find( name ); if( classIt != catIt->second.end( ) ) { ProcessObjectProvider* provider = dynamic_cast< ProcessObjectProvider* >( this->m_Providers[ classIt->second ] ); if( provider != NULL ) { po = provider->create( ); po->SetName( name ); } // fi catIt = this->m_Classes.end( ); } else catIt++; } // elihw return( po ); } // ------------------------------------------------------------------------- bool cpPlugins::Interface::Interface:: Load( const std::string& path ) { bool ret = true; try { ret = this->m_Pluma.load( path ); if( ret ) { std::string folder, name; Self::_SepFName( path, folder, name ); this->m_LoadedPlugins[ folder ].push_back( name ); this->_LoadClasses( ); } // fi } catch( ... ) { ret = false; } // yrt return( ret ); } // ------------------------------------------------------------------------- bool cpPlugins::Interface::Interface:: Load( const std::string& folder, const std::string& name ) { std::string real_folder = folder; PathSeparator sep; if( sep( folder[ folder.size( ) - 1 ] ) ) real_folder = folder.substr( 0, folder.size( ) - 1 ); real_folder = std::string( realpath( real_folder.c_str( ), NULL ) ); bool ret = true; try { ret = this->m_Pluma.load( real_folder, name ); if( ret ) { // Update loaded plugins std::string prefix( PLUGIN_PREFIX ); std::string ext( PLUGIN_EXT ); std::string real_name = name; if( prefix != "" ) real_name.replace( real_name.find( prefix ), prefix.size( ), "" ); real_name.replace( real_name.find( ext ), ext.size( ), "" ); this->m_LoadedPlugins[ real_folder ].push_back( real_name ); this->_LoadClasses( ); } // fi } catch( ... ) { ret = false; } // yrt return( ret ); } // ------------------------------------------------------------------------- bool cpPlugins::Interface::Interface:: LoadFromFolder( const std::string& folder, bool r ) { try { std::list< std::string > f = this->m_Pluma.loadFromFolder( folder, r ); if( f.size( ) > 0 ) { // Update loaded plugins for( auto i = f.begin( ); i != f.end( ); ++i ) { std::string folder, name; Self::_SepFName( *i, folder, name ); this->m_LoadedPlugins[ folder ].push_back( name ); } // rof // Load classes this->_LoadClasses( ); return( true ); } else return( false ); } catch( ... ) { return( false ); } // yrt } // ------------------------------------------------------------------------- bool cpPlugins::Interface::Interface:: Unload( const std::string& name ) { bool ret = true; try { ret = this->m_Pluma.unload( name ); if( ret ) { this->m_Providers.clear( ); this->m_Classes.clear( ); // TODO: this->m_LoadedPlugins this->_LoadClasses( ); } // fi } catch( ... ) { ret = false; } // yrt return( ret ); } // ------------------------------------------------------------------------- void cpPlugins::Interface::Interface:: UnloadAll( ) { try { this->m_Pluma.unloadAll( ); } catch( ... ) { // Do nothing } // yrt this->m_Providers.clear( ); this->m_Classes.clear( ); this->m_LoadedPlugins.clear( ); } // ------------------------------------------------------------------------- bool cpPlugins::Interface::Interface:: IsLoaded( const std::string& name ) const { return( this->m_Pluma.isLoaded( name ) ); } // ------------------------------------------------------------------------- void cpPlugins::Interface::Interface:: _LoadClasses( ) { this->m_Providers.clear( ); this->m_Classes.clear( ); this->m_Pluma.getProviders( this->m_Providers ); // Get reader provider for( unsigned int i = 0; i < this->m_Providers.size( ); ++i ) { ProcessObject::Pointer d = this->m_Providers[ i ]->create( ); this->m_Classes[ d->GetClassCategory( ) ][ d->GetClassName( ) ] = i; } // rof } // ------------------------------------------------------------------------- void cpPlugins::Interface::Interface:: _SepFName( const std::string& path, std::string& folder, std::string& name ) { PathSeparator sep; // Get absolute path std::string real_path = std::string( realpath( path.c_str( ), NULL ) ); // Get name name = std::string( std::find_if( real_path.rbegin( ), real_path.rend( ), sep ).base( ), real_path.end( ) ); // Get containing folder folder = real_path; folder.replace( folder.find( name ), name.size( ), "" ); if( sep( folder[ folder.size( ) - 1 ] ) ) folder = folder.substr( 0, folder.size( ) - 1 ); // Erase prefix and extension from filename std::string prefix( PLUGIN_PREFIX ); std::string ext( PLUGIN_EXT ); if( prefix != "" ) name.replace( name.find( prefix ), prefix.size( ), "" ); name.replace( name.find( ext ), ext.size( ), "" ); } // eof - $RCSfile$