#include #include #include #include #include // ------------------------------------------------------------------------- // Static attributes initialization // ------------------------------------------------------------------------- cpPlugins::Interface::Loader::TLibraries cpPlugins::Interface::Loader::m_Libraries; cpPlugins::Interface::Loader::TFiltersToLibrariesReferences cpPlugins::Interface::Loader::m_References; // ------------------------------------------------------------------------- cpPlugins::Interface::Loader:: Loader( ) { } // ------------------------------------------------------------------------- cpPlugins::Interface::Loader:: ~Loader( ) { } // ------------------------------------------------------------------------- void cpPlugins::Interface::Loader:: Register( const std::string& filename ) { // Canonicalize path std::string path = cpPlugins::OS::FileSystem::CanonicalPath( filename ); if( path == "" ) { throw std::runtime_error( "Unknown library file \"" + filename + "\"." ); return; } // fi // Ignore if the library is already loaded if( Self::m_Libraries.find( path ) != Self::m_Libraries.end( ) ) return; // Try to open library void* hnd = NULL; try { hnd = cpPlugins::OS::DLLManager::Open( path ); } catch( std::exception& err ) { throw std::runtime_error( err.what( ) ); } // yrt if( hnd == NULL ) throw std::runtime_error( "Unknown file type for \"" + filename + "\"." ); // Get interfacing functions TContentsFunc contents_func = NULL; try { contents_func = reinterpret_cast< TContentsFunc >( cpPlugins::OS::DLLManager::Sym( hnd, "cpPlugins_Contents" ) ); } catch( std::exception& err ) { cpPlugins::OS::DLLManager::Close( hnd ); throw std::runtime_error( "Library \"" + filename + "\" is not recognized as a cpPlugins library (i.e. \"cpPlugins_Contents\" function not found)." ); } // yrt TCreatorFunc creator_func = NULL; try { creator_func = reinterpret_cast< TCreatorFunc >( cpPlugins::OS::DLLManager::Sym( hnd, "cpPlugins_Creator" ) ); } catch( std::exception& err ) { cpPlugins::OS::DLLManager::Close( hnd ); throw std::runtime_error( "Library \"" + filename + "\" is not recognized as a cpPlugins library (i.e. \"cpPlugins_Creator\" function not found)." ); } // yrt // Keep track of handlers Self::m_Libraries[ path ] = THandlers( hnd, contents_func, creator_func ); // Get library contents std::vector< std::string > contents; contents_func( &contents ); // Register contents for( auto c : contents ) { std::vector< std::string > t = cpPlugins::OS::String::Tokenize( c, "@" ); if( t.size( ) == 2 ) Self::m_References[ t[ 1 ] ][ t[ 0 ] ] = path; } // rof } // ------------------------------------------------------------------------- void cpPlugins::Interface::Loader:: RegisterFromDirectory( const std::string& dirname ) { std::string patt = "*"; patt += cpPlugins_LIB_EXT; std::set< std::string > files = cpPlugins::OS::FileSystem::LoadDirContents( dirname, false, patt ); for( auto f : files ) { try { Register( f ); } catch( ... ) { // Do nothing } // yrt } // rof } // ------------------------------------------------------------------------- void cpPlugins::Interface::Loader:: GuessEnvironment( const std::string& dirname ) { std::stringstream fname; fname << dirname << cpPlugins_PATH_SEPARATOR << cpPlugins_PATHS; std::string buffer; if( cpPlugins::OS::FileSystem::Read( buffer, fname.str( ) ) ) { std::istringstream input( buffer ); for( std::string line; std::getline( input, line ); ) Self::RegisterFromDirectory( line ); } else Self::RegisterFromDirectory( dirname ); } // ------------------------------------------------------------------------- void cpPlugins::Interface::Loader:: SaveEnvironment( const std::string& dirname ) { std::set< std::string > locations; for( auto lIt : Self::m_Libraries ) locations.insert( cpPlugins::OS::FileSystem::SplitPath( lIt.first ).first ); std::stringstream buffer; for( auto loc : locations ) buffer << loc << std::endl; std::stringstream fname; fname << dirname << cpPlugins_PATH_SEPARATOR << cpPlugins_PATHS; cpPlugins::OS::FileSystem::Write( buffer.str( ), fname.str( ) ); } // ------------------------------------------------------------------------- void cpPlugins::Interface::Loader:: UnRegister( const std::string& filename ) { // Canonicalize path std::string path = cpPlugins::OS::FileSystem::CanonicalPath( filename ); if( path == "" ) return; auto lIt = Self::m_Libraries.find( path ); if( lIt != Self::m_Libraries.end( ) ) { // Unload handlers cpPlugins::OS::DLLManager::Close( std::get< 0 >( lIt->second ) ); Self::m_Libraries.erase( lIt ); // Erase references auto cIt = Self::m_References.begin( ); while( cIt != Self::m_References.end( ) ) { auto fIt = cIt->second.begin( ); while( fIt != cIt->second.end( ) ) { if( fIt->second == path ) { cIt->second.erase( fIt ); fIt = cIt->second.begin( ); } else ++fIt; } // elihw if( cIt->second.size( ) == 0 ) { Self::m_References.erase( cIt ); cIt = Self::m_References.begin( ); } else ++cIt; } // elihw } // fi } // ------------------------------------------------------------------------- void cpPlugins::Interface::Loader:: UnRegisterAll( ) { for( auto lIt : Self::m_Libraries ) cpPlugins::OS::DLLManager::Close( std::get< 0 >( lIt.second ) ); Self::m_Libraries.clear( ); Self::m_References.clear( ); } // ------------------------------------------------------------------------- std::map< std::string, std::set< std::string > > cpPlugins::Interface::Loader:: GetFilters( ) const { std::map< std::string, std::set< std::string > > filters; for( auto ref : Self::m_References ) for( auto fil : ref.second ) filters[ ref.first ].insert( fil.first ); return( filters ); } // ------------------------------------------------------------------------- cpPlugins::Pipeline::ProcessObject::Pointer cpPlugins::Interface::Loader:: CreateFilter( const std::string& category, const std::string& filter, const std::string& name ) { cpPlugins::Pipeline::ProcessObject::Pointer ptr = NULL; auto cIt = Self::m_References.find( category ); if( cIt != Self::m_References.end( ) ) { auto fIt = cIt->second.find( filter ); if( fIt != cIt->second.end( ) ) { auto lIt = Self::m_Libraries.find( fIt->second ); if( lIt != Self::m_Libraries.end( ) ) { auto creator_func = std::get< 2 >( lIt->second ); if( creator_func != NULL ) { itk::LightObject::Pointer l_ptr; creator_func( l_ptr, category, filter ); ptr = dynamic_cast< cpPlugins::Pipeline::ProcessObject* >( l_ptr.GetPointer( ) ); } // fi } // fi } // fi } // fi if( ptr.IsNotNull( ) ) { if( name == "" ) ptr->SetName( filter + "@" + category ); else ptr->SetName( name ); } // fi return( ptr ); } // eof - $RCSfile$