#include #include #include #include // ------------------------------------------------------------------------- cpPlugins::Interface::Plugins:: Pointer cpPlugins::Interface::Plugins:: New( ) { static Pointer singleton = NULL; if( singleton.IsNull( ) ) singleton = new Self( ); return( singleton ); } // ------------------------------------------------------------------------- itk::LightObject::Pointer cpPlugins::Interface::Plugins:: CreateAnother( ) const { itk::LightObject::Pointer smartPtr; smartPtr = NULL; return( smartPtr ); } // ------------------------------------------------------------------------- cpPlugins::Interface::Plugins:: Pointer cpPlugins::Interface::Plugins:: Clone( ) const { Pointer r = NULL; return( r ); } // ------------------------------------------------------------------------- cpPlugins::Interface::Plugins:: TStrings cpPlugins::Interface::Plugins:: GetLibraries( ) const { TStrings res; for( auto i = this->m_Libraries.begin( ); i != this->m_Libraries.end( ); ++i ) res.insert( i->first ); return( res ); } // ------------------------------------------------------------------------- cpPlugins::Interface::Plugins:: TStrings cpPlugins::Interface::Plugins:: GetPlugins( ) const { TStrings res; for( auto i = this->m_Plugins.begin( ); i != this->m_Plugins.end( ); ++i ) res.insert( i->first ); return( res ); } // ------------------------------------------------------------------------- cpPlugins::Interface::Plugins:: TStrings cpPlugins::Interface::Plugins:: GetCategories( ) const { TStrings res; for( auto i = this->m_Filters.begin( ); i != this->m_Filters.end( ); ++i ) res.insert( i->first ); return( res ); } // ------------------------------------------------------------------------- cpPlugins::Interface::Plugins:: TStrings cpPlugins::Interface::Plugins:: GetFilters( const std::string& category ) const { TStrings res; auto cIt = this->m_Filters.find( category ); if( cIt != this->m_Filters.end( ) ) for( auto i = cIt->second.begin( ); i != cIt->second.end( ); ++i ) res.insert( i->first ); return( res ); } // ------------------------------------------------------------------------- void cpPlugins::Interface::Plugins:: AddEnvironments( const std::string& env ) { std::vector< std::string > directories; cpExtensions::Tokenize( directories, env, cpPlugins_ENV_SEPARATOR ); for( auto dir = directories.begin( ); dir != directories.end( ); ++dir ) this->m_Paths.insert( cpExtensions::CanonicalPath( *dir ) ); } // ------------------------------------------------------------------------- void cpPlugins::Interface::Plugins:: LoadEnvironments( ) { std::set< std::string > libs; for( auto d = this->m_Paths.begin( ); d != this->m_Paths.end( ); ++d ) { std::stringstream fname; fname << *d << cpPlugins_PATH_SEPARATOR << cpPlugins_CONFIG; std::string buffer; if( cpExtensions::Read( buffer, fname.str( ) ) ) { std::istringstream input( buffer ); for( std::string line; std::getline( input, line ); ) { auto pos = line.find( "*" ); if( pos != std::string::npos ) { std::string dname, fname; cpPlugins::OS::SplitPath( dname, fname, line ); auto files = cpPlugins::OS::LoadDirContents( dname, false, fname ); for( auto fIt = files.begin( ); fIt != files.end( ); ++fIt ) libs.insert( *fIt ); } else libs.insert( line ); } // rof } // fi } // rof for( auto l = libs.begin( ); l != libs.end( ); ++l ) { std::string lib = cpExtensions::CanonicalPath( *l ); if( lib != "" ) { if( this->m_Libraries.find( lib ) == this->m_Libraries.end( ) ) { std::string error = ""; void* hnd = cpPlugins::OS::DLLManager::Load( lib, error ); if( hnd != NULL ) this->m_Libraries[ lib ] = hnd; } // fi } // fi } // rof } // ------------------------------------------------------------------------- void cpPlugins::Interface::Plugins:: LoadPaths( const std::string& dir ) { std::stringstream fname, envs; fname << dir; if( !cpExtensions::IsPathSeparator( dir.back( ) ) ) fname << cpExtensions_PATH_SEPARATOR; fname << cpPlugins_PATHS; std::string buffer; if( cpExtensions::Read( buffer, fname.str( ) ) ) { std::istringstream input( buffer ); for( std::string line; std::getline( input, line ); ) envs << line << cpPlugins_ENV_SEPARATOR; } // fi if( envs.str( ).size( ) > 0 ) this->AddEnvironments( envs.str( ) ); } // ------------------------------------------------------------------------- void cpPlugins::Interface::Plugins:: SavePaths( const std::string& dir ) const { std::stringstream buffer; for( auto i = this->m_Paths.begin( ); i != this->m_Paths.end( ); ++i ) buffer << *i << std::endl; std::stringstream fname; fname << dir; if( !cpExtensions::IsPathSeparator( dir.back( ) ) ) fname << cpExtensions_PATH_SEPARATOR; fname << cpPlugins_PATHS; if( !cpExtensions::Write( buffer.str( ), fname.str( ) ) ) throw std::runtime_error( "Error writing environment file." ); } // ------------------------------------------------------------------------- void cpPlugins::Interface::Plugins:: LoadFile( const std::string& fname ) { // Resolve canonical filename std::string can_name = cpExtensions::CanonicalPath( fname ); if( can_name == "" ) throw std::runtime_error( std::string( "Loading file: can't find library \"" ) + fname + std::string( "\"" ) ); if( this->m_Plugins.find( can_name ) != this->m_Plugins.end( ) ) return; // Load the library std::string error = ""; void* hnd = cpPlugins::OS::DLLManager::Load( can_name, error ); if( hnd == NULL ) throw std::runtime_error( std::string( "Loading plugin library: " ) + error ); // Get plugins name typedef const char* ( *_TFunction )( ); _TFunction plugins_name_function = ( _TFunction )( cpPlugins::OS::DLLManager::GetFunctionHandle( hnd, "cpPlugins_Name" ) ); if( plugins_name_function == NULL ) { cpPlugins::OS::DLLManager::UnLoad( hnd ); throw std::runtime_error( std::string( "Library \"" ) + can_name + std::string( "\" not recognized as a cpPlugins library" ) ); } // fi std::string plugins_name = plugins_name_function( ); // Get loaded filters _TFunction function = ( _TFunction )( cpPlugins::OS::DLLManager::GetFunctionHandle( hnd, "cpPlugins_LoadedFilters" ) ); if( function == NULL ) { cpPlugins::OS::DLLManager::UnLoad( hnd ); throw std::runtime_error( std::string( "Library \"" ) + can_name + std::string( "\" not recognized as a cpPlugins library" ) ); } // fi std::string descriptors = function( ); std::replace( descriptors.begin( ), descriptors.end( ), ';', ' ' ); std::istringstream str( descriptors ); TFilters filters; while( str ) { std::string value, category, name; str >> value; if( value == "" ) continue; std::replace( value.begin( ), value.end( ), ':', ' ' ); std::istringstream value_str( value ); value_str >> category >> name; // Check if the filter has been already loaded bool found = false; auto fIt = this->m_Filters.find( category ); if( fIt != this->m_Filters.end( ) ) found = fIt->second.find( name ) != fIt->second.end( ); if( found ) { cpPlugins::OS::DLLManager::UnLoad( hnd ); throw std::runtime_error( std::string( "Filter \"" ) + category + std::string( "::" ) + name + std::string( "\" already exists." ) ); } // fi // Get filter creator TCreator creator = ( TCreator )( cpPlugins::OS::DLLManager::GetFunctionHandle( hnd, category + "_" + name ) ); if( creator == NULL ) { cpPlugins::OS::DLLManager::UnLoad( hnd ); throw std::runtime_error( std::string( "Filter \"" ) + category + std::string( "::" ) + name + std::string( "\" does not have a valid creator." ) ); } // fi TCreatorData data; data.PluginName = plugins_name; data.LibraryHandle = hnd; data.Creator = creator; filters[ category ][ name ] = data; } // elihw // Keep track of all loaded handlers for( auto cIt = filters.begin( ); cIt != filters.end( ); ++cIt ) for( auto nIt = cIt->second.begin( ); nIt != cIt->second.end( ); ++nIt ) this->m_Filters[ cIt->first ][ nIt->first ] = nIt->second; this->m_Plugins[ can_name ] = hnd; } // ------------------------------------------------------------------------- void cpPlugins::Interface::Plugins:: LoadPlugin( const std::string& pname ) { std::stringstream fname; fname << cpPlugins_LIB_PREFIX << pname << cpPlugins_LIB_EXT; unsigned int count = 0; for( auto i = this->m_Paths.begin( ); i != this->m_Paths.end( ); ++i ) { std::stringstream dir; dir << *i; if( !cpExtensions::IsPathSeparator( i->back( ) ) ) dir << cpExtensions_PATH_SEPARATOR; dir << fname.str( ); try { this->LoadFile( dir.str( ) ); } catch( ... ) { count++; } // yrt } // rof // Throw error, if any if( count == this->m_Paths.size( ) ) throw std::runtime_error( std::string( "Could not load plugin " ) + std::string( "\"" ) + pname + std::string( "\" from any registered path." ) ); } // ------------------------------------------------------------------------- void cpPlugins::Interface::Plugins:: LoadDirectory( const std::string& dirname ) { std::stringstream pat; pat << "*" << cpPlugins_LIB_EXT; auto libs = cpPlugins::OS::LoadDirContents( dirname, false, pat.str( ) ); for( auto lIt = libs.begin( ); lIt != libs.end( ); ++lIt ) { try { this->LoadFile( *lIt ); } catch( ... ) { } } // rof } // ------------------------------------------------------------------------- void cpPlugins::Interface::Plugins:: GuessPlugins( ) { for( auto i = this->m_Paths.begin( ); i != this->m_Paths.end( ); ++i ) { try { this->LoadDirectory( *i ); } catch( ... ) { } } // rof } // ------------------------------------------------------------------------- cpPlugins::Interface::Plugins::TProcess::Pointer cpPlugins::Interface::Plugins:: CreateProcessObject( const std::string& category, const std::string& name ) { typedef cpPlugins::BaseObjects::ProcessObject::Pointer _Ptr; _Ptr o = NULL; auto cIt = this->m_Filters.find( category ); if( cIt != this->m_Filters.end( ) ) { auto nIt = cIt->second.find( name ); if( nIt != cIt->second.end( ) ) { o = reinterpret_cast< _Ptr* >( nIt->second.Creator( ) )->GetPointer( ); o->SetName( name ); o->SetPluginName( nIt->second.PluginName ); } // fi } // fi return( o ); } // ------------------------------------------------------------------------- cpPlugins::Interface::Plugins:: Plugins( ) : Superclass( ) { #ifdef cpPlugins_OS_Windows char* p; size_t size; _dupenv_s( &p, &size, cpPlugins_PATHS ); #else // cpPlugins_OS_Windows char* p = std::getenv( cpPlugins_PATHS ); #endif // cpPlugins_OS_Windows std::stringstream str; if( p != NULL ) str << p << cpPlugins_ENV_SEPARATOR; str << "."; this->AddEnvironments( str.str( ) ); } // ------------------------------------------------------------------------- cpPlugins::Interface::Plugins:: ~Plugins( ) { } // ------------------------------------------------------------------------- void cpPlugins::Interface::Plugins:: PrintSelf( std::ostream& os, itk::Indent indent ) const { // Show data os << indent << "----- PATHS -----" << std::endl; auto paths = this->GetPaths( ); for( auto paIt = paths.begin( ); paIt != paths.end( ); ++paIt ) os << indent << *paIt << std::endl; os << indent << std::endl << indent << "----- PLUGINS -----" << std::endl; auto plugins = this->GetPlugins( ); for( auto plIt = plugins.begin( ); plIt != plugins.end( ); ++plIt ) os << indent << *plIt << std::endl; os << indent << std::endl << indent << "----- FILTERS -----" << std::endl; auto categories = this->GetCategories( ); for( auto cIt = categories.begin( ); cIt != categories.end( ); ++cIt ) { os << indent << "** Category: " << *cIt << " **" << std::endl; auto filters = this->GetFilters( *cIt ); for( auto fIt = filters.begin( ); fIt != filters.end( ); ++fIt ) os << indent << indent << indent << "Filter: " << *fIt << std::endl; } // rof } // eof - $RCSfile$