[pim/messagelib] /: Clean up ownership semantics of body part plugins
Volker Krause <[email protected]>
| Newsgroups | gmane.comp.kde.cvs |
|---|---|
| Message-ID | <[email protected]> |
Git commit 46f79e03086472d6676646698a29b7bc164a7fa1 by Volker Krause.
Committed on 17/08/2026 at 18:51.
Pushed by vkrause into branch 'master'.
Clean up ownership semantics of body part plugins
This addresses LSAN errors that show up in the render tests in
kdepim-addons.
M +1 -1 CMakeLists.txt
M +13 -18 messageviewer/src/messagepartthemes/default/messagepartrendererfactory.cpp
M +1 -2 messageviewer/src/messagepartthemes/default/messagepartrendererfactory_p.h
M +2 -3 messageviewer/src/messagepartthemes/default/messagepartrenderplugin.h
M +27 -34 mimetreeparser/autotests/bodypartformatterbasefactorytest.cpp
M +0 -10 mimetreeparser/src/bodyformatter/applicationpgpencrypted.cpp
M +0 -3 mimetreeparser/src/bodyformatter/applicationpgpencrypted.h
M +0 -10 mimetreeparser/src/bodyformatter/applicationpkcs7mime.cpp
M +0 -3 mimetreeparser/src/bodyformatter/applicationpkcs7mime.h
M +0 -17 mimetreeparser/src/bodyformatter/encrypted.cpp
M +4 -1 mimetreeparser/src/bodyformatter/encrypted.h
M +0 -10 mimetreeparser/src/bodyformatter/mailman.cpp
M +0 -3 mimetreeparser/src/bodyformatter/mailman.h
M +0 -10 mimetreeparser/src/bodyformatter/multipartalternative.cpp
M +0 -3 mimetreeparser/src/bodyformatter/multipartalternative.h
M +0 -10 mimetreeparser/src/bodyformatter/multipartencrypted.cpp
M +0 -3 mimetreeparser/src/bodyformatter/multipartencrypted.h
M +0 -10 mimetreeparser/src/bodyformatter/multipartmixed.cpp
M +0 -3 mimetreeparser/src/bodyformatter/multipartmixed.h
M +0 -10 mimetreeparser/src/bodyformatter/multipartsigned.cpp
M +0 -3 mimetreeparser/src/bodyformatter/multipartsigned.h
M +0 -10 mimetreeparser/src/bodyformatter/texthtml.cpp
M +0 -3 mimetreeparser/src/bodyformatter/texthtml.h
M +0 -10 mimetreeparser/src/bodyformatter/textplain.cpp
M +0 -3 mimetreeparser/src/bodyformatter/textplain.h
M +27 -64 mimetreeparser/src/bodypartformatter.cpp
M +13 -21 mimetreeparser/src/bodypartformatterfactory.cpp
M +1 -1 mimetreeparser/src/bodypartformatterfactory.h
M +9 -4 mimetreeparser/src/bodypartformatterfactory_p.h
M +2 -3 mimetreeparser/src/interfaces/bodypartformatter.h
https://invent.kde.org/pim/messagelib/-/commit/46f79e03086472d6676646698a29b7bc164a7fa1
diff --git a/CMakeLists.txt b/CMakeLists.txt
index b7104dd76..1e3656e1e 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,7 +1,7 @@
# SPDX-License-Identifier: CC0-1.0
# SPDX-FileCopyrightText: none
cmake_minimum_required(VERSION 3.29)
-set(PIM_VERSION "6.8.40")
+set(PIM_VERSION "6.8.41")
project(Messagelib VERSION ${PIM_VERSION})
diff --git a/messageviewer/src/messagepartthemes/default/messagepartrendererfactory.cpp b/messageviewer/src/messagepartthemes/default/messagepartrendererfactory.cpp
index 8a91974c7..d7b4521ce 100644
--- a/messageviewer/src/messagepartthemes/default/messagepartrendererfactory.cpp
+++ b/messageviewer/src/messagepartthemes/default/messagepartrendererfactory.cpp
@@ -26,15 +26,7 @@
using namespace Qt::Literals::StringLiterals;
using namespace MessageViewer;
-MessagePartRendererFactoryPrivate::~MessagePartRendererFactoryPrivate()
-{
- QHashIterator<QByteArray, std::vector<RendererInfo>> i(m_renderers);
- while (i.hasNext()) {
- i.next();
- auto renderInfo = i.value();
- renderInfo.erase(renderInfo.begin(), renderInfo.end());
- }
-}
+MessagePartRendererFactoryPrivate::~MessagePartRendererFactoryPrivate() = default;
void MessagePartRendererFactoryPrivate::setup()
{
@@ -64,7 +56,7 @@ void MessagePartRendererFactoryPrivate::loadPlugins()
continue;
}
- MessagePartRendererBase *renderer = nullptr;
+ std::unique_ptr<MessagePartRendererBase> renderer;
for (int i = 0; (renderer = plugin->renderer(i)) && i < pluginData.size(); ++i) {
const auto metaData = pluginData.at(i).toObject();
const auto type = metaData.value(QLatin1StringView("type")).toString().toUtf8();
@@ -76,7 +68,7 @@ void MessagePartRendererFactoryPrivate::loadPlugins()
// priority should always be higher than the built-in ones, otherwise what's the point?
const auto priority = metaData.value(QLatin1StringView("priority")).toInt() + 100;
qCDebug(MESSAGEVIEWER_LOG) << "renderer plugin for " << type << mimetype << priority;
- insert(type, renderer, mimetype, priority);
+ insert(type, std::move(renderer), mimetype, priority);
}
const Interface::BodyPartURLHandler *handler = nullptr;
@@ -90,12 +82,15 @@ void MessagePartRendererFactoryPrivate::loadPlugins()
void MessagePartRendererFactoryPrivate::initialize_builtin_renderers()
{
- insert("MimeTreeParser::MessagePart", new MessagePartRenderer());
- insert("MimeTreeParser::TextMessagePart", new TextMessagePartRenderer());
- insert("MimeTreeParser::AttachmentMessagePart", new AttachmentMessagePartRenderer());
+ insert("MimeTreeParser::MessagePart", std::make_unique<MessagePartRenderer>());
+ insert("MimeTreeParser::TextMessagePart", std::make_unique<TextMessagePartRenderer>());
+ insert("MimeTreeParser::AttachmentMessagePart", std::make_unique<AttachmentMessagePartRenderer>());
}
-void MessagePartRendererFactoryPrivate::insert(const QByteArray &type, MessagePartRendererBase *renderer, const QString &mimeType, int priority)
+void MessagePartRendererFactoryPrivate::insert(const QByteArray &type,
+ std::unique_ptr<MessagePartRendererBase> &&renderer,
+ const QString &mimeType,
+ int priority)
{
if (type.isEmpty() || !renderer) {
return;
@@ -105,12 +100,12 @@ void MessagePartRendererFactoryPrivate::insert(const QByteArray &type, MessagePa
const auto mt = db.mimeTypeForName(mimeType);
RendererInfo info;
- info.renderer.reset(renderer);
+ info.renderer.reset(renderer.release());
info.mimeType = mt.isValid() ? mt.name() : mimeType;
info.priority = priority;
auto &v = m_renderers[type];
- v.push_back(info);
+ v.push_back(std::move(info));
}
MessagePartRendererFactory::MessagePartRendererFactory()
@@ -173,7 +168,7 @@ QList<MessagePartRendererBase *> MessagePartRendererFactory::renderersForPart(co
QList<MessagePartRendererBase *> r;
r.reserve(candidates.size());
for (const auto &candidate : candidates) {
- r.push_back(candidate.renderer.data());
+ r.push_back(candidate.renderer.get());
}
return r;
}
diff --git a/messageviewer/src/messagepartthemes/default/messagepartrendererfactory_p.h b/messageviewer/src/messagepartthemes/default/messagepartrendererfactory_p.h
index 03a30c27a..fe6e0ce87 100644
--- a/messageviewer/src/messagepartthemes/default/messagepartrendererfactory_p.h
+++ b/messageviewer/src/messagepartthemes/default/messagepartrendererfactory_p.h
@@ -7,7 +7,6 @@
#pragma once
#include <QByteArray>
-
#include <QHash>
#include <QString>
@@ -31,7 +30,7 @@ public:
void setup();
void loadPlugins();
void initialize_builtin_renderers();
- void insert(const QByteArray &type, MessagePartRendererBase *formatter, const QString &mimeType = QString(), int priority = 0);
+ void insert(const QByteArray &type, std::unique_ptr<MessagePartRendererBase> &&formatter, const QString &mimeType = QString(), int priority = 0);
QHash<QByteArray, std::vector<RendererInfo>> m_renderers;
QString m_pluginSubdir = u"pim6/messageviewer/bodypartformatter"_s;
diff --git a/messageviewer/src/messagepartthemes/default/messagepartrenderplugin.h b/messageviewer/src/messagepartthemes/default/messagepartrenderplugin.h
index 942a2c01a..25d346d32 100644
--- a/messageviewer/src/messagepartthemes/default/messagepartrenderplugin.h
+++ b/messageviewer/src/messagepartthemes/default/messagepartrenderplugin.h
@@ -30,9 +30,8 @@ public:
/*!
*/
virtual ~MessagePartRenderPlugin();
- /*!
- */
- virtual MessagePartRendererBase *renderer(int index) = 0;
+ /*! Return a renderer instance for the Nth entry in the plugin metadata. */
+ [[nodiscard]] virtual std::unique_ptr<MessagePartRendererBase> renderer(int index) = 0;
/*!
*/
virtual const Interface::BodyPartURLHandler *urlHandler(int idx) const;
diff --git a/mimetreeparser/autotests/bodypartformatterbasefactorytest.cpp b/mimetreeparser/autotests/bodypartformatterbasefactorytest.cpp
index cc99847d3..01b0b45c7 100644
--- a/mimetreeparser/autotests/bodypartformatterbasefactorytest.cpp
+++ b/mimetreeparser/autotests/bodypartformatterbasefactorytest.cpp
@@ -26,11 +26,8 @@ class TestFactory : public BodyPartFormatterFactory
public:
void loadPlugins() override
{
- textCalFormatter = std::make_unique<DummyFormatter>();
- insert(u"TEXT/CALENDAR"_s, textCalFormatter.get(), 100);
+ insert(u"TEXT/CALENDAR"_s, std::make_unique<DummyFormatter>(), 100);
}
-
- std::unique_ptr<DummyFormatter> textCalFormatter;
};
using namespace MimeTreeParser;
@@ -44,80 +41,76 @@ private Q_SLOTS:
TestFactory fac;
auto l = fac.formattersForType(u"application/octet-stream"_s);
QCOMPARE(l.size(), 3);
- const auto application_octet_stream_f = l.at(2);
- QVERIFY(application_octet_stream_f);
+ const auto &application_octet_stream_f = typeid(*l.at(2));
l = fac.formattersForType(u"application/pgp-encrypted"_s);
// shared-mime-info < 2.4 has application/pgp-encrytped as a subtype of text/plain, 2.4+ doesn't
// depending of that we get two additional entries for text/plain formatters here
QVERIFY(l.size() == 4 || l.size() == 6);
- QVERIFY(l.at(0) != application_octet_stream_f);
- QCOMPARE(l.at(l.size() - 1), application_octet_stream_f);
+ QCOMPARE_NE(typeid(*l.at(0)), application_octet_stream_f);
+ QCOMPARE(typeid(*l.at(l.size() - 1)), application_octet_stream_f);
l = fac.formattersForType(u"application/unknown"_s);
QCOMPARE(l.size(), 3);
- QCOMPARE(l.at(2), application_octet_stream_f);
+ QCOMPARE(typeid(*l.at(2)), application_octet_stream_f);
l = fac.formattersForType(u"text/plain"_s);
QCOMPARE(l.size(), 5);
- const auto text_plain_f1 = l.at(0);
- const auto text_plain_f2 = l.at(1);
- QVERIFY(text_plain_f1);
- QVERIFY(text_plain_f2);
+ const auto &text_plain_f1 = typeid(*l.at(0));
+ const auto &text_plain_f2 = typeid(*l.at(1));
QVERIFY(text_plain_f1 != text_plain_f2);
- QCOMPARE(l.at(4), application_octet_stream_f);
+ QCOMPARE(typeid(*l.at(4)), application_octet_stream_f);
l = fac.formattersForType(u"text/calendar"_s);
QCOMPARE(l.size(), 6);
- QVERIFY(fac.textCalFormatter);
- QCOMPARE(l.at(0), fac.textCalFormatter.get());
- QCOMPARE(l.at(1), text_plain_f1);
- QCOMPARE(l.at(2), text_plain_f2);
- QCOMPARE(l.at(5), application_octet_stream_f);
+ QVERIFY(dynamic_cast<const DummyFormatter *>(l.at(0)));
+ QCOMPARE(typeid(*l.at(1)), text_plain_f1);
+ QCOMPARE(typeid(*l.at(2)), text_plain_f2);
+ QCOMPARE(typeid(*l.at(5)), application_octet_stream_f);
l = fac.formattersForType(u"text/x-vcalendar"_s);
QCOMPARE(l.size(), 6);
- QCOMPARE(l.at(0), fac.textCalFormatter.get());
+ QVERIFY(dynamic_cast<const DummyFormatter *>(l.at(0)));
l = fac.formattersForType(u"TEXT/X-VCALENDAR"_s);
QCOMPARE(l.size(), 6);
- QCOMPARE(l.at(0), fac.textCalFormatter.get());
+ QVERIFY(dynamic_cast<const DummyFormatter *>(l.at(0)));
l = fac.formattersForType(u"text/html"_s);
QCOMPARE(l.size(), 6);
- QCOMPARE(l.at(1), text_plain_f1);
- QCOMPARE(l.at(2), text_plain_f2);
- QCOMPARE(l.at(5), application_octet_stream_f);
+ QCOMPARE(typeid(*l.at(1)), text_plain_f1);
+ QCOMPARE(typeid(*l.at(2)), text_plain_f2);
+ QCOMPARE(typeid(*l.at(5)), application_octet_stream_f);
l = fac.formattersForType(u"text/rtf"_s);
QCOMPARE(l.size(), 6);
- QCOMPARE(l.at(0), application_octet_stream_f);
- QCOMPARE(l.at(5), application_octet_stream_f);
+ QCOMPARE(typeid(*l.at(0)), application_octet_stream_f);
+ QCOMPARE(typeid(*l.at(5)), application_octet_stream_f);
l = fac.formattersForType(u"multipart/mixed"_s);
QCOMPARE(l.size(), 1);
- const auto multipart_mixed_f = l.at(0);
- QVERIFY(multipart_mixed_f);
+ const auto &multipart_mixed_f = typeid(*l.at(0));
+ // QVERIFY(multipart_mixed_f);
l = fac.formattersForType(u"multipart/random"_s);
QCOMPARE(l.size(), 1);
- QCOMPARE(l.at(0), multipart_mixed_f);
+ QCOMPARE(typeid(*l.at(0)), multipart_mixed_f);
l = fac.formattersForType(u"multipart/encrypted"_s);
QCOMPARE(l.size(), 2);
- QVERIFY(l.at(0) != multipart_mixed_f);
- QCOMPARE(l.at(1), multipart_mixed_f);
+ QVERIFY(typeid(*l.at(0)) != multipart_mixed_f);
+ QCOMPARE(typeid(*l.at(1)), multipart_mixed_f);
l = fac.formattersForType(u"image/png"_s);
QCOMPARE(l.size(), 4);
- QCOMPARE(l.at(3), application_octet_stream_f);
+ QCOMPARE(typeid(*l.at(3)), application_octet_stream_f);
l = fac.formattersForType(u"vendor/random"_s);
QCOMPARE(l.size(), 3);
- QCOMPARE(l.at(2), application_octet_stream_f);
+ QCOMPARE(typeid(*l.at(2)), application_octet_stream_f);
l = fac.formattersForType(u"message/rfc822"_s);
QCOMPARE(l.size(), 6);
- QCOMPARE(l.at(5), application_octet_stream_f);
+ QCOMPARE(typeid(*l.at(5)), application_octet_stream_f);
l = fac.formattersForType(u"message/news"_s);
QCOMPARE(l.size(), 5); // ### news does not inherit rfc822
diff --git a/mimetreeparser/src/bodyformatter/applicationpgpencrypted.cpp b/mimetreeparser/src/bodyformatter/applicationpgpencrypted.cpp
index 2ae441177..7e3e69e7a 100644
--- a/mimetreeparser/src/bodyformatter/applicationpgpencrypted.cpp
+++ b/mimetreeparser/src/bodyformatter/applicationpgpencrypted.cpp
@@ -19,16 +19,6 @@
using namespace MimeTreeParser;
-const ApplicationPGPEncryptedBodyPartFormatter *ApplicationPGPEncryptedBodyPartFormatter::self;
-
-const Interface::BodyPartFormatter *ApplicationPGPEncryptedBodyPartFormatter::create()
-{
- if (!self) {
- self = new ApplicationPGPEncryptedBodyPartFormatter();
- }
- return self;
-}
-
MessagePart::Ptr ApplicationPGPEncryptedBodyPartFormatter::process(Interface::BodyPart &part) const
{
KMime::Content *node(part.content());
diff --git a/mimetreeparser/src/bodyformatter/applicationpgpencrypted.h b/mimetreeparser/src/bodyformatter/applicationpgpencrypted.h
index 208735a6d..944df1e2e 100644
--- a/mimetreeparser/src/bodyformatter/applicationpgpencrypted.h
+++ b/mimetreeparser/src/bodyformatter/applicationpgpencrypted.h
@@ -13,10 +13,7 @@ namespace MimeTreeParser
{
class ApplicationPGPEncryptedBodyPartFormatter : public Interface::BodyPartFormatter
{
- static const ApplicationPGPEncryptedBodyPartFormatter *self;
-
public:
[[nodiscard]] MessagePartPtr process(Interface::BodyPart &part) const override;
- static const Interface::BodyPartFormatter *create();
};
}
diff --git a/mimetreeparser/src/bodyformatter/applicationpkcs7mime.cpp b/mimetreeparser/src/bodyformatter/applicationpkcs7mime.cpp
index 76173d1b8..f475934bd 100644
--- a/mimetreeparser/src/bodyformatter/applicationpkcs7mime.cpp
+++ b/mimetreeparser/src/bodyformatter/applicationpkcs7mime.cpp
@@ -17,16 +17,6 @@
using namespace MimeTreeParser;
-const ApplicationPkcs7MimeBodyPartFormatter *ApplicationPkcs7MimeBodyPartFormatter::self;
-
-const Interface::BodyPartFormatter *ApplicationPkcs7MimeBodyPartFormatter::create()
-{
- if (!self) {
- self = new ApplicationPkcs7MimeBodyPartFormatter();
- }
- return self;
-}
-
MessagePart::Ptr ApplicationPkcs7MimeBodyPartFormatter::process(Interface::BodyPart &part) const
{
KMime::Content *node = part.content();
diff --git a/mimetreeparser/src/bodyformatter/applicationpkcs7mime.h b/mimetreeparser/src/bodyformatter/applicationpkcs7mime.h
index 869254822..021bbadb3 100644
--- a/mimetreeparser/src/bodyformatter/applicationpkcs7mime.h
+++ b/mimetreeparser/src/bodyformatter/applicationpkcs7mime.h
@@ -13,10 +13,7 @@ namespace MimeTreeParser
{
class ApplicationPkcs7MimeBodyPartFormatter : public Interface::BodyPartFormatter
{
- static const ApplicationPkcs7MimeBodyPartFormatter *self;
-
public:
[[nodiscard]] MessagePartPtr process(Interface::BodyPart &part) const override;
- static const Interface::BodyPartFormatter *create();
};
}
diff --git a/mimetreeparser/src/bodyformatter/encrypted.cpp b/mimetreeparser/src/bodyformatter/encrypted.cpp
index 09c545859..709f71541 100644
--- a/mimetreeparser/src/bodyformatter/encrypted.cpp
+++ b/mimetreeparser/src/bodyformatter/encrypted.cpp
@@ -19,23 +19,6 @@
using namespace MimeTreeParser;
-const Interface::BodyPartFormatter *EncryptedBodyPartFormatter::create(EncryptedBodyPartFormatter::EncryptionFlags flags)
-{
- switch (flags) {
- case AutoPGP: {
- static EncryptedBodyPartFormatter self;
- self.mFlags = flags;
- return &self;
- }
- case ForcePGP: {
- static EncryptedBodyPartFormatter self;
- self.mFlags = flags;
- return &self;
- }
- }
- Q_UNREACHABLE();
-}
-
MessagePart::Ptr EncryptedBodyPartFormatter::process(Interface::BodyPart &part) const
{
KMime::Content *node = part.content();
diff --git a/mimetreeparser/src/bodyformatter/encrypted.h b/mimetreeparser/src/bodyformatter/encrypted.h
index fedae2a41..7c0928ad7 100644
--- a/mimetreeparser/src/bodyformatter/encrypted.h
+++ b/mimetreeparser/src/bodyformatter/encrypted.h
@@ -19,9 +19,12 @@ public:
ForcePGP = 0x1, ///< Always decode PGP data
};
Q_DECLARE_FLAGS(EncryptionFlags, EncryptionFlag)
+ explicit EncryptedBodyPartFormatter(EncryptionFlag flag)
+ : mFlags(flag)
+ {
+ }
[[nodiscard]] MessagePartPtr process(Interface::BodyPart &part) const override;
- static const Interface::BodyPartFormatter *create(EncryptionFlags flags);
private:
EncryptionFlags mFlags;
diff --git a/mimetreeparser/src/bodyformatter/mailman.cpp b/mimetreeparser/src/bodyformatter/mailman.cpp
index 7a7043484..cb1c90f55 100644
--- a/mimetreeparser/src/bodyformatter/mailman.cpp
+++ b/mimetreeparser/src/bodyformatter/mailman.cpp
@@ -18,16 +18,6 @@
using namespace Qt::Literals::StringLiterals;
using namespace MimeTreeParser;
-const MailmanBodyPartFormatter *MailmanBodyPartFormatter::self;
-
-const Interface::BodyPartFormatter *MailmanBodyPartFormatter::create()
-{
- if (!self) {
- self = new MailmanBodyPartFormatter();
- }
- return self;
-}
-
bool MailmanBodyPartFormatter::isMailmanMessage(KMime::Content *curNode) const
{
if (!curNode || curNode->head().isEmpty()) {
diff --git a/mimetreeparser/src/bodyformatter/mailman.h b/mimetreeparser/src/bodyformatter/mailman.h
index 244881ac6..a4057b848 100644
--- a/mimetreeparser/src/bodyformatter/mailman.h
+++ b/mimetreeparser/src/bodyformatter/mailman.h
@@ -13,11 +13,8 @@ namespace MimeTreeParser
{
class MailmanBodyPartFormatter : public Interface::BodyPartFormatter
{
- static const MailmanBodyPartFormatter *self;
-
public:
[[nodiscard]] MessagePartPtr process(Interface::BodyPart &part) const override;
- static const Interface::BodyPartFormatter *create();
private:
[[nodiscard]] bool isMailmanMessage(KMime::Content *curNode) const;
diff --git a/mimetreeparser/src/bodyformatter/multipartalternative.cpp b/mimetreeparser/src/bodyformatter/multipartalternative.cpp
index 9c1faa047..e1763bd24 100644
--- a/mimetreeparser/src/bodyformatter/multipartalternative.cpp
+++ b/mimetreeparser/src/bodyformatter/multipartalternative.cpp
@@ -13,16 +13,6 @@
using namespace MimeTreeParser;
-const MultiPartAlternativeBodyPartFormatter *MultiPartAlternativeBodyPartFormatter::self;
-
-const Interface::BodyPartFormatter *MultiPartAlternativeBodyPartFormatter::create()
-{
- if (!self) {
- self = new MultiPartAlternativeBodyPartFormatter();
- }
- return self;
-}
-
MessagePart::Ptr MultiPartAlternativeBodyPartFormatter::process(Interface::BodyPart &part) const
{
KMime::Content *node = part.content();
diff --git a/mimetreeparser/src/bodyformatter/multipartalternative.h b/mimetreeparser/src/bodyformatter/multipartalternative.h
index e0392f335..bcd3673ad 100644
--- a/mimetreeparser/src/bodyformatter/multipartalternative.h
+++ b/mimetreeparser/src/bodyformatter/multipartalternative.h
@@ -13,10 +13,7 @@ namespace MimeTreeParser
{
class MultiPartAlternativeBodyPartFormatter : public Interface::BodyPartFormatter
{
- static const MultiPartAlternativeBodyPartFormatter *self;
-
public:
[[nodiscard]] MessagePartPtr process(Interface::BodyPart &part) const override;
- static const Interface::BodyPartFormatter *create();
};
}
diff --git a/mimetreeparser/src/bodyformatter/multipartencrypted.cpp b/mimetreeparser/src/bodyformatter/multipartencrypted.cpp
index 2fc37ce25..34383b7d3 100644
--- a/mimetreeparser/src/bodyformatter/multipartencrypted.cpp
+++ b/mimetreeparser/src/bodyformatter/multipartencrypted.cpp
@@ -19,16 +19,6 @@
using namespace MimeTreeParser;
-const MultiPartEncryptedBodyPartFormatter *MultiPartEncryptedBodyPartFormatter::self;
-
-const Interface::BodyPartFormatter *MultiPartEncryptedBodyPartFormatter::create()
-{
- if (!self) {
- self = new MultiPartEncryptedBodyPartFormatter();
- }
- return self;
-}
-
MessagePart::Ptr MultiPartEncryptedBodyPartFormatter::process(Interface::BodyPart &part) const
{
KMime::Content *node = part.content();
diff --git a/mimetreeparser/src/bodyformatter/multipartencrypted.h b/mimetreeparser/src/bodyformatter/multipartencrypted.h
index 93a21e5b0..b2c44afe1 100644
--- a/mimetreeparser/src/bodyformatter/multipartencrypted.h
+++ b/mimetreeparser/src/bodyformatter/multipartencrypted.h
@@ -13,10 +13,7 @@ namespace MimeTreeParser
{
class MultiPartEncryptedBodyPartFormatter : public Interface::BodyPartFormatter
{
- static const MultiPartEncryptedBodyPartFormatter *self;
-
public:
[[nodiscard]] MessagePartPtr process(Interface::BodyPart &part) const override;
- static const Interface::BodyPartFormatter *create();
};
}
diff --git a/mimetreeparser/src/bodyformatter/multipartmixed.cpp b/mimetreeparser/src/bodyformatter/multipartmixed.cpp
index d4272287a..2dc163426 100644
--- a/mimetreeparser/src/bodyformatter/multipartmixed.cpp
+++ b/mimetreeparser/src/bodyformatter/multipartmixed.cpp
@@ -13,16 +13,6 @@
using namespace MimeTreeParser;
-const MultiPartMixedBodyPartFormatter *MultiPartMixedBodyPartFormatter::self;
-
-const Interface::BodyPartFormatter *MultiPartMixedBodyPartFormatter::create()
-{
- if (!self) {
- self = new MultiPartMixedBodyPartFormatter();
- }
- return self;
-}
-
MessagePart::Ptr MultiPartMixedBodyPartFormatter::process(Interface::BodyPart &part) const
{
if (part.content()->contents().isEmpty()) {
diff --git a/mimetreeparser/src/bodyformatter/multipartmixed.h b/mimetreeparser/src/bodyformatter/multipartmixed.h
index 54e2d72dc..b61cace48 100644
--- a/mimetreeparser/src/bodyformatter/multipartmixed.h
+++ b/mimetreeparser/src/bodyformatter/multipartmixed.h
@@ -13,10 +13,7 @@ namespace MimeTreeParser
{
class MultiPartMixedBodyPartFormatter : public Interface::BodyPartFormatter
{
- static const MultiPartMixedBodyPartFormatter *self;
-
public:
[[nodiscard]] MessagePartPtr process(Interface::BodyPart &part) const override;
- static const Interface::BodyPartFormatter *create();
};
}
diff --git a/mimetreeparser/src/bodyformatter/multipartsigned.cpp b/mimetreeparser/src/bodyformatter/multipartsigned.cpp
index 3d3bdc016..eaddc11d8 100644
--- a/mimetreeparser/src/bodyformatter/multipartsigned.cpp
+++ b/mimetreeparser/src/bodyformatter/multipartsigned.cpp
@@ -17,16 +17,6 @@
using namespace MimeTreeParser;
-const MultiPartSignedBodyPartFormatter *MultiPartSignedBodyPartFormatter::self;
-
-const Interface::BodyPartFormatter *MultiPartSignedBodyPartFormatter::create()
-{
- if (!self) {
- self = new MultiPartSignedBodyPartFormatter();
- }
- return self;
-}
-
MessagePart::Ptr MultiPartSignedBodyPartFormatter::process(Interface::BodyPart &part) const
{
KMime::Content *node = part.content();
diff --git a/mimetreeparser/src/bodyformatter/multipartsigned.h b/mimetreeparser/src/bodyformatter/multipartsigned.h
index 9bad2a326..0e5444bd1 100644
--- a/mimetreeparser/src/bodyformatter/multipartsigned.h
+++ b/mimetreeparser/src/bodyformatter/multipartsigned.h
@@ -13,10 +13,7 @@ namespace MimeTreeParser
{
class MultiPartSignedBodyPartFormatter : public Interface::BodyPartFormatter
{
- static const MultiPartSignedBodyPartFormatter *self;
-
public:
[[nodiscard]] MessagePartPtr process(Interface::BodyPart &part) const override;
- static const Interface::BodyPartFormatter *create();
};
}
diff --git a/mimetreeparser/src/bodyformatter/texthtml.cpp b/mimetreeparser/src/bodyformatter/texthtml.cpp
index d3322886f..2502cf047 100644
--- a/mimetreeparser/src/bodyformatter/texthtml.cpp
+++ b/mimetreeparser/src/bodyformatter/texthtml.cpp
@@ -13,16 +13,6 @@
using namespace MimeTreeParser;
-const TextHtmlBodyPartFormatter *TextHtmlBodyPartFormatter::self;
-
-const Interface::BodyPartFormatter *TextHtmlBodyPartFormatter::create()
-{
- if (!self) {
- self = new TextHtmlBodyPartFormatter();
- }
- return self;
-}
-
MessagePart::Ptr TextHtmlBodyPartFormatter::process(Interface::BodyPart &part) const
{
KMime::Content *node = part.content();
diff --git a/mimetreeparser/src/bodyformatter/texthtml.h b/mimetreeparser/src/bodyformatter/texthtml.h
index 942feb5bb..82c8712f9 100644
--- a/mimetreeparser/src/bodyformatter/texthtml.h
+++ b/mimetreeparser/src/bodyformatter/texthtml.h
@@ -13,10 +13,7 @@ namespace MimeTreeParser
{
class TextHtmlBodyPartFormatter : public Interface::BodyPartFormatter
{
- static const TextHtmlBodyPartFormatter *self;
-
public:
[[nodiscard]] MessagePartPtr process(Interface::BodyPart &part) const override;
- static const Interface::BodyPartFormatter *create();
};
}
diff --git a/mimetreeparser/src/bodyformatter/textplain.cpp b/mimetreeparser/src/bodyformatter/textplain.cpp
index 72485d1fc..52fbb9805 100644
--- a/mimetreeparser/src/bodyformatter/textplain.cpp
+++ b/mimetreeparser/src/bodyformatter/textplain.cpp
@@ -13,16 +13,6 @@
using namespace MimeTreeParser;
-const TextPlainBodyPartFormatter *TextPlainBodyPartFormatter::self;
-
-const Interface::BodyPartFormatter *TextPlainBodyPartFormatter::create()
-{
- if (!self) {
- self = new TextPlainBodyPartFormatter();
- }
- return self;
-}
-
MessagePart::Ptr TextPlainBodyPartFormatter::process(Interface::BodyPart &part) const
{
KMime::Content *node = part.content();
diff --git a/mimetreeparser/src/bodyformatter/textplain.h b/mimetreeparser/src/bodyformatter/textplain.h
index 11aaf289c..304271d70 100644
--- a/mimetreeparser/src/bodyformatter/textplain.h
+++ b/mimetreeparser/src/bodyformatter/textplain.h
@@ -13,10 +13,7 @@ namespace MimeTreeParser
{
class TextPlainBodyPartFormatter : public Interface::BodyPartFormatter
{
- static const TextPlainBodyPartFormatter *self;
-
public:
[[nodiscard]] MessagePartPtr process(Interface::BodyPart &part) const override;
- static const Interface::BodyPartFormatter *create();
};
}
diff --git a/mimetreeparser/src/bodypartformatter.cpp b/mimetreeparser/src/bodypartformatter.cpp
index f3b19941a..a5ca79f9e 100644
--- a/mimetreeparser/src/bodypartformatter.cpp
+++ b/mimetreeparser/src/bodypartformatter.cpp
@@ -36,8 +36,6 @@ namespace
{
class AnyTypeBodyPartFormatter : public MimeTreeParser::Interface::BodyPartFormatter
{
- static const AnyTypeBodyPartFormatter *self;
-
public:
MessagePart::Ptr process(Interface::BodyPart &part) const override
{
@@ -50,31 +48,11 @@ public:
mp->setIsImage(false);
return mp;
}
-
- static const MimeTreeParser::Interface::BodyPartFormatter *create()
- {
- if (!self) {
- self = new AnyTypeBodyPartFormatter();
- }
- return self;
- }
};
-const AnyTypeBodyPartFormatter *AnyTypeBodyPartFormatter::self = nullptr;
-
class ImageTypeBodyPartFormatter : public MimeTreeParser::Interface::BodyPartFormatter
{
- static const ImageTypeBodyPartFormatter *self;
-
public:
- static const MimeTreeParser::Interface::BodyPartFormatter *create()
- {
- if (!self) {
- self = new ImageTypeBodyPartFormatter();
- }
- return self;
- }
-
MessagePart::Ptr process(Interface::BodyPart &part) const override
{
KMime::Content *node = part.content();
@@ -95,27 +73,12 @@ public:
}
};
-const ImageTypeBodyPartFormatter *ImageTypeBodyPartFormatter::self = nullptr;
-
class MessageRfc822BodyPartFormatter : public MimeTreeParser::Interface::BodyPartFormatter
{
- static const MessageRfc822BodyPartFormatter *self;
-
public:
MessagePart::Ptr process(Interface::BodyPart &) const override;
- static const MimeTreeParser::Interface::BodyPartFormatter *create();
};
-const MessageRfc822BodyPartFormatter *MessageRfc822BodyPartFormatter::self;
-
-const MimeTreeParser::Interface::BodyPartFormatter *MessageRfc822BodyPartFormatter::create()
-{
- if (!self) {
- self = new MessageRfc822BodyPartFormatter();
- }
- return self;
-}
-
MessagePart::Ptr MessageRfc822BodyPartFormatter::process(Interface::BodyPart &part) const
{
const std::shared_ptr<KMime::Message> message = part.content()->bodyAsMessage();
@@ -125,31 +88,31 @@ MessagePart::Ptr MessageRfc822BodyPartFormatter::process(Interface::BodyPart &pa
void BodyPartFormatterFactoryPrivate::messageviewer_create_builtin_bodypart_formatters()
{
- insert(u"application/pkcs7-mime"_s, ApplicationPkcs7MimeBodyPartFormatter::create());
- insert(u"application/x-pkcs7-mime"_s, ApplicationPkcs7MimeBodyPartFormatter::create());
- insert(u"application/pgp-encrypted"_s, ApplicationPGPEncryptedBodyPartFormatter::create());
-
- insert(u"application/octet-stream"_s, ApplicationPkcs7MimeBodyPartFormatter::create());
- insert(u"application/octet-stream"_s, EncryptedBodyPartFormatter::create(EncryptedBodyPartFormatter::AutoPGP));
- insert(u"application/octet-stream"_s, AnyTypeBodyPartFormatter::create());
-
- insert(u"text/pgp"_s, EncryptedBodyPartFormatter::create(EncryptedBodyPartFormatter::ForcePGP));
- insert(u"text/html"_s, TextHtmlBodyPartFormatter::create());
- insert(u"text/rtf"_s, AnyTypeBodyPartFormatter::create());
- insert(u"text/plain"_s, MailmanBodyPartFormatter::create());
- insert(u"text/plain"_s, TextPlainBodyPartFormatter::create());
-
- insert(u"image/png"_s, ImageTypeBodyPartFormatter::create());
- insert(u"image/jpeg"_s, ImageTypeBodyPartFormatter::create());
- insert(u"image/gif"_s, ImageTypeBodyPartFormatter::create());
- insert(u"image/svg+xml"_s, ImageTypeBodyPartFormatter::create());
- insert(u"image/bmp"_s, ImageTypeBodyPartFormatter::create());
- insert(u"image/vnd.microsoft.icon"_s, ImageTypeBodyPartFormatter::create());
-
- insert(u"message/rfc822"_s, MessageRfc822BodyPartFormatter::create());
-
- insert(u"multipart/alternative"_s, MultiPartAlternativeBodyPartFormatter::create());
- insert(u"multipart/encrypted"_s, MultiPartEncryptedBodyPartFormatter::create());
- insert(u"multipart/signed"_s, MultiPartSignedBodyPartFormatter::create());
- insert(u"multipart/mixed"_s, MultiPartMixedBodyPartFormatter::create());
+ insert(u"application/pkcs7-mime"_s, std::make_unique<ApplicationPkcs7MimeBodyPartFormatter>());
+ insert(u"application/x-pkcs7-mime"_s, std::make_unique<ApplicationPkcs7MimeBodyPartFormatter>());
+ insert(u"application/pgp-encrypted"_s, std::make_unique<ApplicationPGPEncryptedBodyPartFormatter>());
+
+ insert(u"application/octet-stream"_s, std::make_unique<ApplicationPkcs7MimeBodyPartFormatter>());
+ insert(u"application/octet-stream"_s, std::make_unique<EncryptedBodyPartFormatter>(EncryptedBodyPartFormatter::AutoPGP));
+ insert(u"application/octet-stream"_s, std::make_unique<AnyTypeBodyPartFormatter>());
+
+ insert(u"text/pgp"_s, std::make_unique<EncryptedBodyPartFormatter>(EncryptedBodyPartFormatter::ForcePGP));
+ insert(u"text/html"_s, std::make_unique<TextHtmlBodyPartFormatter>());
+ insert(u"text/rtf"_s, std::make_unique<AnyTypeBodyPartFormatter>());
+ insert(u"text/plain"_s, std::make_unique<MailmanBodyPartFormatter>());
+ insert(u"text/plain"_s, std::make_unique<TextPlainBodyPartFormatter>());
+
+ insert(u"image/png"_s, std::make_unique<ImageTypeBodyPartFormatter>());
+ insert(u"image/jpeg"_s, std::make_unique<ImageTypeBodyPartFormatter>());
+ insert(u"image/gif"_s, std::make_unique<ImageTypeBodyPartFormatter>());
+ insert(u"image/svg+xml"_s, std::make_unique<ImageTypeBodyPartFormatter>());
+ insert(u"image/bmp"_s, std::make_unique<ImageTypeBodyPartFormatter>());
+ insert(u"image/vnd.microsoft.icon"_s, std::make_unique<ImageTypeBodyPartFormatter>());
+
+ insert(u"message/rfc822"_s, std::make_unique<MessageRfc822BodyPartFormatter>());
+
+ insert(u"multipart/alternative"_s, std::make_unique<MultiPartAlternativeBodyPartFormatter>());
+ insert(u"multipart/encrypted"_s, std::make_unique<MultiPartEncryptedBodyPartFormatter>());
+ insert(u"multipart/signed"_s, std::make_unique<MultiPartSignedBodyPartFormatter>());
+ insert(u"multipart/mixed"_s, std::make_unique<MultiPartMixedBodyPartFormatter>());
}
diff --git a/mimetreeparser/src/bodypartformatterfactory.cpp b/mimetreeparser/src/bodypartformatterfactory.cpp
index 9627e8b5a..23d5548ec 100644
--- a/mimetreeparser/src/bodypartformatterfactory.cpp
+++ b/mimetreeparser/src/bodypartformatterfactory.cpp
@@ -29,15 +29,7 @@ BodyPartFormatterFactoryPrivate::BodyPartFormatterFactoryPrivate(BodyPartFormatt
{
}
-BodyPartFormatterFactoryPrivate::~BodyPartFormatterFactoryPrivate()
-{
- QHashIterator<QString, std::vector<FormatterInfo>> i(registry);
- while (i.hasNext()) {
- i.next();
- auto formatterInfo = i.value();
- formatterInfo.erase(formatterInfo.begin(), formatterInfo.end());
- }
-}
+BodyPartFormatterFactoryPrivate::~BodyPartFormatterFactoryPrivate() = default;
void BodyPartFormatterFactoryPrivate::setup()
{
@@ -48,7 +40,7 @@ void BodyPartFormatterFactoryPrivate::setup()
assert(!registry.empty());
}
-void BodyPartFormatterFactoryPrivate::insert(const QString &mimeType, const Interface::BodyPartFormatter *formatter, int priority)
+void BodyPartFormatterFactoryPrivate::insert(const QString &mimeType, std::unique_ptr<const Interface::BodyPartFormatter> &&formatter, int priority)
{
if (mimeType.isEmpty() || !formatter) {
return;
@@ -57,24 +49,24 @@ void BodyPartFormatterFactoryPrivate::insert(const QString &mimeType, const Inte
QMimeDatabase db;
const auto mt = db.mimeTypeForName(mimeType);
FormatterInfo info;
- info.formatter = formatter;
+ info.formatter = std::move(formatter);
info.priority = priority;
auto &v = registry[mt.isValid() ? mt.name() : mimeType];
- v.push_back(info);
- std::stable_sort(v.begin(), v.end(), [](FormatterInfo lhs, FormatterInfo rhs) {
+ v.push_back(std::move(info));
+ std::stable_sort(v.begin(), v.end(), [](const FormatterInfo &lhs, const FormatterInfo &rhs) {
return lhs.priority > rhs.priority;
});
}
void BodyPartFormatterFactoryPrivate::appendFormattersForType(const QString &mimeType, QList<const Interface::BodyPartFormatter *> &formatters)
{
- const auto it = registry.constFind(mimeType);
- if (it == registry.constEnd()) {
+ const auto it = registry.find(mimeType);
+ if (it == registry.end()) {
return;
}
- for (const auto &f : it.value()) {
- formatters.push_back(f.formatter);
+ for (const auto &f : (*it).second) {
+ formatters.push_back(f.formatter.get());
}
}
@@ -91,9 +83,9 @@ BodyPartFormatterFactory *BodyPartFormatterFactory::instance()
return &s_instance;
}
-void BodyPartFormatterFactory::insert(const QString &mimeType, const Interface::BodyPartFormatter *formatter, int priority)
+void BodyPartFormatterFactory::insert(const QString &mimeType, std::unique_ptr<const Interface::BodyPartFormatter> &&formatter, int priority)
{
- d->insert(mimeType.toLower(), formatter, priority);
+ d->insert(mimeType.toLower(), std::move(formatter), priority);
}
QList<const Interface::BodyPartFormatter *> BodyPartFormatterFactory::formattersForType(const QString &mimeType) const
@@ -151,7 +143,7 @@ void BodyPartFormatterFactory::loadPlugins()
continue;
}
- const MimeTreeParser::Interface::BodyPartFormatter *bfp = nullptr;
+ std::unique_ptr<const MimeTreeParser::Interface::BodyPartFormatter> bfp;
for (int i = 0; (bfp = plugin->bodyPartFormatter(i)) && i < formatterData.size(); ++i) {
const auto metaData = formatterData.at(i).toObject();
const auto mimetype = metaData.value(QLatin1StringView("mimetype")).toString();
@@ -162,7 +154,7 @@ void BodyPartFormatterFactory::loadPlugins()
// priority should always be higher than the built-in ones, otherwise what's the point?
const auto priority = metaData.value(QLatin1StringView("priority")).toInt() + 100;
qCDebug(MIMETREEPARSER_LOG) << "plugin for " << mimetype << priority;
- insert(mimetype, bfp, priority);
+ insert(mimetype, std::move(bfp), priority);
}
}
}
diff --git a/mimetreeparser/src/bodypartformatterfactory.h b/mimetreeparser/src/bodypartformatterfactory.h
index 8bb313461..94c7df891 100644
--- a/mimetreeparser/src/bodypartformatterfactory.h
+++ b/mimetreeparser/src/bodypartformatterfactory.h
@@ -65,7 +65,7 @@ protected:
* \param formatter The BodyPartFormatter to insert.
* \param priority The priority of the formatter.
*/
- void insert(const QString &mimeType, const Interface::BodyPartFormatter *formatter, int priority);
+ void insert(const QString &mimeType, std::unique_ptr<const Interface::BodyPartFormatter> &&formatter, int priority);
/*!
*/
virtual void loadPlugins();
diff --git a/mimetreeparser/src/bodypartformatterfactory_p.h b/mimetreeparser/src/bodypartformatterfactory_p.h
index e634f4ac1..7f7215a0f 100644
--- a/mimetreeparser/src/bodypartformatterfactory_p.h
+++ b/mimetreeparser/src/bodypartformatterfactory_p.h
@@ -10,13 +10,18 @@
#pragma once
-#include <QHash>
+#include <unordered_map>
#include <vector>
namespace MimeTreeParser
{
class BodyPartFormatterFactory;
+namespace Interface
+{
+class BodyPartFormatter;
+}
+
class BodyPartFormatterFactoryPrivate
{
public:
@@ -25,14 +30,14 @@ public:
void setup();
void messageviewer_create_builtin_bodypart_formatters(); // defined in bodypartformatter.cpp
- void insert(const QString &mimeType, const Interface::BodyPartFormatter *formatter, int priority = 0);
+ void insert(const QString &mimeType, std::unique_ptr<const Interface::BodyPartFormatter> &&formatter, int priority = 0);
void appendFormattersForType(const QString &mimeType, QList<const Interface::BodyPartFormatter *> &formatters);
BodyPartFormatterFactory *const q;
struct FormatterInfo {
- const Interface::BodyPartFormatter *formatter = nullptr;
+ std::unique_ptr<const Interface::BodyPartFormatter> formatter;
int priority = 0;
};
- QHash<QString, std::vector<FormatterInfo>> registry;
+ std::unordered_map<QString, std::vector<FormatterInfo>> registry;
};
}
diff --git a/mimetreeparser/src/interfaces/bodypartformatter.h b/mimetreeparser/src/interfaces/bodypartformatter.h
index 97cb5c258..5b4f43a95 100644
--- a/mimetreeparser/src/interfaces/bodypartformatter.h
+++ b/mimetreeparser/src/interfaces/bodypartformatter.h
@@ -66,9 +66,8 @@ public:
*/
virtual ~BodyPartFormatterPlugin();
- /*!
- */
- virtual const BodyPartFormatter *bodyPartFormatter(int idx) const = 0;
+ /*! Return a formatter instance for the Nth entry in the plugin metadata. */
+ [[nodiscard]] virtual std::unique_ptr<const BodyPartFormatter> bodyPartFormatter(int idx) const = 0;
};
} // namespace Interface
}