diff options
author | Thiago Macieira <thiago.macieira@intel.com> | 2024-04-23 07:49:57 -0700 |
---|---|---|
committer | Thiago Macieira <thiago.macieira@intel.com> | 2024-05-02 17:12:27 -0700 |
commit | 39e156e639ac4eadd7a0d4dac73d05db077e817b (patch) | |
tree | 56ce564f0ee1079a99bdd73751bf2788c9323508 /src/corelib/io | |
parent | bc5cd4dba8dceed808a573c6201acd9d210dc315 (diff) |
QResource: obey the MapPrivateOption option to provide RW memory
The documentation says:
The mapping will have the same open mode as the file (read and/or
write), except when using MapPrivateOption, in which case it is always
possible to write to the mapped memory.
So obey it.
This may cause high memory use by copying data we already have. This may
be important because applications may want to memory-map resources which
they intentionally didn't compress because those resources are
large. Later commits will implement some workarounds.
Fixes: QTBUG-124608
Pick-to: 6.7 6.6 6.5
Change-Id: I6979d02a7395405cbf23fffd17c8f03baf0ec00d
Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@gmx.de>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Diffstat (limited to 'src/corelib/io')
-rw-r--r-- | src/corelib/io/qresource.cpp | 17 |
1 files changed, 16 insertions, 1 deletions
diff --git a/src/corelib/io/qresource.cpp b/src/corelib/io/qresource.cpp index bad11b1479..a5cc979635 100644 --- a/src/corelib/io/qresource.cpp +++ b/src/corelib/io/qresource.cpp @@ -1349,6 +1349,7 @@ private: uchar *map(qint64 offset, qint64 size, QFile::MemoryMapFlags flags); bool unmap(uchar *ptr); void uncompress() const; + void mapUncompressed(); qint64 offset; QResource resource; mutable QByteArray uncompressed; @@ -1565,7 +1566,6 @@ bool QResourceFileEngine::supportsExtension(Extension extension) const uchar *QResourceFileEnginePrivate::map(qint64 offset, qint64 size, QFile::MemoryMapFlags flags) { Q_Q(QResourceFileEngine); - Q_UNUSED(flags); Q_ASSERT_X(resource.compressionAlgorithm() == QResource::NoCompression || !uncompressed.isNull(), "QFile::map()", "open() should have uncompressed compressed resources"); @@ -1584,6 +1584,12 @@ uchar *QResourceFileEnginePrivate::map(qint64 offset, qint64 size, QFile::Memory // resource was not compressed address = resource.data(); + if (flags & QFile::MapPrivateOption) { + // We need to provide read-write memory + mapUncompressed(); + address = reinterpret_cast<const uchar *>(uncompressed.constData()); + } + return const_cast<uchar *>(address) + offset; } @@ -1601,6 +1607,15 @@ void QResourceFileEnginePrivate::uncompress() const uncompressed = resource.uncompressedData(); } +void QResourceFileEnginePrivate::mapUncompressed() +{ + Q_ASSERT(resource.compressionAlgorithm() == QResource::NoCompression); + if (!uncompressed.isNull()) + return; // nothing to do + uncompressed = resource.uncompressedData(); + uncompressed.detach(); +} + #endif // !defined(QT_BOOTSTRAPPED) QT_END_NAMESPACE |