4
0
mirror of https://github.com/QuasarApp/qca.git synced 2025-05-09 17:29:33 +00:00

new plugin code, based on QPlugin

svn path=/trunk/kdesupport/qca/; revision=393688
This commit is contained in:
Justin Karneges 2005-02-28 02:28:23 +00:00
parent 7dc68f5e61
commit 0e1c7408e8
6 changed files with 68 additions and 74 deletions

3
TODO

@ -1,6 +1,7 @@
* Additional unit tests
* Bundle root certificates to be used on platforms without a system store
(we need to choose a reliable source, maybe mozilla or debian? kde??)
* Update to latest Botan, and remake the botantools patch as appropriate
* API documentation
clean up Algorithm
@ -16,13 +17,11 @@
threading (safety, usability) in API and plugins. look for singletons
it's possible we use QSecureArray in some unnecessary places
don't forget to QCA_EXPORT everything
ensure plugin system is upgradable this time. no createProvider3(), please..
standardize on count() vs size() when iterating?
* finish API:
do something about qhostaddress in SASL. try to remove QtNetwork dependency?
move to qt 4
use qplugin
use qshareddata for thread-safe objects
turn ambiguous bool args into enums
create include files for all class names?

@ -287,6 +287,12 @@ namespace QCA
*/
QCA_EXPORT const ProviderList & providers();
/**
* Scan for new plugins
*
*/
QCA_EXPORT void scanForPlugins();
/**
* Unload the current plugins
*

@ -31,10 +31,6 @@
#define QCA_PLUGIN_VERSION 2
#define QCA_EXPORT_PLUGIN(P) \
QCA_PLUGIN_EXPORT QCA::Provider *createProvider2() { return new P; } \
QCA_PLUGIN_EXPORT int version() { return QCA_PLUGIN_VERSION; }
/** \page providers Providers
QCA works on the concept of a "provider". There is a limited
@ -53,6 +49,14 @@ whatsoever, or to specify the default provider directly (this goes for the
algorithm constructors as well as setGlobalRNG()).
*/
class QCAPlugin : public QObject
{
Q_OBJECT
public:
virtual int version() const = 0;
virtual QCA::Provider *createProvider() = 0;
};
namespace QCA {
class RandomContext : public Provider::Context

@ -179,6 +179,11 @@ const ProviderList & providers()
return manager->providers();
}
void scanForPlugins()
{
manager->scan();
}
void unloadAllPlugins()
{
if(!qca_init)

@ -23,14 +23,6 @@
#include <QtCore>
#include "qcaprovider.h"
#if defined(Q_OS_WIN32)
# define PLUGIN_EXT "dll"
#elif defined(Q_OS_MAC)
# define PLUGIN_EXT "dylib"
#else
# define PLUGIN_EXT "so"
#endif
#define PLUGIN_SUBDIR "crypto"
namespace QCA {
@ -38,73 +30,43 @@ namespace QCA {
class ProviderItem
{
public:
QCA::Provider *p;
Provider *p;
QString fname;
int version;
int priority;
static ProviderItem *load(const QString &fname)
{
QLibrary *lib = new QLibrary(fname);
if(!lib->load())
QPluginLoader *lib = new QPluginLoader(fname);
QCAPlugin *plugin = qobject_cast<QCAPlugin*>(lib->instance());
if(!plugin || plugin->version() != QCA_PLUGIN_VERSION)
{
delete lib;
return 0;
}
int ver = 0;
bool old;
void *s = lib->resolve("version");
if(s)
{
old = false;
int (*versionfunc)() = (int (*)())s;
ver = versionfunc();
}
else
{
old = true;
}
if(old)
s = lib->resolve("createProvider");
else
s = lib->resolve("createProvider2");
if(!s)
Provider *p = plugin->createProvider();
if(!p)
{
delete lib;
return 0;
}
ProviderItem *i;
if(old)
{
// old method
//QCAProvider *(*createProvider)() = (QCAProvider *(*)())s;
//QCAProvider *p = createProvider();
//if(!p)
//{
delete lib;
return 0;
//}
//ver = p->qcaVersion();
//i = new ProviderItem(lib, p);
}
else
{
// new method
QCA::Provider *(*createProvider)() = (QCA::Provider *(*)())s;
QCA::Provider *p = createProvider();
if(!p)
{
delete lib;
return 0;
}
i = new ProviderItem(lib, p);
}
ProviderItem *i = new ProviderItem(lib, p);
i->fname = fname;
i->version = ver;
return i;
}
static ProviderItem *loadStatic(QObject *instance)
{
QCAPlugin *plugin = qobject_cast<QCAPlugin*>(instance);
if(!plugin || plugin->version() != QCA_PLUGIN_VERSION)
return 0;
Provider *p = plugin->createProvider();
if(!p)
return 0;
ProviderItem *i = new ProviderItem(0, p);
return i;
}
@ -129,10 +91,10 @@ public:
}
private:
QLibrary *lib;
QPluginLoader *lib;
bool init_done;
ProviderItem(QLibrary *_lib, QCA::Provider *_p)
ProviderItem(QPluginLoader *_lib, QCA::Provider *_p)
{
lib = _lib;
p = _p;
@ -143,6 +105,7 @@ private:
ProviderManager::ProviderManager()
{
def = 0;
scanned_static = false;
}
ProviderManager::~ProviderManager()
@ -152,6 +115,29 @@ ProviderManager::~ProviderManager()
void ProviderManager::scan()
{
// check static first, but only once
if(!scanned_static)
{
QObjectList list = QPluginLoader::staticInstances();
for(int n = 0; n < list.count(); ++n)
{
QObject *instance = list[n];
ProviderItem *i = ProviderItem::loadStatic(instance);
if(!i)
continue;
if(i->p && haveAlready(i->p->name()))
{
delete i;
continue;
}
addItem(i, -1);
}
scanned_static = true;
}
// check plugin files
QStringList dirs = QCoreApplication::libraryPaths();
for(QStringList::ConstIterator it = dirs.begin(); it != dirs.end(); ++it)
{
@ -166,18 +152,11 @@ void ProviderManager::scan()
QFileInfo fi(dir.filePath(*it));
if(fi.isDir())
continue;
if(fi.suffix() != PLUGIN_EXT)
continue;
QString fname = fi.filePath();
ProviderItem *i = ProviderItem::load(fname);
if(!i)
continue;
if(i->version != QCA_PLUGIN_VERSION)
{
delete i;
continue;
}
if(i->p && haveAlready(i->p->name()))
{

@ -54,6 +54,7 @@ namespace QCA
QList<ProviderItem*> providerItemList;
QCA::ProviderList providerList;
QCA::Provider *def;
bool scanned_static;
void addItem(ProviderItem *i, int priority);
bool haveAlready(const QString &name) const;
};