KDECore
klibrary.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "klibrary.h"
00021
00022 #include <QtCore/QDir>
00023 #include <QtCore/QPointer>
00024
00025 #include <kcomponentdata.h>
00026 #include <kstandarddirs.h>
00027 #include <kpluginfactory.h>
00028 #include <kdebug.h>
00029
00030 extern QString makeLibName( const QString &libname );
00031
00032 extern QString findLibraryInternal(const QString &name, const KComponentData &cData);
00033
00034
00035 QString findLibrary(const QString &name, const KComponentData &cData)
00036 {
00037 QString libname = findLibraryInternal(name, cData);
00038 #ifdef Q_OS_WIN
00039
00040 if( libname.isEmpty() )
00041 {
00042 libname = name;
00043 QString file, path;
00044
00045 int pos = libname.lastIndexOf( '/' );
00046 if ( pos >= 0 )
00047 {
00048 file = libname.mid( pos + 1 );
00049 path = libname.left( pos );
00050 libname = path + '/' + file.mid( 3 );
00051 }
00052 else
00053 {
00054 file = libname;
00055 libname = file.mid( 3 );
00056 }
00057 if( !file.startsWith( "lib" ) )
00058 return file;
00059
00060 libname = findLibraryInternal(libname, cData);
00061 if( libname.isEmpty() )
00062 libname = name;
00063 }
00064 #endif
00065 return libname;
00066 }
00067
00068
00069 KLibrary::KLibrary(QObject *parent)
00070 : QLibrary(parent), d_ptr(0)
00071 {
00072 }
00073
00074 KLibrary::KLibrary(const QString &name, const KComponentData &cData, QObject *parent)
00075 : QLibrary(findLibrary(name, cData), parent), d_ptr(0)
00076 {
00077 }
00078
00079 KLibrary::KLibrary(const QString &name, int verNum, const KComponentData &cData, QObject *parent)
00080 : QLibrary(findLibrary(name, cData), verNum, parent), d_ptr(0)
00081 {
00082 }
00083
00084 KLibrary::~KLibrary()
00085 {
00086 }
00087
00088 class FactoryHash : public QHash<QString, QPointer<KPluginFactory> >
00089 {
00090 public:
00091 ~FactoryHash() {
00092
00093 qDeleteAll(*this);
00094 }
00095 };
00096
00097 K_GLOBAL_STATIC(FactoryHash, s_createdKde3Factories)
00098
00099 static KPluginFactory* kde3Factory(KLibrary *lib, const QByteArray &factoryname)
00100 {
00101 QByteArray symname = "init_";
00102 if(!factoryname.isEmpty()) {
00103 symname += factoryname;
00104 } else {
00105 symname += QFileInfo(lib->fileName()).fileName().split(".").first().toLatin1();
00106 }
00107
00108 const QString hashKey = lib->fileName() + QLatin1Char(':') + QString::fromAscii(symname);
00109 KPluginFactory *factory = s_createdKde3Factories->value(hashKey);
00110 if (factory) {
00111 return factory;
00112 }
00113
00114 typedef KPluginFactory* (*t_func)();
00115 t_func func = reinterpret_cast<t_func>(lib->resolveFunction( symname ));
00116 if ( !func )
00117 {
00118 #ifdef Q_OS_WIN
00119
00120 if (!factoryname.startsWith("lib"))
00121 return kde3Factory(lib, QByteArray("lib")+symname.mid(5 ));
00122 #endif
00123 kDebug(150) << "The library" << lib->fileName() << "does not offer an"
00124 << symname << "function.";
00125 return 0;
00126 }
00127
00128 factory = func();
00129
00130 if( !factory )
00131 {
00132 kDebug(150) << "The library" << lib->fileName() << "does not offer a KDE compatible factory.";
00133 return 0;
00134 }
00135 s_createdKde3Factories->insert(hashKey, factory);
00136
00137 return factory;
00138 }
00139
00140 static KPluginFactory *kde4Factory(KLibrary *lib)
00141 {
00142 const QByteArray symname("qt_plugin_instance");
00143
00144 typedef QObject* (*t_func)();
00145 t_func func = reinterpret_cast<t_func>(lib->resolveFunction(symname));
00146 if ( !func )
00147 {
00148 kDebug(150) << "The library" << lib->fileName() << "does not offer a qt_plugin_instance function.";
00149 return 0;
00150 }
00151
00152 QObject* instance = func();
00153 KPluginFactory *factory = qobject_cast<KPluginFactory *>(instance);
00154
00155 if( !factory )
00156 {
00157 kDebug(150) << "The library" << lib->fileName() << "does not offer a KDE 4 compatible factory.";
00158 return 0;
00159 }
00160 return factory;
00161 }
00162
00163 KPluginFactory* KLibrary::factory(const char* factoryname)
00164 {
00165 KPluginFactory *factory = kde4Factory(this);
00166 if (!factory)
00167 factory = kde3Factory(this, factoryname);
00168
00169 return factory;
00170 }
00171
00172 void *KLibrary::resolveSymbol( const char* symname )
00173 {
00174 return resolve( symname );
00175 }
00176
00177 KLibrary::void_function_ptr KLibrary::resolveFunction( const char* symname )
00178 {
00179 void *psym = resolve( symname );
00180 if (!psym)
00181 return 0;
00182
00183
00184
00185 ptrdiff_t tmp = reinterpret_cast<ptrdiff_t>(psym);
00186 void_function_ptr sym = reinterpret_cast<void_function_ptr>(tmp);
00187
00188 return sym;
00189 }
00190
00191 void KLibrary::setFileName(const QString &name, const KComponentData &data)
00192 {
00193 QLibrary::setFileName(findLibrary(name, data));
00194 }
00195
00196 #include "klibrary.moc"