QResource: quick refactor of registerSelf for files to support LFS
This commit adds sufficient support for large files in resources, but not completely because the rest Qt is not ready for it (and not tested). We've had the QT_MMAP macro in qplatformdefs.h for a while, so let's use it and use qsizetype where we can. This also the check that the file existed before opening it (you can only open it if it exists), plus a few nullptr updates. Change-Id: I42a48bd64ccc41aebf84fffd15653ffdabb0e66b Reviewed-by: Lars Knoll <lars.knoll@qt.io>
This commit is contained in:
parent
9ee29b826c
commit
12e843581a
@ -68,6 +68,11 @@
|
|||||||
# include "private/qcore_unix_p.h"
|
# include "private/qcore_unix_p.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(Q_OS_UNIX) && !defined(Q_OS_NACL) && !defined(Q_OS_INTEGRITY)
|
||||||
|
# define QT_USE_MMAP
|
||||||
|
# include <sys/mman.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
//#define DEBUG_RESOURCE_MATCH
|
//#define DEBUG_RESOURCE_MATCH
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
@ -969,7 +974,7 @@ public:
|
|||||||
ResourceRootType type() const override { return Resource_Buffer; }
|
ResourceRootType type() const override { return Resource_Buffer; }
|
||||||
|
|
||||||
// size == -1 means "unknown"
|
// size == -1 means "unknown"
|
||||||
bool registerSelf(const uchar *b, int size)
|
bool registerSelf(const uchar *b, qsizetype size)
|
||||||
{
|
{
|
||||||
// 5 int "pointers"
|
// 5 int "pointers"
|
||||||
if (size >= 0 && size < 20)
|
if (size >= 0 && size < 20)
|
||||||
@ -1010,28 +1015,12 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#if defined(Q_OS_UNIX) && !defined (Q_OS_NACL) && !defined(Q_OS_INTEGRITY)
|
|
||||||
#define QT_USE_MMAP
|
|
||||||
#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
|
|
||||||
QT_BEGIN_INCLUDE_NAMESPACE
|
|
||||||
#include <sys/mman.h>
|
|
||||||
#include <errno.h>
|
|
||||||
QT_END_INCLUDE_NAMESPACE
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class QDynamicFileResourceRoot: public QDynamicBufferResourceRoot
|
class QDynamicFileResourceRoot: public QDynamicBufferResourceRoot
|
||||||
{
|
{
|
||||||
QString fileName;
|
QString fileName;
|
||||||
// for mmap'ed files, this is what needs to be unmapped.
|
// for mmap'ed files, this is what needs to be unmapped.
|
||||||
uchar *unmapPointer;
|
uchar *unmapPointer;
|
||||||
unsigned int unmapLength;
|
qsizetype unmapLength;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
inline QDynamicFileResourceRoot(const QString &_root) : QDynamicBufferResourceRoot(_root), unmapPointer(0), unmapLength(0) { }
|
inline QDynamicFileResourceRoot(const QString &_root) : QDynamicBufferResourceRoot(_root), unmapPointer(0), unmapLength(0) { }
|
||||||
@ -1057,14 +1046,14 @@ public:
|
|||||||
# 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
|
||||||
|
|
||||||
bool QDynamicFileResourceRoot::registerSelf(const QString &f)
|
bool QDynamicFileResourceRoot::registerSelf(const QString &f)
|
||||||
{
|
{
|
||||||
bool fromMM = false;
|
bool fromMM = false;
|
||||||
uchar *data = 0;
|
uchar *data = nullptr;
|
||||||
unsigned int data_len = 0;
|
qsizetype data_len = 0;
|
||||||
|
|
||||||
#ifdef QT_USE_MMAP
|
#ifdef QT_USE_MMAP
|
||||||
int fd = QT_OPEN(QFile::encodeName(f), O_RDONLY,
|
int fd = QT_OPEN(QFile::encodeName(f), O_RDONLY,
|
||||||
@ -1076,35 +1065,35 @@ bool QDynamicFileResourceRoot::registerSelf(const QString &f)
|
|||||||
);
|
);
|
||||||
if (fd >= 0) {
|
if (fd >= 0) {
|
||||||
QT_STATBUF st;
|
QT_STATBUF st;
|
||||||
if (!QT_FSTAT(fd, &st)) {
|
if (!QT_FSTAT(fd, &st) && st.st_size <= std::numeric_limits<qsizetype>::max()) {
|
||||||
uchar *ptr;
|
int protection = PROT_READ; // read-only memory
|
||||||
ptr = reinterpret_cast<uchar *>(
|
int flags = MAP_FILE | MAP_PRIVATE; // swap-backed map from file
|
||||||
mmap(0, st.st_size, // any address, whole file
|
void *ptr = QT_MMAP(nullptr, st.st_size, // 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<uchar *>(MAP_FAILED)) {
|
data = static_cast<uchar *>(ptr);
|
||||||
data = ptr;
|
|
||||||
data_len = st.st_size;
|
data_len = st.st_size;
|
||||||
fromMM = true;
|
fromMM = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
::close(fd);
|
QT_CLOSE(fd);
|
||||||
}
|
}
|
||||||
#endif // QT_USE_MMAP
|
#endif // QT_USE_MMAP
|
||||||
if (!data) {
|
if (!data) {
|
||||||
QFile file(f);
|
QFile file(f);
|
||||||
if (!file.exists())
|
bool ok = false;
|
||||||
return false;
|
if (file.open(QIODevice::ReadOnly)) {
|
||||||
|
qint64 fsize = file.size();
|
||||||
|
if (fsize <= std::numeric_limits<qsizetype>::max()) {
|
||||||
data_len = file.size();
|
data_len = file.size();
|
||||||
data = new uchar[data_len];
|
data = new uchar[data_len];
|
||||||
|
ok = (data_len == file.read((char*)data, data_len));
|
||||||
bool ok = false;
|
}
|
||||||
if (file.open(QIODevice::ReadOnly))
|
}
|
||||||
ok = (data_len == (uint)file.read((char*)data, data_len));
|
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
delete [] data;
|
delete [] data;
|
||||||
data = 0;
|
data = nullptr;
|
||||||
data_len = 0;
|
data_len = 0;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user