summaryrefslogtreecommitdiffstats
path: root/src/corelib
diff options
context:
space:
mode:
authorThomas McGuire <thomas.mcguire.qnx@kdab.com>2012-10-29 17:14:07 +0100
committerThe Qt Project <gerrit-noreply@qt-project.org>2012-11-02 18:07:35 +0100
commit92d75077d686fcad26b5ad02a40c3987fb1fc82b (patch)
treef3d29d5543464fb78ea2ffe7657a2f7622219de3 /src/corelib
parent28f36ebcc246c90f82355bb0a40b3cca07913fae (diff)
QTranslator: Use resource memory instead of copying it
Previously, translations in resource files were loaded through QFile and the data was copied. Now, simply use the resource memory in-place. Change-Id: I55a06c1e7bb15c169cc69b908b3021136beac9d2 Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@digia.com>
Diffstat (limited to 'src/corelib')
-rw-r--r--src/corelib/kernel/qtranslator.cpp101
1 files changed, 66 insertions, 35 deletions
diff --git a/src/corelib/kernel/qtranslator.cpp b/src/corelib/kernel/qtranslator.cpp
index c4486d3ae6..f934202cf6 100644
--- a/src/corelib/kernel/qtranslator.cpp
+++ b/src/corelib/kernel/qtranslator.cpp
@@ -58,6 +58,7 @@
#include "qtranslator_p.h"
#include "qlocale.h"
#include "qendian.h"
+#include "qresource.h"
#if defined(Q_OS_UNIX) && !defined(Q_OS_INTEGRITY)
#define QT_USE_MMAP
@@ -292,16 +293,19 @@ public:
#if defined(QT_USE_MMAP)
used_mmap(0),
#endif
- unmapPointer(0), unmapLength(0),
+ unmapPointer(0), unmapLength(0), resource(0),
messageArray(0), offsetArray(0), contextArray(0), numerusRulesArray(0),
messageLength(0), offsetLength(0), contextLength(0), numerusRulesLength(0) {}
#if defined(QT_USE_MMAP)
bool used_mmap : 1;
#endif
- char *unmapPointer; // owned memory (mmap or new)
+ char *unmapPointer; // used memory (mmap, new or resource file)
quint32 unmapLength;
+ // The resource object in case we loaded the translations from a resource
+ QResource *resource;
+
// used if the translator has dependencies
QList<QTranslator*> subTranslators;
@@ -518,22 +522,42 @@ bool QTranslatorPrivate::do_load(const QString &realname, const QString &directo
QTranslatorPrivate *d = this;
bool ok = false;
- QFile file(realname);
- if (!file.open(QIODevice::ReadOnly | QIODevice::Unbuffered))
- return false;
+ if (realname.startsWith(':')) {
+ // 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.
+ Q_ASSERT(!d->resource);
+ d->resource = new QResource(realname);
+ if (resource->isValid() && !resource->isCompressed() && resource->size() > MagicLength
+ && !memcmp(resource->data(), magic, MagicLength)) {
+ d->unmapLength = resource->size();
+ d->unmapPointer = reinterpret_cast<char *>(const_cast<uchar *>(resource->data()));
+#if defined(QT_USE_MMAP)
+ d->used_mmap = false;
+#endif
+ ok = true;
+ } else {
+ delete resource;
+ resource = 0;
+ }
+ }
- qint64 fileSize = file.size();
- if (fileSize <= MagicLength || quint32(-1) <= fileSize)
- return false;
+ if (!ok) {
+ QFile file(realname);
+ if (!file.open(QIODevice::ReadOnly | QIODevice::Unbuffered))
+ return false;
- {
- char magicBuffer[MagicLength];
- if (MagicLength != file.read(magicBuffer, MagicLength)
- || memcmp(magicBuffer, magic, MagicLength))
+ qint64 fileSize = file.size();
+ if (fileSize <= MagicLength || quint32(-1) <= fileSize)
return false;
- }
- d->unmapLength = quint32(fileSize);
+ {
+ char magicBuffer[MagicLength];
+ if (MagicLength != file.read(magicBuffer, MagicLength)
+ || memcmp(magicBuffer, magic, MagicLength))
+ return false;
+ }
+
+ d->unmapLength = quint32(fileSize);
#ifdef QT_USE_MMAP
@@ -544,30 +568,31 @@ bool QTranslatorPrivate::do_load(const QString &realname, const QString &directo
#define MAP_FAILED -1
#endif
- int fd = file.handle();
- if (fd >= 0) {
- char *ptr;
- ptr = reinterpret_cast<char *>(
- mmap(0, d->unmapLength, // any address, whole file
- PROT_READ, // read-only memory
- MAP_FILE | MAP_PRIVATE, // swap-backed map from file
- fd, 0)); // from offset 0 of fd
- if (ptr && ptr != reinterpret_cast<char *>(MAP_FAILED)) {
- file.close();
- d->used_mmap = true;
- d->unmapPointer = ptr;
- ok = true;
+ int fd = file.handle();
+ if (fd >= 0) {
+ char *ptr;
+ ptr = reinterpret_cast<char *>(
+ mmap(0, d->unmapLength, // any address, whole file
+ PROT_READ, // read-only memory
+ MAP_FILE | MAP_PRIVATE, // swap-backed map from file
+ fd, 0)); // from offset 0 of fd
+ if (ptr && ptr != reinterpret_cast<char *>(MAP_FAILED)) {
+ file.close();
+ d->used_mmap = true;
+ d->unmapPointer = ptr;
+ ok = true;
+ }
}
- }
#endif // QT_USE_MMAP
- if (!ok) {
- d->unmapPointer = new char[d->unmapLength];
- if (d->unmapPointer) {
- file.seek(0);
- qint64 readResult = file.read(d->unmapPointer, d->unmapLength);
- if (readResult == qint64(unmapLength))
- ok = true;
+ if (!ok) {
+ d->unmapPointer = new char[d->unmapLength];
+ if (d->unmapPointer) {
+ file.seek(0);
+ qint64 readResult = file.read(d->unmapPointer, d->unmapLength);
+ if (readResult == qint64(unmapLength))
+ ok = true;
+ }
}
}
@@ -580,8 +605,11 @@ bool QTranslatorPrivate::do_load(const QString &realname, const QString &directo
munmap(unmapPointer, unmapLength);
} else
#endif
+ if (!d->resource)
delete [] unmapPointer;
+ delete d->resource;
+ d->resource = 0;
d->unmapPointer = 0;
d->unmapLength = 0;
@@ -1030,9 +1058,12 @@ void QTranslatorPrivate::clear()
munmap(unmapPointer, unmapLength);
} else
#endif
+ if (!resource)
delete [] unmapPointer;
}
+ delete resource;
+ resource = 0;
unmapPointer = 0;
unmapLength = 0;
messageArray = 0;