diff --git a/src/corelib/codecs/qtextcodec.h b/src/corelib/codecs/qtextcodec.h index 4ba8b85..67e0faa 100644 --- a/src/corelib/codecs/qtextcodec.h +++ b/src/corelib/codecs/qtextcodec.h @@ -59,6 +59,8 @@ class QIODevice; class QTextDecoder; class QTextEncoder; +class QTextCodecPlugin; + class Q_CORE_EXPORT QTextCodec { Q_DISABLE_COPY(QTextCodec) @@ -147,6 +149,7 @@ public: private: friend class QTextCodecCleanup; + friend class QTextCodecPlugin; static QTextCodec *cftr; static bool validCodecs(); }; diff --git a/src/corelib/codecs/qtextcodecplugin.cpp b/src/corelib/codecs/qtextcodecplugin.cpp index 90b64f4..f14f630 100644 --- a/src/corelib/codecs/qtextcodecplugin.cpp +++ b/src/corelib/codecs/qtextcodecplugin.cpp @@ -42,6 +42,10 @@ #include "qtextcodecplugin.h" #include "qstringlist.h" + +#define _QT_TEXT_CODEC_LIST_PROPERTY_NAME "_q_text_codec_list" + + #ifndef QT_NO_TEXTCODECPLUGIN QT_BEGIN_NAMESPACE @@ -134,6 +138,16 @@ QTextCodecPlugin::QTextCodecPlugin(QObject *parent) */ QTextCodecPlugin::~QTextCodecPlugin() { + // destroy all text codecs created by this text codec plugin + QVariant v = property(_QT_TEXT_CODEC_LIST_PROPERTY_NAME); + QList listCodecs = v.toList(); + + QList::const_iterator itr = listCodecs.constBegin(); + while (itr != listCodecs.constEnd()) { + QTextCodec *tc = reinterpret_cast((*itr).value()); + delete tc; + ++itr; + } } QStringList QTextCodecPlugin::keys() const @@ -156,6 +170,14 @@ QTextCodec *QTextCodecPlugin::create(const QString &name) return createForName(name.toLatin1()); } +void QTextCodecPlugin::addTextCodec(QTextCodec *tc) +{ + QVariant v = property(_QT_TEXT_CODEC_LIST_PROPERTY_NAME); + QList listCodecs = v.toList(); + listCodecs.append(QVariant::fromValue(reinterpret_cast(tc))); + setProperty(_QT_TEXT_CODEC_LIST_PROPERTY_NAME, QVariant(listCodecs)); +} + QT_END_NAMESPACE #endif // QT_NO_TEXTCODECPLUGIN diff --git a/src/corelib/codecs/qtextcodecplugin.h b/src/corelib/codecs/qtextcodecplugin.h index d169bde..9deb561 100644 --- a/src/corelib/codecs/qtextcodecplugin.h +++ b/src/corelib/codecs/qtextcodecplugin.h @@ -85,6 +85,9 @@ public: private: QStringList keys() const; QTextCodec *create(const QString &name); + +protected: + void addTextCodec(QTextCodec *tc); }; #endif // QT_NO_TEXTCODECPLUGIN diff --git a/src/corelib/plugin/qfactoryloader.cpp b/src/corelib/plugin/qfactoryloader.cpp index a26dcd8..4517a78 100644 --- a/src/corelib/plugin/qfactoryloader.cpp +++ b/src/corelib/plugin/qfactoryloader.cpp @@ -67,7 +67,7 @@ public: ~QFactoryLoaderPrivate(); mutable QMutex mutex; QByteArray iid; - QList libraryList; + mutable QList > libraryList; QMap keyMap; QStringList keyList; QString suffix; @@ -79,8 +79,12 @@ public: QFactoryLoaderPrivate::~QFactoryLoaderPrivate() { - for (int i = 0; i < libraryList.count(); ++i) - libraryList.at(i)->release(); + for (int i = 0; i < libraryList.count(); ++i) { + if (libraryList.at(i).second) + libraryList.at(i).first->unload(); + + libraryList.at(i).first->release(); + } } QFactoryLoader::QFactoryLoader(const char *iid, @@ -135,6 +139,7 @@ void QFactoryLoader::update() library->release(); continue; } + bool did_load = false; QString regkey = QString::fromLatin1("Qt Factory Cache %1.%2/%3:/%4") .arg((QT_VERSION & 0xff0000) >> 16) .arg((QT_VERSION & 0xff00) >> 8) @@ -154,6 +159,7 @@ void QFactoryLoader::update() library->release(); continue; } + did_load = true; QObject *instance = library->instance(); if (!instance) // ignore plugins that have a valid signature but cannot be loaded. @@ -176,7 +182,7 @@ void QFactoryLoader::update() library->release(); continue; } - d->libraryList += library; + d->libraryList += QPair(library, did_load); for (int k = 0; k < keys.count(); ++k) { // first come first serve, unless the first // library was built with a future Qt version, @@ -233,13 +239,24 @@ QObject *QFactoryLoader::instance(const QString &key) const QString lowered = d->cs ? key : key.toLower(); if (QLibraryPrivate* library = d->keyMap.value(lowered)) { - if (library->instance || library->loadPlugin()) { - if (QObject *obj = library->instance()) { - if (obj && !obj->parent()) - obj->moveToThread(QCoreApplicationPrivate::mainThread()); - return obj; + if (!library->instance) { + if (!library->loadPlugin()) + return 0; + + QList >::iterator itr; + for (itr = d->libraryList.begin(); itr != d->libraryList.end(); ++itr) { + if (library == (*itr).first) { + (*itr).second = true; // mark this plugin as loaded + break; + } } } + + if (QObject *obj = library->instance()) { + if (obj && !obj->parent()) + obj->moveToThread(QCoreApplicationPrivate::mainThread()); + return obj; + } } return 0; } diff --git a/src/plugins/codecs/cn/main.cpp b/src/plugins/codecs/cn/main.cpp index 9a467f3d..0d5ef75 100644 --- a/src/plugins/codecs/cn/main.cpp +++ b/src/plugins/codecs/cn/main.cpp @@ -103,37 +103,49 @@ QList CNTextCodecs::mibEnums() const QTextCodec *CNTextCodecs::createForMib(int mib) { + QTextCodec *tc = 0; + if (mib == QGb18030Codec::_mibEnum()) - return new QGb18030Codec; - if (mib == QGbkCodec::_mibEnum()) - return new QGbkCodec; - if (mib == QGb2312Codec::_mibEnum()) - return new QGb2312Codec; + tc = new QGb18030Codec; + else if (mib == QGbkCodec::_mibEnum()) + tc = new QGbkCodec; + else if (mib == QGb2312Codec::_mibEnum()) + tc = new QGb2312Codec; #ifdef Q_WS_X11 - if (mib == QFontGbkCodec::_mibEnum()) - return new QFontGbkCodec; - if (mib == QFontGb2312Codec::_mibEnum()) - return new QFontGb2312Codec; + else if (mib == QFontGbkCodec::_mibEnum()) + tc = new QFontGbkCodec; + else if (mib == QFontGb2312Codec::_mibEnum()) + tc = new QFontGb2312Codec; #endif - return 0; + + if (tc) + addTextCodec(tc); + + return tc; } QTextCodec *CNTextCodecs::createForName(const QByteArray &name) { + QTextCodec *tc = 0; + if (name == QGb18030Codec::_name() || QGb18030Codec::_aliases().contains(name)) - return new QGb18030Codec; - if (name == QGbkCodec::_name() || QGbkCodec::_aliases().contains(name)) - return new QGbkCodec; - if (name == QGb2312Codec::_name() || QGb2312Codec::_aliases().contains(name)) - return new QGb2312Codec; + tc = new QGb18030Codec; + else if (name == QGbkCodec::_name() || QGbkCodec::_aliases().contains(name)) + tc = new QGbkCodec; + else if (name == QGb2312Codec::_name() || QGb2312Codec::_aliases().contains(name)) + tc = new QGb2312Codec; #ifdef Q_WS_X11 - if (name == QFontGbkCodec::_name() || QFontGbkCodec::_aliases().contains(name)) - return new QFontGbkCodec; - if (name == QFontGb2312Codec::_name() || QFontGb2312Codec::_aliases().contains(name)) - return new QFontGb2312Codec; + else if (name == QFontGbkCodec::_name() || QFontGbkCodec::_aliases().contains(name)) + tc = new QFontGbkCodec; + else if (name == QFontGb2312Codec::_name() || QFontGb2312Codec::_aliases().contains(name)) + tc = new QFontGb2312Codec; #endif - return 0; + + if (tc) + addTextCodec(tc); + + return tc; } diff --git a/src/plugins/codecs/jp/main.cpp b/src/plugins/codecs/jp/main.cpp index 2c04cb2..dc35a1c 100644 --- a/src/plugins/codecs/jp/main.cpp +++ b/src/plugins/codecs/jp/main.cpp @@ -108,37 +108,49 @@ QList JPTextCodecs::mibEnums() const QTextCodec *JPTextCodecs::createForMib(int mib) { + QTextCodec *tc = 0; + if (mib == QEucJpCodec::_mibEnum()) - return new QEucJpCodec; - if (mib == QJisCodec::_mibEnum()) - return new QJisCodec; - if (mib == QSjisCodec::_mibEnum()) - return new QSjisCodec; + tc = new QEucJpCodec; + else if (mib == QJisCodec::_mibEnum()) + tc = new QJisCodec; + else if (mib == QSjisCodec::_mibEnum()) + tc = new QSjisCodec; #ifdef Q_WS_X11 - if (mib == QFontJis0208Codec::_mibEnum()) - return new QFontJis0208Codec; - if (mib == QFontJis0201Codec::_mibEnum()) - return new QFontJis0201Codec; + else if (mib == QFontJis0208Codec::_mibEnum()) + tc = new QFontJis0208Codec; + else if (mib == QFontJis0201Codec::_mibEnum()) + tc = new QFontJis0201Codec; #endif - return 0; + + if (tc) + addTextCodec(tc); + + return tc; } QTextCodec *JPTextCodecs::createForName(const QByteArray &name) { + QTextCodec *tc = 0; + if (name == QEucJpCodec::_name() || QEucJpCodec::_aliases().contains(name)) - return new QEucJpCodec; - if (name == QJisCodec::_name() || QJisCodec::_aliases().contains(name)) - return new QJisCodec; - if (name == QSjisCodec::_name() || QSjisCodec::_aliases().contains(name)) - return new QSjisCodec; + tc = new QEucJpCodec; + else if (name == QJisCodec::_name() || QJisCodec::_aliases().contains(name)) + tc = new QJisCodec; + else if (name == QSjisCodec::_name() || QSjisCodec::_aliases().contains(name)) + tc = new QSjisCodec; #ifdef Q_WS_X11 - if (name == QFontJis0208Codec::_name() || QFontJis0208Codec::_aliases().contains(name)) - return new QFontJis0208Codec; - if (name == QFontJis0201Codec::_name() || QFontJis0201Codec::_aliases().contains(name)) - return new QFontJis0201Codec; + else if (name == QFontJis0208Codec::_name() || QFontJis0208Codec::_aliases().contains(name)) + tc = new QFontJis0208Codec; + else if (name == QFontJis0201Codec::_name() || QFontJis0201Codec::_aliases().contains(name)) + tc = new QFontJis0201Codec; #endif - return 0; + + if (tc) + addTextCodec(tc); + + return tc; } Q_EXPORT_STATIC_PLUGIN(JPTextCodecs); diff --git a/src/plugins/codecs/kr/main.cpp b/src/plugins/codecs/kr/main.cpp index 68f9482..47d4ee9 100644 --- a/src/plugins/codecs/kr/main.cpp +++ b/src/plugins/codecs/kr/main.cpp @@ -97,29 +97,41 @@ QList KRTextCodecs::mibEnums() const QTextCodec *KRTextCodecs::createForMib(int mib) { + QTextCodec *tc = 0; + if (mib == QEucKrCodec::_mibEnum()) - return new QEucKrCodec; + tc = new QEucKrCodec; #ifdef Q_WS_X11 - if (mib == QFontKsc5601Codec::_mibEnum()) - return new QFontKsc5601Codec; + else if (mib == QFontKsc5601Codec::_mibEnum()) + tc = new QFontKsc5601Codec; #endif - if (mib == QCP949Codec::_mibEnum()) - return new QCP949Codec; - return 0; + else if (mib == QCP949Codec::_mibEnum()) + tc = new QCP949Codec; + + if (tc) + addTextCodec(tc); + + return tc; } QTextCodec *KRTextCodecs::createForName(const QByteArray &name) { + QTextCodec *tc = 0; + if (name == QEucKrCodec::_name() || QEucKrCodec::_aliases().contains(name)) - return new QEucKrCodec; + tc = new QEucKrCodec; #ifdef Q_WS_X11 - if (name == QFontKsc5601Codec::_name() || QFontKsc5601Codec::_aliases().contains(name)) - return new QFontKsc5601Codec; + else if (name == QFontKsc5601Codec::_name() || QFontKsc5601Codec::_aliases().contains(name)) + tc = new QFontKsc5601Codec; #endif - if (name == QCP949Codec::_name() || QCP949Codec::_aliases().contains(name)) - return new QCP949Codec; - return 0; + else if (name == QCP949Codec::_name() || QCP949Codec::_aliases().contains(name)) + tc = new QCP949Codec; + + if (tc) + addTextCodec(tc); + + return tc; } diff --git a/src/plugins/codecs/tw/main.cpp b/src/plugins/codecs/tw/main.cpp index 1dc7731..420539f 100644 --- a/src/plugins/codecs/tw/main.cpp +++ b/src/plugins/codecs/tw/main.cpp @@ -100,33 +100,45 @@ QList TWTextCodecs::mibEnums() const QTextCodec *TWTextCodecs::createForMib(int mib) { + QTextCodec *tc = 0; + if (mib == QBig5Codec::_mibEnum()) - return new QBig5Codec; - if (mib == QBig5hkscsCodec::_mibEnum()) - return new QBig5hkscsCodec; + tc = new QBig5Codec; + else if (mib == QBig5hkscsCodec::_mibEnum()) + tc = new QBig5hkscsCodec; #ifdef Q_WS_X11 - if (mib == QFontBig5hkscsCodec::_mibEnum()) - return new QFontBig5hkscsCodec; - if (mib == QFontBig5Codec::_mibEnum()) - return new QFontBig5Codec; + else if (mib == QFontBig5hkscsCodec::_mibEnum()) + tc = new QFontBig5hkscsCodec; + else if (mib == QFontBig5Codec::_mibEnum()) + tc = new QFontBig5Codec; #endif - return 0; + + if (tc) + addTextCodec(tc); + + return tc; } QTextCodec *TWTextCodecs::createForName(const QByteArray &name) { + QTextCodec *tc = 0; + if (name == QBig5Codec::_name() || QBig5Codec::_aliases().contains(name)) - return new QBig5Codec; - if (name == QBig5hkscsCodec::_name() || QBig5hkscsCodec::_aliases().contains(name)) - return new QBig5hkscsCodec; + tc = new QBig5Codec; + else if (name == QBig5hkscsCodec::_name() || QBig5hkscsCodec::_aliases().contains(name)) + tc = new QBig5hkscsCodec; #ifdef Q_WS_X11 - if (name == QFontBig5hkscsCodec::_name() || QFontBig5hkscsCodec::_aliases().contains(name)) - return new QFontBig5hkscsCodec; - if (name == QFontBig5Codec::_name() || QFontBig5Codec::_aliases().contains(name)) - return new QFontBig5Codec; + else if (name == QFontBig5hkscsCodec::_name() || QFontBig5hkscsCodec::_aliases().contains(name)) + tc = new QFontBig5hkscsCodec; + else if (name == QFontBig5Codec::_name() || QFontBig5Codec::_aliases().contains(name)) + tc = new QFontBig5Codec; #endif - return 0; + + if (tc) + addTextCodec(tc); + + return tc; }