QTranslator: replace manual memory handling with std::unique_ptr

The QTranslator owns its QResource and its sub-translators, so hold
them in unique_ptr to show what's going on.

Change-Id: I65dfa8c3b6dd774066a01de23ae6cff7449b363a
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
This commit is contained in:
Marc Mutz 2020-05-24 11:19:48 +02:00
parent add92a551c
commit 033e5dc183

View File

@ -70,6 +70,9 @@
#include "qobject_p.h" #include "qobject_p.h"
#include <vector>
#include <memory>
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
enum Tag { Tag_End = 1, Tag_SourceText16, Tag_Translation, Tag_Context16, Tag_Obsolete1, enum Tag { Tag_End = 1, Tag_SourceText16, Tag_Translation, Tag_Context16, Tag_Obsolete1,
@ -300,10 +303,10 @@ public:
qsizetype unmapLength; qsizetype unmapLength;
// The resource object in case we loaded the translations from a resource // The resource object in case we loaded the translations from a resource
QResource *resource; std::unique_ptr<QResource> resource;
// used if the translator has dependencies // used if the translator has dependencies
QList<QTranslator*> subTranslators; std::vector<std::unique_ptr<QTranslator>> subTranslators;
// Pointers and offsets into unmapPointer[unmapLength] array, or user // Pointers and offsets into unmapPointer[unmapLength] array, or user
// provided data array // provided data array
@ -531,7 +534,7 @@ bool QTranslatorPrivate::do_load(const QString &realname, const QString &directo
// If the translation is in a non-compressed resource file, the data is already in // If the translation is in a non-compressed resource file, the data is already in
// memory, so no need to use QFile to copy it again. // memory, so no need to use QFile to copy it again.
Q_ASSERT(!d->resource); Q_ASSERT(!d->resource);
d->resource = new QResource(realname); d->resource = std::make_unique<QResource>(realname);
if (resource->isValid() && resource->compressionAlgorithm() == QResource::NoCompression if (resource->isValid() && resource->compressionAlgorithm() == QResource::NoCompression
&& resource->size() >= MagicLength && resource->size() >= MagicLength
&& !memcmp(resource->data(), magic, MagicLength)) { && !memcmp(resource->data(), magic, MagicLength)) {
@ -542,7 +545,6 @@ bool QTranslatorPrivate::do_load(const QString &realname, const QString &directo
#endif #endif
ok = true; ok = true;
} else { } else {
delete resource;
resource = nullptr; resource = nullptr;
} }
} }
@ -615,7 +617,6 @@ bool QTranslatorPrivate::do_load(const QString &realname, const QString &directo
if (!d->resource) if (!d->resource)
delete [] unmapPointer; delete [] unmapPointer;
delete d->resource;
d->resource = nullptr; d->resource = nullptr;
d->unmapPointer = nullptr; d->unmapPointer = nullptr;
d->unmapLength = 0; d->unmapLength = 0;
@ -864,21 +865,18 @@ bool QTranslatorPrivate::do_load(const uchar *data, qsizetype len, const QString
if (ok && !isValidNumerusRules(numerusRulesArray, numerusRulesLength)) if (ok && !isValidNumerusRules(numerusRulesArray, numerusRulesLength))
ok = false; ok = false;
if (ok) { if (ok) {
const int dependenciesCount = dependencies.count(); subTranslators.reserve(std::size_t(dependencies.size()));
subTranslators.reserve(dependenciesCount); for (const QString &dependency : std::as_const(dependencies)) {
for (int i = 0 ; i < dependenciesCount; ++i) { auto translator = std::make_unique<QTranslator>();
QTranslator *translator = new QTranslator; ok = translator->load(dependency, directory);
subTranslators.append(translator);
ok = translator->load(dependencies.at(i), directory);
if (!ok) if (!ok)
break; break;
subTranslators.push_back(std::move(translator));
} }
// In case some dependencies fail to load, unload all the other ones too. // In case some dependencies fail to load, unload all the other ones too.
if (!ok) { if (!ok)
qDeleteAll(subTranslators);
subTranslators.clear(); subTranslators.clear();
}
} }
if (!ok) { if (!ok) {
@ -1055,7 +1053,7 @@ QString QTranslatorPrivate::do_translate(const char *context, const char *source
} }
searchDependencies: searchDependencies:
for (QTranslator *translator : subTranslators) { for (const auto &translator : subTranslators) {
QString tn = translator->translate(context, sourceText, comment, n); QString tn = translator->translate(context, sourceText, comment, n);
if (!tn.isNull()) if (!tn.isNull())
return tn; return tn;
@ -1083,7 +1081,6 @@ void QTranslatorPrivate::clear()
delete [] unmapPointer; delete [] unmapPointer;
} }
delete resource;
resource = nullptr; resource = nullptr;
unmapPointer = nullptr; unmapPointer = nullptr;
unmapLength = 0; unmapLength = 0;
@ -1096,7 +1093,6 @@ void QTranslatorPrivate::clear()
offsetLength = 0; offsetLength = 0;
numerusRulesLength = 0; numerusRulesLength = 0;
qDeleteAll(subTranslators);
subTranslators.clear(); subTranslators.clear();
language.clear(); language.clear();
@ -1140,7 +1136,7 @@ bool QTranslator::isEmpty() const
{ {
Q_D(const QTranslator); Q_D(const QTranslator);
return !d->messageArray && !d->offsetArray && !d->contextArray return !d->messageArray && !d->offsetArray && !d->contextArray
&& d->subTranslators.isEmpty(); && d->subTranslators.empty();
} }
/*! /*!