1 #include <cpPlugins/Interface.h>
3 #ifdef cpPlugins_SYS_WINDOWS
5 #else // cpPlugins_SYS_WINDOWS
7 #endif // cpPlugins_SYS_WINDOWS
8 #include <cpPlugins_dirent.h>
10 // -------------------------------------------------------------------------
11 cpPlugins::Interface::
16 // -------------------------------------------------------------------------
17 cpPlugins::Interface::
23 // -------------------------------------------------------------------------
24 const cpPlugins::Interface::
25 TFilters& cpPlugins::Interface::
28 return( this->m_Filters );
31 // -------------------------------------------------------------------------
32 bool cpPlugins::Interface::
33 LoadConfiguration( const std::string& filename )
35 std::ifstream in( filename.c_str( ) );
41 while( std::getline( in, line ) )
45 this->LoadPluginFile( line );
57 // -------------------------------------------------------------------------
58 bool cpPlugins::Interface::
59 SaveConfiguration( const std::string& filename ) const
61 std::ofstream out( filename.c_str( ) );
64 auto dIt = this->m_DynLibraries.begin( );
65 for( ; dIt != this->m_DynLibraries.end( ); ++dIt )
66 out << dIt->first << std::endl;
71 // -------------------------------------------------------------------------
72 void cpPlugins::Interface::
73 LoadPluginFile( const std::string& filename )
75 // Open library with its canonical path name
76 auto canonical_fn = cpPlugins::PathHelper::CanonicalPath( filename );
77 if( canonical_fn == "" )
78 throw std::runtime_error(
79 std::string( "cpPlugins::Interface: Library \"" ) +
81 std::string( "\" does not exist." )
83 void* hnd = Self::_DLOpen( canonical_fn );
85 throw std::runtime_error(
86 std::string( "cpPlugins::Interface: Could not load library \"" ) +
92 TFilters filters = Self::_DLGetFilters( hnd );
94 // Save the loaded filters info
95 bool save_handler = false;
96 for( auto catIt = filters.begin( ); catIt != filters.end( ); ++catIt )
98 // Check if the filter is completely new
99 auto act_catIt = this->m_Filters.find( catIt->first );
101 auto clsIt = catIt->second.begin( );
102 clsIt != catIt->second.end( );
106 bool new_filter = true;
107 if( act_catIt != this->m_Filters.end( ) )
109 ( act_catIt->second.find( *clsIt ) == act_catIt->second.end( ) );
114 // Update filters container
115 auto creator = Self::_DLGetCreator( hnd, catIt->first, *clsIt );
116 if( creator != NULL )
118 this->m_DynFilters[ catIt->first][ *clsIt ] =
119 TDynFunc( canonical_fn, creator );
120 this->m_Filters[ catIt->first ].insert( *clsIt );
131 // Keep dynlib handler, if needed
133 this->m_DynLibraries[ canonical_fn ] = hnd;
135 Self::_DLClose( hnd );
138 // -------------------------------------------------------------------------
139 void cpPlugins::Interface::
140 LoadPluginDir( const std::string& dirname )
145 if( (dir = opendir ( dirname.c_str( ) ) ) != NULL)
147 while ((ent = readdir (dir)) != NULL) {
148 printf ("%s\n", ent->d_name);
152 std::cerr << "error" << std::endl;
156 // -------------------------------------------------------------------------
157 void cpPlugins::Interface::
161 auto d = this->m_DynLibraries.begin( );
162 d != this->m_DynLibraries.end( );
165 Self::_DLClose( d->second );
166 this->m_DynLibraries.clear( );
167 this->m_DynFilters.clear( );
168 this->m_Filters.clear( );
171 // -------------------------------------------------------------------------
172 cpPlugins::ProcessObject::Pointer cpPlugins::Interface::
173 Create( const std::string& category, const std::string& name )
175 typedef cpPlugins::ProcessObject::Pointer _TPointer;
176 _TPointer filter = NULL;
177 auto catIt = this->m_DynFilters.find( category );
178 if( catIt != this->m_DynFilters.end( ) )
180 auto clsIt = catIt->second.find( name );
181 if( clsIt != catIt->second.end( ) )
183 ( reinterpret_cast< _TPointer* >( clsIt->second.second( ) ) )->
190 // -------------------------------------------------------------------------
191 void* cpPlugins::Interface::
192 _DLOpen( const std::string& fname )
195 #ifdef cpPlugins_SYS_WINDOWS
196 hnd = ::LoadLibraryA( fname.c_str( ) );
197 #else // cpPlugins_SYS_WINDOWS
198 hnd = dlopen( fname.c_str( ), RTLD_NOW | RTLD_GLOBAL );
200 #endif // cpPlugins_SYS_WINDOWS
204 // -------------------------------------------------------------------------
205 cpPlugins::Interface::
206 TFilters cpPlugins::Interface::
207 _DLGetFilters( void* hnd )
210 typedef const char* ( *f_t )( );
212 #ifdef cpPlugins_SYS_WINDOWS
213 f = ( f_t )( ::GetProcAddress( ( HMODULE )hnd, "cpPlugins_LoadedFilters" ) );
214 #else // cpPlugins_SYS_WINDOWS
215 f = ( f_t )( dlsym( hnd, "cpPlugins_LoadedFilters" ) );
216 #endif // cpPlugins_SYS_WINDOWS
219 Self::_DLClose( hnd );
220 throw std::runtime_error(
221 "cpPlugins::Interface: Library not recognized as a cpPlugins library: "
225 std::string descriptors = f( );
227 // Demangle descriptors
229 std::replace( descriptors.begin( ), descriptors.end( ), ';', ' ' );
230 std::istringstream str( descriptors );
233 std::string value, category, name;
237 std::replace( value.begin( ), value.end( ), ':', ' ' );
238 std::istringstream value_str( value );
239 value_str >> category >> name;
240 filters[ category ].insert( name );
246 // -------------------------------------------------------------------------
247 cpPlugins::Interface::
248 TCreator cpPlugins::Interface::
250 void* hnd, const std::string& category, const std::string& name
254 std::string func_name = category + "_" + name;
255 #ifdef cpPlugins_SYS_WINDOWS
256 c = ( TCreator )( ::GetProcAddress( ( HMODULE )hnd, func_name.c_str( ) ) );
257 #else // cpPlugins_SYS_WINDOWS
258 c = ( TCreator )( dlsym( hnd, func_name.c_str( ) ) );
259 #endif // cpPlugins_SYS_WINDOWS
261 throw std::runtime_error(
262 std::string( "cpPlugins::Interface: Class \"" ) +
263 category + std::string( ":" ) + name +
264 std::string( "\" does not have a valid creator function." )
269 // -------------------------------------------------------------------------
270 void cpPlugins::Interface::
271 _DLClose( void* hnd )
273 #ifdef cpPlugins_SYS_WINDOWS
274 ::FreeLibrary( ( HMODULE )hnd );
275 #else // cpPlugins_SYS_WINDOWS
277 #endif // cpPlugins_SYS_WINDOWS