]> Creatis software - cpPlugins.git/blobdiff - lib/cpPlugins/Interface.cxx
...
[cpPlugins.git] / lib / cpPlugins / Interface.cxx
index 259288243d5a309e803115bddb6e50a98645b210..1d883736b1af1fffdf9350921c756e500626586a 100644 (file)
@@ -5,6 +5,7 @@
 #else // cpPlugins_SYS_WINDOWS
 #  include <dlfcn.h>
 #endif // cpPlugins_SYS_WINDOWS
+#include <cpPlugins_dirent.h>
 
 // -------------------------------------------------------------------------
 cpPlugins::Interface::
@@ -64,6 +65,7 @@ SaveConfiguration( const std::string& filename ) const
   for( ; dIt != this->m_DynLibraries.end( ); ++dIt )
     out << dIt->first << std::endl;
   out.close( );
+  return( true );
 }
 
 // -------------------------------------------------------------------------
@@ -72,11 +74,25 @@ LoadPluginFile( const std::string& filename )
 {
   // Open library with its canonical path name
   auto canonical_fn = cpPlugins::PathHelper::CanonicalPath( filename );
+  if( canonical_fn == "" )
+    throw std::runtime_error(
+      std::string( "cpPlugins::Interface: Library \"" ) +
+      filename +
+      std::string( "\" does not exist." )
+      );
+
+  // Check if it was already loaded
+  if(
+    this->m_DynLibraries.find( canonical_fn ) != this->m_DynLibraries.end( )
+    )
+    return;
+
+  // Ok, try to load the library
   void* hnd = Self::_DLOpen( canonical_fn );
   if( hnd == NULL )
     throw std::runtime_error(
       std::string( "cpPlugins::Interface: Could not load library \"" ) +
-      canonical_fn +
+      filename +
       std::string( "\"" )
       );
 
@@ -104,7 +120,7 @@ LoadPluginFile( const std::string& filename )
       if( new_filter )
       {
         // Update filters container
-        TCreator creator = Self::_DLGetCreator( hnd, catIt->first, *clsIt );
+        auto creator = Self::_DLGetCreator( hnd, catIt->first, *clsIt );
         if( creator != NULL )
         {
           this->m_DynFilters[ catIt->first][ *clsIt ] =
@@ -127,6 +143,41 @@ LoadPluginFile( const std::string& filename )
     Self::_DLClose( hnd );
 }
 
+// -------------------------------------------------------------------------
+unsigned int cpPlugins::Interface::
+LoadPluginDir( const std::string& dirname )
+{
+  DIR* dir;
+  struct dirent* ent;
+  unsigned int count = 0;
+  if( ( dir = opendir( dirname.c_str( ) ) ) != NULL )
+  {
+    while( ( ent = readdir( dir ) ) != NULL )
+    {
+      try
+      {
+        this->LoadPluginFile(
+          dirname +
+          std::string( "/" ) +
+          ent->d_name
+          );
+        count++;
+      }
+      catch( ... )
+      {
+        // Ignore errors
+      } // yrt
+    } // elihw
+    closedir( dir );
+  }
+  else
+    throw std::runtime_error(
+      std::string( "cpPlugins::Interface: Could not load directory " ) +
+      std::string( "\"" ) +  dirname + std::string( "\"" )
+      );
+  return( count );
+}
+
 // -------------------------------------------------------------------------
 void cpPlugins::Interface::
 UnloadAll( )
@@ -146,13 +197,16 @@ UnloadAll( )
 cpPlugins::ProcessObject::Pointer cpPlugins::Interface::
 Create( const std::string& category, const std::string& name )
 {
-  cpPlugins::ProcessObject::Pointer filter = NULL;
+  typedef cpPlugins::ProcessObject::Pointer _TPointer;
+  _TPointer filter = NULL;
   auto catIt = this->m_DynFilters.find( category );
   if( catIt != this->m_DynFilters.end( ) )
   {
     auto clsIt = catIt->second.find( name );
     if( clsIt != catIt->second.end( ) )
-      filter = clsIt->second.second( );
+      filter =
+        ( reinterpret_cast< _TPointer* >( clsIt->second.second( ) ) )->
+        GetPointer( );
 
   } // fi
   return( filter );
@@ -177,29 +231,40 @@ cpPlugins::Interface::
 TFilters cpPlugins::Interface::
 _DLGetFilters( void* hnd )
 {
-  typedef const TFilters ( *f_t )( );
-
-  TFilters filters;
+  // Get descriptors
+  typedef const char* ( *f_t )( );
+  f_t f = NULL;
 #ifdef cpPlugins_SYS_WINDOWS
-  auto f = ( f_t )(
-    ::GetProcAddress( ( HMODULE )hnd, "cpPlugins_LoadedFilters" )
-    );
-  std::cout << f << std::endl;
+  f = ( f_t )( ::GetProcAddress( ( HMODULE )hnd, "cpPlugins_LoadedFilters" ) );
 #else // cpPlugins_SYS_WINDOWS
-  auto f = ( f_t ) dlsym( hnd, "cpPlugins_LoadedFilters" );
-  const char* err = dlerror( );
-  if( err != NULL )
+  f = ( f_t )( dlsym( hnd, "cpPlugins_LoadedFilters" ) );
+#endif // cpPlugins_SYS_WINDOWS
+  if( f == NULL )
   {
-    dlclose( hnd );
+    Self::_DLClose( hnd );
     throw std::runtime_error(
-      std::string(
-        "cpPlugins::Interface: Library not recognized as a cpPlugins library: "
-        ) + std::string( err )
+      "cpPlugins::Interface: Library not recognized as a cpPlugins library: "
       );
 
   } // fi
-#endif // cpPlugins_SYS_WINDOWS
-  filters = f( );
+  std::string descriptors = f( );
+
+  // Demangle descriptors
+  TFilters filters;
+  std::replace( descriptors.begin( ), descriptors.end( ), ';', ' ' );
+  std::istringstream str( descriptors );
+  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;
+    filters[ category ].insert( name );
+
+  } // elihw
   return( filters );
 }
 
@@ -213,16 +278,16 @@ _DLGetCreator(
   TCreator c = NULL;
   std::string func_name = category + "_" + name;
 #ifdef cpPlugins_SYS_WINDOWS
-  // TODO:
+  c = ( TCreator )( ::GetProcAddress( ( HMODULE )hnd, func_name.c_str( ) ) );
 #else // cpPlugins_SYS_WINDOWS
-  c = ( TCreator )dlsym( hnd, func_name.c_str( ) );
+  c = ( TCreator )( dlsym( hnd, func_name.c_str( ) ) );
+#endif // cpPlugins_SYS_WINDOWS
   if( c == NULL )
     throw std::runtime_error(
       std::string( "cpPlugins::Interface: Class \"" ) +
       category + std::string( ":" ) + name +
       std::string( "\" does not have a valid creator function." )
       );
-#endif // cpPlugins_SYS_WINDOWS
   return( c );
 }