1 #include <cpPlugins/Interface/Loader.h>
2 #include <cpPlugins/OS/FileSystem.h>
3 #include <cpPlugins/OS/DLLManager.h>
4 #include <cpPlugins/OS/String.h>
7 // -------------------------------------------------------------------------
8 // Static attributes initialization
9 // -------------------------------------------------------------------------
11 cpPlugins::Interface::Loader::TLibraries
12 cpPlugins::Interface::Loader::m_Libraries;
14 cpPlugins::Interface::Loader::TFiltersToLibrariesReferences
15 cpPlugins::Interface::Loader::m_References;
17 // -------------------------------------------------------------------------
18 cpPlugins::Interface::Loader::
23 // -------------------------------------------------------------------------
24 cpPlugins::Interface::Loader::
29 // -------------------------------------------------------------------------
30 void cpPlugins::Interface::Loader::
31 Register( const std::string& filename )
34 std::string path = cpPlugins::OS::FileSystem::CanonicalPath( filename );
37 throw std::runtime_error( "Unknown library file \"" + filename + "\"." );
42 // Ignore if the library is already loaded
43 if( Self::m_Libraries.find( path ) != Self::m_Libraries.end( ) )
46 // Try to open library
50 hnd = cpPlugins::OS::DLLManager::Open( path );
52 catch( std::exception& err )
54 throw std::runtime_error( err.what( ) );
58 throw std::runtime_error( "Unknown file type for \"" + filename + "\"." );
60 // Get interfacing functions
61 TContentsFunc contents_func = NULL;
64 contents_func = reinterpret_cast< TContentsFunc >(
65 cpPlugins::OS::DLLManager::Sym( hnd, "cpPlugins_Contents" )
68 catch( std::exception& err )
70 cpPlugins::OS::DLLManager::Close( hnd );
71 throw std::runtime_error( "Library \"" + filename + "\" is not recognized as a cpPlugins library (i.e. \"cpPlugins_Contents\" function not found)." );
75 TCreatorFunc creator_func = NULL;
78 creator_func = reinterpret_cast< TCreatorFunc >(
79 cpPlugins::OS::DLLManager::Sym( hnd, "cpPlugins_Creator" )
82 catch( std::exception& err )
84 cpPlugins::OS::DLLManager::Close( hnd );
85 throw std::runtime_error( "Library \"" + filename + "\" is not recognized as a cpPlugins library (i.e. \"cpPlugins_Creator\" function not found)." );
89 // Keep track of handlers
90 Self::m_Libraries[ path ] = THandlers( hnd, contents_func, creator_func );
92 // Get library contents
93 std::vector< std::string > contents;
94 contents_func( &contents );
97 for( auto c : contents )
99 std::vector< std::string > t = cpPlugins::OS::String::Tokenize( c, "@" );
101 Self::m_References[ t[ 1 ] ][ t[ 0 ] ] = path;
106 // -------------------------------------------------------------------------
107 void cpPlugins::Interface::Loader::
108 RegisterFromDirectory( const std::string& dirname )
110 std::string patt = "*";
111 patt += cpPlugins_LIB_EXT;
112 std::set< std::string > files =
113 cpPlugins::OS::FileSystem::LoadDirContents(
116 for( auto f : files )
131 // -------------------------------------------------------------------------
132 void cpPlugins::Interface::Loader::
133 GuessEnvironment( const std::string& dirname )
135 std::stringstream fname;
136 fname << dirname << cpPlugins_PATH_SEPARATOR << cpPlugins_PATHS;
138 if( cpPlugins::OS::FileSystem::Read( buffer, fname.str( ) ) )
140 std::istringstream input( buffer );
141 for( std::string line; std::getline( input, line ); )
142 Self::RegisterFromDirectory( line );
145 Self::RegisterFromDirectory( dirname );
148 // -------------------------------------------------------------------------
149 void cpPlugins::Interface::Loader::
150 SaveEnvironment( const std::string& dirname )
152 std::set< std::string > locations;
153 for( auto lIt : Self::m_Libraries )
155 cpPlugins::OS::FileSystem::SplitPath( lIt.first ).first
157 std::stringstream buffer;
158 for( auto loc : locations )
159 buffer << loc << std::endl;
160 std::stringstream fname;
161 fname << dirname << cpPlugins_PATH_SEPARATOR << cpPlugins_PATHS;
162 cpPlugins::OS::FileSystem::Write( buffer.str( ), fname.str( ) );
165 // -------------------------------------------------------------------------
166 void cpPlugins::Interface::Loader::
167 UnRegister( const std::string& filename )
170 std::string path = cpPlugins::OS::FileSystem::CanonicalPath( filename );
174 auto lIt = Self::m_Libraries.find( path );
175 if( lIt != Self::m_Libraries.end( ) )
178 cpPlugins::OS::DLLManager::Close( std::get< 0 >( lIt->second ) );
179 Self::m_Libraries.erase( lIt );
182 auto cIt = Self::m_References.begin( );
183 while( cIt != Self::m_References.end( ) )
185 auto fIt = cIt->second.begin( );
186 while( fIt != cIt->second.end( ) )
188 if( fIt->second == path )
190 cIt->second.erase( fIt );
191 fIt = cIt->second.begin( );
197 if( cIt->second.size( ) == 0 )
199 Self::m_References.erase( cIt );
200 cIt = Self::m_References.begin( );
210 // -------------------------------------------------------------------------
211 void cpPlugins::Interface::Loader::
214 for( auto lIt : Self::m_Libraries )
215 cpPlugins::OS::DLLManager::Close( std::get< 0 >( lIt.second ) );
216 Self::m_Libraries.clear( );
217 Self::m_References.clear( );
220 // -------------------------------------------------------------------------
221 std::map< std::string, std::set< std::string > >
222 cpPlugins::Interface::Loader::
225 std::map< std::string, std::set< std::string > > filters;
226 for( auto ref : Self::m_References )
227 for( auto fil : ref.second )
228 filters[ ref.first ].insert( fil.first );
232 // -------------------------------------------------------------------------
233 cpPlugins::Pipeline::ProcessObject::Pointer cpPlugins::Interface::Loader::
235 const std::string& category, const std::string& filter,
236 const std::string& name
239 cpPlugins::Pipeline::ProcessObject::Pointer ptr = NULL;
240 auto cIt = Self::m_References.find( category );
241 if( cIt != Self::m_References.end( ) )
243 auto fIt = cIt->second.find( filter );
244 if( fIt != cIt->second.end( ) )
246 auto lIt = Self::m_Libraries.find( fIt->second );
247 if( lIt != Self::m_Libraries.end( ) )
249 auto creator_func = std::get< 2 >( lIt->second );
250 if( creator_func != NULL )
252 itk::LightObject::Pointer l_ptr;
253 creator_func( l_ptr, category, filter );
255 dynamic_cast< cpPlugins::Pipeline::ProcessObject* >(
267 if( ptr.IsNotNull( ) )
270 ptr->SetName( filter + "@" + category );
272 ptr->SetName( name );