]> Creatis software - cpPlugins.git/blob - lib/cpPlugins/Interface.cxx
First dump for version 0.1.0
[cpPlugins.git] / lib / cpPlugins / Interface.cxx
1 #include <cpPlugins/Interface.h>
2
3 #include <map>
4 #include <set>
5 #include <string>
6
7 #ifdef cpPlugins_SYS_WINDOWS
8 #else // cpPlugins_SYS_WINDOWS
9 #  include <dlfcn.h>
10 #endif // cpPlugins_SYS_WINDOWS
11
12
13 // -------------------------------------------------------------------------
14 cpPlugins::Interface::
15 Interface( )
16 {
17 }
18
19 // -------------------------------------------------------------------------
20 cpPlugins::Interface::
21 ~Interface( )
22 {
23   this->UnloadAll( );
24 }
25
26 // -------------------------------------------------------------------------
27 const cpPlugins::Interface::
28 TFilters& cpPlugins::Interface::
29 GetFilters( )
30 {
31   return( this->m_Filters );
32 }
33
34 // -------------------------------------------------------------------------
35 void cpPlugins::Interface::
36 LoadPluginFile( const std::string& filename )
37 {
38   auto canonical_fn = cpPlugins::PathHelper::CanonicalPath( filename );
39   void* hnd = NULL;
40   std::map< std::string, std::set< std::string > > filters;
41 #ifdef cpPlugins_SYS_WINDOWS
42   // TODO:
43 #else // cpPlugins_SYS_WINDOWS
44
45   // Try to load canonical filename and clean error messages
46   hnd = dlopen( canonical_fn.c_str( ), RTLD_NOW | RTLD_GLOBAL );
47   if( hnd == NULL )
48     throw std::runtime_error(
49       std::string( "cpPlugins::Interface: Could not load library \"" ) +
50       canonical_fn +
51       std::string( "\"" )
52       );
53   dlerror( );
54
55   // Init plugins
56   typedef const std::map< std::string, std::set< std::string > > ( *func_t )( );
57   auto func = ( func_t ) dlsym( hnd, "LoadedFilters" );
58   const char* func_error = dlerror( );
59   if( func_error != NULL )
60   {
61     dlclose( hnd );
62     throw std::runtime_error(
63       std::string( "cpPlugins::Interface: Library \"" ) +
64       canonical_fn +
65       std::string( "\" not recognized as a cpPlugins library." )
66       );
67
68   } // fi
69   filters = func( );
70 #endif // cpPlugins_SYS_WINDOWS
71   if( hnd != NULL )
72   {
73     // Save the loaded filters names
74     for( auto cIt = filters.begin( ); cIt != filters.end( ); ++cIt )
75     {
76       auto colIt = this->m_Filters.find( cIt->first );
77       for( auto fIt = cIt->second.begin( ); fIt != cIt->second.end( ); ++fIt )
78       {
79         bool found = false;
80         if( colIt != this->m_Filters.end( ) )
81         {
82           auto rowIt = colIt->second.find( *fIt );
83           if( rowIt != colIt->second.end( ) )
84             found = true;
85
86         } // fi
87         if( !found )
88           this->m_Filters[ cIt->first ][ *fIt ] = canonical_fn;
89
90       } // rof
91
92     } // rof
93
94     // Save the hnd
95     this->m_Plugins[ canonical_fn ] = hnd;
96   }
97   else
98     throw std::runtime_error(
99       "cpPlugins::Interface: Operative system not yet supported."
100       );
101 }
102
103 // -------------------------------------------------------------------------
104 void cpPlugins::Interface::
105 UnloadAll( )
106 {
107   auto pIt = this->m_Plugins.begin( );
108   for( ; pIt != this->m_Plugins.end( ); ++pIt )
109   {
110 #ifdef cpPlugins_SYS_WINDOWS
111 #else // cpPlugins_SYS_WINDOWS
112     dlclose( pIt->second );
113 #endif // cpPlugins_SYS_WINDOWS
114   } // rof
115   this->m_Plugins.clear( );
116   this->m_Filters.clear( );
117 }
118
119 // -------------------------------------------------------------------------
120 cpPlugins::ProcessObject::Pointer cpPlugins::Interface::
121 Create( const std::string& category, const std::string& name )
122 {
123   cpPlugins::ProcessObject::Pointer filter;
124   auto cIt = this->m_Filters.find( category );
125   if( cIt != this->m_Filters.end( ) )
126   {
127     auto nIt = cIt->second.find( name );
128     if( nIt != cIt->second.end( ) )
129     {
130       auto pIt = this->m_Plugins.find( nIt->second );
131       if( pIt != this->m_Plugins.end( ) )
132       {
133 #ifdef cpPlugins_SYS_WINDOWS
134 #else // cpPlugins_SYS_WINDOWS
135         std::string func_name = category + "_" + name;
136         typedef cpPlugins::ProcessObject::Pointer ( *func_t )( );
137         auto func = ( func_t ) dlsym( pIt->second, func_name.c_str( ) );
138         if( func == NULL )
139         {
140           throw std::runtime_error(
141             std::string( "cpPlugins::Interface: Class \"" ) +
142             category + std::string( ":" ) + name +
143             std::string( "\" does not have a valid creator function." )
144             );
145
146         } // fi
147         filter = func( );
148 #endif // cpPlugins_SYS_WINDOWS
149       } // fi
150
151     } // fi
152
153   } // fi
154   return( filter );
155 }
156
157 // eof - $RCSfile$