QTranslator: add initial largefile support

Using QT_MMAP macro instead of mmap() so we could map more than 2 GB of
the file. Not that the file format supports such a thing, but just in
case.

Change-Id: Iae320a2868db402a993dfffd15689bba1d667c7d
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
Thiago Macieira 2018-11-19 11:00:51 -08:00
parent 121b0bfed5
commit 652098d40f

View File

@ -61,14 +61,8 @@
#if defined(Q_OS_UNIX) && !defined(Q_OS_INTEGRITY) #if defined(Q_OS_UNIX) && !defined(Q_OS_INTEGRITY)
#define QT_USE_MMAP #define QT_USE_MMAP
#include "private/qcore_unix_p.h" #include "private/qcore_unix_p.h"
#endif
// most of the headers below are already included in qplatformdefs.h
// also this lacks Large File support but that's probably irrelevant
#if defined(QT_USE_MMAP)
// for mmap // for mmap
#include <sys/mman.h> #include <sys/mman.h>
#include <errno.h>
#endif #endif
#include <stdlib.h> #include <stdlib.h>
@ -302,7 +296,7 @@ public:
bool used_mmap : 1; bool used_mmap : 1;
#endif #endif
char *unmapPointer; // used memory (mmap, new or resource file) char *unmapPointer; // used memory (mmap, new or resource file)
quint32 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; QResource *resource;
@ -322,7 +316,7 @@ public:
uint numerusRulesLength; uint numerusRulesLength;
bool do_load(const QString &filename, const QString &directory); bool do_load(const QString &filename, const QString &directory);
bool do_load(const uchar *data, int len, const QString &directory); bool do_load(const uchar *data, qsizetype len, const QString &directory);
QString do_translate(const char *context, const char *sourceText, const char *comment, QString do_translate(const char *context, const char *sourceText, const char *comment,
int n) const; int n) const;
void clear(); void clear();
@ -553,7 +547,7 @@ bool QTranslatorPrivate::do_load(const QString &realname, const QString &directo
return false; return false;
qint64 fileSize = file.size(); qint64 fileSize = file.size();
if (fileSize < MagicLength || quint32(-1) <= fileSize) if (fileSize < MagicLength || fileSize > std::numeric_limits<qsizetype>::max())
return false; return false;
{ {
@ -563,7 +557,7 @@ bool QTranslatorPrivate::do_load(const QString &realname, const QString &directo
return false; return false;
} }
d->unmapLength = quint32(fileSize); d->unmapLength = qsizetype(fileSize);
#ifdef QT_USE_MMAP #ifdef QT_USE_MMAP
@ -571,21 +565,20 @@ bool QTranslatorPrivate::do_load(const QString &realname, const QString &directo
#define MAP_FILE 0 #define MAP_FILE 0
#endif #endif
#ifndef MAP_FAILED #ifndef MAP_FAILED
#define MAP_FAILED -1 #define MAP_FAILED reinterpret_cast<void *>(-1)
#endif #endif
int fd = file.handle(); int fd = file.handle();
if (fd >= 0) { if (fd >= 0) {
char *ptr; int protection = PROT_READ; // read-only memory
ptr = reinterpret_cast<char *>( int flags = MAP_FILE | MAP_PRIVATE; // swap-backed map from file
mmap(0, d->unmapLength, // any address, whole file void *ptr = QT_MMAP(nullptr, d->unmapLength,// any address, whole file
PROT_READ, // read-only memory protection, flags,
MAP_FILE | MAP_PRIVATE, // swap-backed map from file fd, 0); // from offset 0 of fd
fd, 0)); // from offset 0 of fd if (ptr != MAP_FAILED) {
if (ptr && ptr != reinterpret_cast<char *>(MAP_FAILED)) {
file.close(); file.close();
d->used_mmap = true; d->used_mmap = true;
d->unmapPointer = ptr; d->unmapPointer = static_cast<char *>(ptr);
ok = true; ok = true;
} }
} }
@ -815,7 +808,7 @@ static quint32 read32(const uchar *data)
return qFromBigEndian<quint32>(data); return qFromBigEndian<quint32>(data);
} }
bool QTranslatorPrivate::do_load(const uchar *data, int len, const QString &directory) bool QTranslatorPrivate::do_load(const uchar *data, qsizetype len, const QString &directory)
{ {
bool ok = true; bool ok = true;
const uchar *end = data + len; const uchar *end = data + len;