summaryrefslogtreecommitdiffstats
path: root/src/corelib/io
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/io')
-rw-r--r--src/corelib/io/qdir.cpp37
-rw-r--r--src/corelib/io/qdir_p.h6
-rw-r--r--src/corelib/io/qdiriterator.cpp6
-rw-r--r--src/corelib/io/qfile.cpp25
-rw-r--r--src/corelib/io/qfiledevice.cpp14
-rw-r--r--src/corelib/io/qfiledevice_p.h4
-rw-r--r--src/corelib/io/qfileinfo.cpp6
-rw-r--r--src/corelib/io/qfileinfo_p.h8
-rw-r--r--src/corelib/io/qfilesystemengine_unix.cpp4
-rw-r--r--src/corelib/io/qfilesystemiterator_unix.cpp47
-rw-r--r--src/corelib/io/qfilesystemwatcher_inotify.cpp27
-rw-r--r--src/corelib/io/qfsfileengine.cpp45
-rw-r--r--src/corelib/io/qfsfileengine_p.h10
-rw-r--r--src/corelib/io/qipaddress.cpp2
-rw-r--r--src/corelib/io/qprocess.cpp7
-rw-r--r--src/corelib/io/qprocess_p.h50
-rw-r--r--src/corelib/io/qprocess_unix.cpp2
-rw-r--r--src/corelib/io/qresource.cpp70
-rw-r--r--src/corelib/io/qresource.h5
-rw-r--r--src/corelib/io/qsavefile.cpp37
-rw-r--r--src/corelib/io/qstandardpaths.cpp2
-rw-r--r--src/corelib/io/qstandardpaths_unix.cpp75
-rw-r--r--src/corelib/io/qstorageinfo_unix.cpp14
-rw-r--r--src/corelib/io/qtemporaryfile.cpp16
-rw-r--r--src/corelib/io/qtldurl.cpp6
-rw-r--r--src/corelib/io/qurl.cpp2
-rw-r--r--src/corelib/io/qurlidna.cpp5
-rw-r--r--src/corelib/io/qurlquery.cpp10
28 files changed, 315 insertions, 227 deletions
diff --git a/src/corelib/io/qdir.cpp b/src/corelib/io/qdir.cpp
index 62dae3577c..fae935fc24 100644
--- a/src/corelib/io/qdir.cpp
+++ b/src/corelib/io/qdir.cpp
@@ -153,7 +153,7 @@ QDirPrivate::QDirPrivate(const QDirPrivate &copy)
bool QDirPrivate::exists() const
{
- if (fileEngine.isNull()) {
+ if (!fileEngine) {
QFileSystemEngine::fillMetaData(dirEntry, metaData,
QFileSystemMetaData::ExistsAttribute | QFileSystemMetaData::DirectoryType); // always stat
return metaData.exists() && metaData.isDirectory();
@@ -226,7 +226,7 @@ inline void QDirPrivate::resolveAbsoluteEntry() const
return;
QString absoluteName;
- if (fileEngine.isNull()) {
+ if (!fileEngine) {
if (!dirEntry.isRelative() && dirEntry.isClean()) {
absoluteDirEntry = dirEntry;
return;
@@ -693,7 +693,7 @@ QString QDir::absolutePath() const
QString QDir::canonicalPath() const
{
const QDirPrivate* d = d_ptr.constData();
- if (d->fileEngine.isNull()) {
+ if (!d->fileEngine) {
QFileSystemEntry answer = QFileSystemEngine::canonicalName(d->dirEntry, d->metaData);
return answer.filePath();
}
@@ -947,6 +947,12 @@ QString QDir::fromNativeSeparators(const QString &pathName)
int i = pathName.indexOf(QLatin1Char('\\'));
if (i != -1) {
QString n(pathName);
+ if (n.startsWith(QLatin1String("\\\\?\\"))) {
+ n.remove(0, 4);
+ i = n.indexOf(QLatin1Char('\\'));
+ if (i == -1)
+ return n;
+ }
QChar * const data = n.data();
data[i++] = QLatin1Char('/');
@@ -1496,7 +1502,7 @@ bool QDir::mkdir(const QString &dirName) const
}
QString fn = filePath(dirName);
- if (d->fileEngine.isNull())
+ if (!d->fileEngine)
return QFileSystemEngine::createDirectory(QFileSystemEntry(fn), false);
return d->fileEngine->mkdir(fn, false);
}
@@ -1520,7 +1526,7 @@ bool QDir::rmdir(const QString &dirName) const
}
QString fn = filePath(dirName);
- if (d->fileEngine.isNull())
+ if (!d->fileEngine)
return QFileSystemEngine::removeDirectory(QFileSystemEntry(fn), false);
return d->fileEngine->rmdir(fn, false);
@@ -1548,7 +1554,7 @@ bool QDir::mkpath(const QString &dirPath) const
}
QString fn = filePath(dirPath);
- if (d->fileEngine.isNull())
+ if (!d->fileEngine)
return QFileSystemEngine::createDirectory(QFileSystemEntry(fn), true);
return d->fileEngine->mkdir(fn, true);
}
@@ -1574,7 +1580,7 @@ bool QDir::rmpath(const QString &dirPath) const
}
QString fn = filePath(dirPath);
- if (d->fileEngine.isNull())
+ if (!d->fileEngine)
return QFileSystemEngine::removeDirectory(QFileSystemEntry(fn), true);
return d->fileEngine->rmdir(fn, true);
}
@@ -1647,7 +1653,7 @@ bool QDir::isReadable() const
{
const QDirPrivate* d = d_ptr.constData();
- if (d->fileEngine.isNull()) {
+ if (!d->fileEngine) {
if (!d->metaData.hasFlags(QFileSystemMetaData::UserReadPermission))
QFileSystemEngine::fillMetaData(d->dirEntry, d->metaData, QFileSystemMetaData::UserReadPermission);
@@ -1692,7 +1698,7 @@ bool QDir::exists() const
*/
bool QDir::isRoot() const
{
- if (d_ptr->fileEngine.isNull())
+ if (!d_ptr->fileEngine)
return d_ptr->dirEntry.isRoot();
return d_ptr->fileEngine->fileFlags(QAbstractFileEngine::FlagsMask) & QAbstractFileEngine::RootFlag;
}
@@ -1724,7 +1730,7 @@ bool QDir::isRoot() const
*/
bool QDir::isRelative() const
{
- if (d_ptr->fileEngine.isNull())
+ if (!d_ptr->fileEngine)
return d_ptr->dirEntry.isRelative();
return d_ptr->fileEngine->isRelativePath();
}
@@ -1741,7 +1747,7 @@ bool QDir::makeAbsolute()
{
const QDirPrivate *d = d_ptr.constData();
QScopedPointer<QDirPrivate> dir;
- if (!d->fileEngine.isNull()) {
+ if (!!d->fileEngine) {
QString absolutePath = d->fileEngine->fileName(QAbstractFileEngine::AbsoluteName);
if (QDir::isRelativePath(absolutePath))
return false;
@@ -1774,8 +1780,8 @@ bool QDir::operator==(const QDir &dir) const
if (d == other)
return true;
Qt::CaseSensitivity sensitive;
- if (d->fileEngine.isNull() || other->fileEngine.isNull()) {
- if (d->fileEngine.data() != other->fileEngine.data()) // one is native, the other is a custom file-engine
+ if (!d->fileEngine || !other->fileEngine) {
+ if (d->fileEngine.get() != other->fileEngine.get()) // one is native, the other is a custom file-engine
return false;
sensitive = QFileSystemEngine::isCaseSensitive() ? Qt::CaseSensitive : Qt::CaseInsensitive;
@@ -2339,6 +2345,11 @@ static QString qt_cleanPath(const QString &path, bool *ok)
if (path.isEmpty())
return path;
QString name = path;
+#if defined (Q_OS_WIN)
+ if (name.startsWith(QLatin1String("\\\\?\\")))
+ name.remove(0, 4);
+#endif
+
QChar dir_separator = QDir::separator();
if (dir_separator != QLatin1Char('/'))
name.replace(dir_separator, QLatin1Char('/'));
diff --git a/src/corelib/io/qdir_p.h b/src/corelib/io/qdir_p.h
index 0f3ab7f899..af105de8db 100644
--- a/src/corelib/io/qdir_p.h
+++ b/src/corelib/io/qdir_p.h
@@ -54,6 +54,8 @@
#include "qfilesystementry_p.h"
#include "qfilesystemmetadata_p.h"
+#include <memory>
+
QT_BEGIN_NAMESPACE
class QDirPrivate : public QSharedData
@@ -82,7 +84,7 @@ public:
static inline QChar getFilterSepChar(const QString &nameFilter);
- static inline QStringList splitFilters(const QString &nameFilter, QChar sep = 0);
+ static inline QStringList splitFilters(const QString &nameFilter, QChar sep = {});
void setPath(const QString &path);
@@ -98,7 +100,7 @@ public:
QDir::SortFlags sort;
QDir::Filters filters;
- QScopedPointer<QAbstractFileEngine> fileEngine;
+ std::unique_ptr<QAbstractFileEngine> fileEngine;
QFileSystemEntry dirEntry;
mutable QFileSystemEntry absoluteDirEntry;
diff --git a/src/corelib/io/qdiriterator.cpp b/src/corelib/io/qdiriterator.cpp
index 303caf29a4..ce436b06e3 100644
--- a/src/corelib/io/qdiriterator.cpp
+++ b/src/corelib/io/qdiriterator.cpp
@@ -107,6 +107,8 @@
#include <QtCore/private/qfilesystemengine_p.h>
#include <QtCore/private/qfileinfo_p.h>
+#include <memory>
+
QT_BEGIN_NAMESPACE
template <class Iterator>
@@ -132,7 +134,7 @@ public:
void checkAndPushDirectory(const QFileInfo &);
bool matchesFilters(const QString &fileName, const QFileInfo &fi) const;
- QScopedPointer<QAbstractFileEngine> engine;
+ std::unique_ptr<QAbstractFileEngine> engine;
QFileSystemEntry dirEntry;
const QStringList nameFilters;
@@ -435,7 +437,7 @@ bool QDirIteratorPrivate::matchesFilters(const QString &fileName, const QFileInf
QDirIterator::QDirIterator(const QDir &dir, IteratorFlags flags)
{
const QDirPrivate *other = dir.d_ptr.constData();
- d.reset(new QDirIteratorPrivate(other->dirEntry, other->nameFilters, other->filters, flags, !other->fileEngine.isNull()));
+ d.reset(new QDirIteratorPrivate(other->dirEntry, other->nameFilters, other->filters, flags, bool(other->fileEngine)));
}
/*!
diff --git a/src/corelib/io/qfile.cpp b/src/corelib/io/qfile.cpp
index 9f9a9e3040..95f03ef816 100644
--- a/src/corelib/io/qfile.cpp
+++ b/src/corelib/io/qfile.cpp
@@ -55,6 +55,8 @@
# include "qcoreapplication.h"
#endif
+#include <private/qmemory_p.h>
+
#ifdef QT_NO_QOBJECT
#define tr(X) QString::fromLatin1(X)
#endif
@@ -85,10 +87,9 @@ QFilePrivate::openExternalFile(int flags, int fd, QFile::FileHandleFlags handleF
Q_UNUSED(fd);
return false;
#else
- delete fileEngine;
- fileEngine = nullptr;
- QFSFileEngine *fe = new QFSFileEngine;
- fileEngine = fe;
+ auto fs = qt_make_unique<QFSFileEngine>();
+ auto fe = fs.get();
+ fileEngine = std::move(fs);
return fe->open(QIODevice::OpenMode(flags), fd, handleFlags);
#endif
}
@@ -101,10 +102,9 @@ QFilePrivate::openExternalFile(int flags, FILE *fh, QFile::FileHandleFlags handl
Q_UNUSED(fh);
return false;
#else
- delete fileEngine;
- fileEngine = nullptr;
- QFSFileEngine *fe = new QFSFileEngine;
- fileEngine = fe;
+ auto fs = qt_make_unique<QFSFileEngine>();
+ auto fe = fs.get();
+ fileEngine = std::move(fs);
return fe->open(QIODevice::OpenMode(flags), fh, handleFlags);
#endif
}
@@ -112,8 +112,8 @@ QFilePrivate::openExternalFile(int flags, FILE *fh, QFile::FileHandleFlags handl
QAbstractFileEngine *QFilePrivate::engine() const
{
if (!fileEngine)
- fileEngine = QAbstractFileEngine::create(fileName);
- return fileEngine;
+ fileEngine.reset(QAbstractFileEngine::create(fileName));
+ return fileEngine.get();
}
//************* QFile
@@ -334,10 +334,7 @@ QFile::setFileName(const QString &name)
file_already_open(*this, "setFileName");
close();
}
- if(d->fileEngine) { //get a new file engine later
- delete d->fileEngine;
- d->fileEngine = nullptr;
- }
+ d->fileEngine.reset(); //get a new file engine later
d->fileName = name;
}
diff --git a/src/corelib/io/qfiledevice.cpp b/src/corelib/io/qfiledevice.cpp
index 2f74547054..ee619d99cc 100644
--- a/src/corelib/io/qfiledevice.cpp
+++ b/src/corelib/io/qfiledevice.cpp
@@ -42,6 +42,8 @@
#include "qfiledevice_p.h"
#include "qfsfileengine_p.h"
+#include <private/qmemory_p.h>
+
#ifdef QT_NO_QOBJECT
#define tr(X) QString::fromLatin1(X)
#endif
@@ -53,24 +55,20 @@ QT_BEGIN_NAMESPACE
#endif
QFileDevicePrivate::QFileDevicePrivate()
- : fileEngine(nullptr),
- cachedSize(0),
+ : cachedSize(0),
error(QFile::NoError), lastWasWrite(false)
{
writeBufferChunkSize = QFILE_WRITEBUFFER_SIZE;
}
QFileDevicePrivate::~QFileDevicePrivate()
-{
- delete fileEngine;
- fileEngine = nullptr;
-}
+ = default;
QAbstractFileEngine * QFileDevicePrivate::engine() const
{
if (!fileEngine)
- fileEngine = new QFSFileEngine;
- return fileEngine;
+ fileEngine = qt_make_unique<QFSFileEngine>();
+ return fileEngine.get();
}
void QFileDevicePrivate::setError(QFileDevice::FileError err)
diff --git a/src/corelib/io/qfiledevice_p.h b/src/corelib/io/qfiledevice_p.h
index 47053d01b7..aef3fca811 100644
--- a/src/corelib/io/qfiledevice_p.h
+++ b/src/corelib/io/qfiledevice_p.h
@@ -53,6 +53,8 @@
#include "private/qiodevice_p.h"
+#include <memory>
+
QT_BEGIN_NAMESPACE
class QAbstractFileEngine;
@@ -75,7 +77,7 @@ protected:
void setError(QFileDevice::FileError err, const QString &errorString);
void setError(QFileDevice::FileError err, int errNum);
- mutable QAbstractFileEngine *fileEngine;
+ mutable std::unique_ptr<QAbstractFileEngine> fileEngine;
mutable qint64 cachedSize;
QFileDevice::FileHandleFlags handleFlags;
diff --git a/src/corelib/io/qfileinfo.cpp b/src/corelib/io/qfileinfo.cpp
index f5b398feae..a5a3bc8b3e 100644
--- a/src/corelib/io/qfileinfo.cpp
+++ b/src/corelib/io/qfileinfo.cpp
@@ -707,11 +707,11 @@ bool QFileInfo::exists(const QString &file)
return false;
QFileSystemEntry entry(file);
QFileSystemMetaData data;
- QAbstractFileEngine *engine =
- QFileSystemEngine::resolveEntryAndCreateLegacyEngine(entry, data);
+ std::unique_ptr<QAbstractFileEngine> engine
+ {QFileSystemEngine::resolveEntryAndCreateLegacyEngine(entry, data)};
// Expensive fallback to non-QFileSystemEngine implementation
if (engine)
- return QFileInfo(new QFileInfoPrivate(entry, data, engine)).exists();
+ return QFileInfo(new QFileInfoPrivate(entry, data, std::move(engine))).exists();
QFileSystemEngine::fillMetaData(entry, data, QFileSystemMetaData::ExistsAttribute);
return data.exists();
diff --git a/src/corelib/io/qfileinfo_p.h b/src/corelib/io/qfileinfo_p.h
index 36f440812f..333ea70adc 100644
--- a/src/corelib/io/qfileinfo_p.h
+++ b/src/corelib/io/qfileinfo_p.h
@@ -61,6 +61,8 @@
#include <QtCore/private/qfilesystementry_p.h>
#include <QtCore/private/qfilesystemmetadata_p.h>
+#include <memory>
+
QT_BEGIN_NAMESPACE
class QFileInfoPrivate : public QSharedData
@@ -126,10 +128,10 @@ public:
metaData = QFileSystemMetaData();
}
- inline QFileInfoPrivate(const QFileSystemEntry &file, const QFileSystemMetaData &data, QAbstractFileEngine *engine)
+ inline QFileInfoPrivate(const QFileSystemEntry &file, const QFileSystemMetaData &data, std::unique_ptr<QAbstractFileEngine> engine)
: fileEntry(file),
metaData(data),
- fileEngine(engine),
+ fileEngine{std::move(engine)},
cachedFlags(0),
#ifndef QT_NO_FSFILEENGINE
isDefaultConstructed(false),
@@ -163,7 +165,7 @@ public:
QFileSystemEntry fileEntry;
mutable QFileSystemMetaData metaData;
- QScopedPointer<QAbstractFileEngine> const fileEngine;
+ std::unique_ptr<QAbstractFileEngine> const fileEngine;
mutable QString fileNames[QAbstractFileEngine::NFileNames];
mutable QString fileOwners[2]; // QAbstractFileEngine::FileOwner: OwnerUser and OwnerGroup
diff --git a/src/corelib/io/qfilesystemengine_unix.cpp b/src/corelib/io/qfilesystemengine_unix.cpp
index 066a7c3f01..74865fe31f 100644
--- a/src/corelib/io/qfilesystemengine_unix.cpp
+++ b/src/corelib/io/qfilesystemengine_unix.cpp
@@ -822,6 +822,8 @@ QString QFileSystemEngine::resolveUserName(uint userId)
#endif
if (pw)
return QFile::decodeName(QByteArray(pw->pw_name));
+#else // Integrity || WASM
+ Q_UNUSED(userId);
#endif
return QString();
}
@@ -859,6 +861,8 @@ QString QFileSystemEngine::resolveGroupName(uint groupId)
#endif
if (gr)
return QFile::decodeName(QByteArray(gr->gr_name));
+#else // Integrity || WASM
+ Q_UNUSED(groupId);
#endif
return QString();
}
diff --git a/src/corelib/io/qfilesystemiterator_unix.cpp b/src/corelib/io/qfilesystemiterator_unix.cpp
index 5ac7e13a2e..2d09c277eb 100644
--- a/src/corelib/io/qfilesystemiterator_unix.cpp
+++ b/src/corelib/io/qfilesystemiterator_unix.cpp
@@ -40,13 +40,54 @@
#include "qplatformdefs.h"
#include "qfilesystemiterator_p.h"
+#if QT_CONFIG(textcodec)
+# include <qtextcodec.h>
+# include <private/qutfcodec_p.h>
+#endif
+
#ifndef QT_NO_FILESYSTEMITERATOR
+#include <memory>
+
#include <stdlib.h>
#include <errno.h>
QT_BEGIN_NAMESPACE
+static bool checkNameDecodable(const char *d_name, qsizetype len)
+{
+ // This function is called in a loop from advance() below, but the loop is
+ // usually run only once.
+
+#if QT_CONFIG(textcodec)
+ // We identify the codecs by their RFC 2978 MIBenum values. In this
+ // function:
+ // 3 US-ASCII (ANSI X3.4-1986)
+ // 4 Latin1 (ISO-8859-1)
+ // 106 UTF-8
+ QTextCodec *codec = QTextCodec::codecForLocale();
+# ifdef QT_LOCALE_IS_UTF8
+ int mibEnum = 106;
+# else
+ int mibEnum = codec->mibEnum();
+# endif
+ if (Q_LIKELY(mibEnum == 106)) // UTF-8
+ return QUtf8::isValidUtf8(d_name, len).isValidUtf8;
+ if (mibEnum == 3) // US-ASCII
+ return QtPrivate::isAscii(QLatin1String(d_name, len));
+ if (mibEnum == 4) // Latin 1
+ return true;
+
+ // fall back to generic QTextCodec
+ QTextCodec::ConverterState cs(QTextCodec::IgnoreHeader);
+ codec->toUnicode(d_name, len, &cs);
+ return cs.invalidChars == 0 && cs.remainingChars == 0;
+#else
+ // if we have no text codecs, then QString::fromLocal8Bit is fromLatin1
+ return true;
+#endif
+}
+
QFileSystemIterator::QFileSystemIterator(const QFileSystemEntry &entry, QDir::Filters filters,
const QStringList &nameFilters, QDirIterator::IteratorFlags flags)
: nativePath(entry.nativeFilePath())
@@ -81,9 +122,9 @@ bool QFileSystemIterator::advance(QFileSystemEntry &fileEntry, QFileSystemMetaDa
dirEntry = QT_READDIR(dir);
if (dirEntry) {
- // process entries with correct UTF-8 names only
- if (QFile::encodeName(QFile::decodeName(dirEntry->d_name)) == dirEntry->d_name) {
- fileEntry = QFileSystemEntry(nativePath + QByteArray(dirEntry->d_name), QFileSystemEntry::FromNativePath());
+ qsizetype len = strlen(dirEntry->d_name);
+ if (checkNameDecodable(dirEntry->d_name, len)) {
+ fileEntry = QFileSystemEntry(nativePath + QByteArray(dirEntry->d_name, len), QFileSystemEntry::FromNativePath());
metaData.fillFromDirEnt(*dirEntry);
return true;
}
diff --git a/src/corelib/io/qfilesystemwatcher_inotify.cpp b/src/corelib/io/qfilesystemwatcher_inotify.cpp
index 5fb5685f42..ca1f6cc359 100644
--- a/src/corelib/io/qfilesystemwatcher_inotify.cpp
+++ b/src/corelib/io/qfilesystemwatcher_inotify.cpp
@@ -422,16 +422,27 @@ void QInotifyFileSystemWatcherEngine::readFromInotify()
}
}
-QString QInotifyFileSystemWatcherEngine::getPathFromID(int id) const
+template <typename Hash, typename Key>
+typename Hash::const_iterator
+find_last_in_equal_range(const Hash &c, const Key &key)
{
- QHash<int, QString>::const_iterator i = idToPath.find(id);
- while (i != idToPath.constEnd() && i.key() == id) {
- if ((i + 1) == idToPath.constEnd() || (i + 1).key() != id) {
- return i.value();
- }
+ // find c.equal_range(key).second - 1 without backwards iteration:
+ auto i = c.find(key);
+ const auto end = c.cend();
+ if (i == end)
+ return end;
+ decltype(i) prev;
+ do {
+ prev = i;
++i;
- }
- return QString();
+ } while (i != end && i.key() == key);
+ return prev;
+}
+
+QString QInotifyFileSystemWatcherEngine::getPathFromID(int id) const
+{
+ auto i = find_last_in_equal_range(idToPath, id);
+ return i == idToPath.cend() ? QString() : i.value() ;
}
QT_END_NAMESPACE
diff --git a/src/corelib/io/qfsfileengine.cpp b/src/corelib/io/qfsfileengine.cpp
index 0db27f3e25..0d73839f8d 100644
--- a/src/corelib/io/qfsfileengine.cpp
+++ b/src/corelib/io/qfsfileengine.cpp
@@ -167,19 +167,21 @@ QFSFileEngine::QFSFileEngine(QFSFileEnginePrivate &dd)
/*!
\internal
*/
-bool QFSFileEngine::processOpenModeFlags(QIODevice::OpenMode *mode)
+ProcessOpenModeResult processOpenModeFlags(QIODevice::OpenMode openMode)
{
- QIODevice::OpenMode &openMode = *mode;
+ ProcessOpenModeResult result;
+ result.ok = false;
if ((openMode & QFile::NewOnly) && (openMode & QFile::ExistingOnly)) {
qWarning("NewOnly and ExistingOnly are mutually exclusive");
- setError(QFile::OpenError, QLatin1String("NewOnly and ExistingOnly are mutually exclusive"));
- return false;
+ result.error = QLatin1String("NewOnly and ExistingOnly are mutually exclusive");
+ return result;
}
if ((openMode & QFile::ExistingOnly) && !(openMode & (QFile::ReadOnly | QFile::WriteOnly))) {
qWarning("ExistingOnly must be specified alongside ReadOnly, WriteOnly, or ReadWrite");
- setError(QFile::OpenError, QLatin1String("ExistingOnly must be specified alongside ReadOnly, WriteOnly, or ReadWrite"));
- return false;
+ result.error = QLatin1String(
+ "ExistingOnly must be specified alongside ReadOnly, WriteOnly, or ReadWrite");
+ return result;
}
// Either Append or NewOnly implies WriteOnly
@@ -190,7 +192,9 @@ bool QFSFileEngine::processOpenModeFlags(QIODevice::OpenMode *mode)
if ((openMode & QFile::WriteOnly) && !(openMode & (QFile::ReadOnly | QFile::Append | QFile::NewOnly)))
openMode |= QFile::Truncate;
- return true;
+ result.ok = true;
+ result.openMode = openMode;
+ return result;
}
/*!
@@ -234,16 +238,19 @@ bool QFSFileEngine::open(QIODevice::OpenMode openMode)
return false;
}
- if (!processOpenModeFlags(&openMode))
+ const ProcessOpenModeResult res = processOpenModeFlags(openMode);
+ if (!res.ok) {
+ setError(QFileDevice::OpenError, res.error);
return false;
+ }
- d->openMode = openMode;
+ d->openMode = res.openMode;
d->lastFlushFailed = false;
d->tried_stat = 0;
d->fh = nullptr;
d->fd = -1;
- return d->nativeOpen(openMode);
+ return d->nativeOpen(d->openMode);
}
/*!
@@ -262,17 +269,20 @@ bool QFSFileEngine::open(QIODevice::OpenMode openMode, FILE *fh, QFile::FileHand
Q_D(QFSFileEngine);
- if (!processOpenModeFlags(&openMode))
+ const ProcessOpenModeResult res = processOpenModeFlags(openMode);
+ if (!res.ok) {
+ setError(QFileDevice::OpenError, res.error);
return false;
+ }
- d->openMode = openMode;
+ d->openMode = res.openMode;
d->lastFlushFailed = false;
d->closeFileHandle = (handleFlags & QFile::AutoCloseHandle);
d->fileEntry.clear();
d->tried_stat = 0;
d->fd = -1;
- return d->openFh(openMode, fh);
+ return d->openFh(d->openMode, fh);
}
/*!
@@ -321,10 +331,13 @@ bool QFSFileEngine::open(QIODevice::OpenMode openMode, int fd, QFile::FileHandle
{
Q_D(QFSFileEngine);
- if (!processOpenModeFlags(&openMode))
+ const ProcessOpenModeResult res = processOpenModeFlags(openMode);
+ if (!res.ok) {
+ setError(QFileDevice::OpenError, res.error);
return false;
+ }
- d->openMode = openMode;
+ d->openMode = res.openMode;
d->lastFlushFailed = false;
d->closeFileHandle = (handleFlags & QFile::AutoCloseHandle);
d->fileEntry.clear();
@@ -332,7 +345,7 @@ bool QFSFileEngine::open(QIODevice::OpenMode openMode, int fd, QFile::FileHandle
d->fd = -1;
d->tried_stat = 0;
- return d->openFd(openMode, fd);
+ return d->openFd(d->openMode, fd);
}
diff --git a/src/corelib/io/qfsfileengine_p.h b/src/corelib/io/qfsfileengine_p.h
index 0f416f4886..639c01571a 100644
--- a/src/corelib/io/qfsfileengine_p.h
+++ b/src/corelib/io/qfsfileengine_p.h
@@ -61,6 +61,13 @@
QT_BEGIN_NAMESPACE
+struct ProcessOpenModeResult {
+ bool ok;
+ QIODevice::OpenMode openMode;
+ QString error;
+};
+Q_CORE_EXPORT ProcessOpenModeResult processOpenModeFlags(QIODevice::OpenMode mode);
+
class QFSFileEnginePrivate;
class Q_CORE_EXPORT QFSFileEngine : public QAbstractFileEngine
@@ -131,9 +138,6 @@ public:
protected:
QFSFileEngine(QFSFileEnginePrivate &dd);
-
-private:
- inline bool processOpenModeFlags(QIODevice::OpenMode *mode);
};
class Q_AUTOTEST_EXPORT QFSFileEnginePrivate : public QAbstractFileEnginePrivate
diff --git a/src/corelib/io/qipaddress.cpp b/src/corelib/io/qipaddress.cpp
index b3421fca8f..ddc5b6607f 100644
--- a/src/corelib/io/qipaddress.cpp
+++ b/src/corelib/io/qipaddress.cpp
@@ -312,7 +312,7 @@ void toString(QString &appendTo, const IPv6Address address)
}
}
- const QChar colon = ushort(':');
+ const QChar colon = u':';
if (zeroRunLength < 4)
zeroRunOffset = -1;
else if (zeroRunOffset == 0)
diff --git a/src/corelib/io/qprocess.cpp b/src/corelib/io/qprocess.cpp
index 0b964e6a21..35ca2542f7 100644
--- a/src/corelib/io/qprocess.cpp
+++ b/src/corelib/io/qprocess.cpp
@@ -202,6 +202,7 @@ void QProcessEnvironmentPrivate::insert(const QProcessEnvironmentPrivate &other)
vars.insert(it.key(), it.value());
#ifdef Q_OS_UNIX
+ const OrderedNameMapMutexLocker locker(this, &other);
auto nit = other.nameMap.constBegin();
const auto nend = other.nameMap.constEnd();
for ( ; nit != nend; ++nit)
@@ -275,7 +276,6 @@ bool QProcessEnvironment::operator==(const QProcessEnvironment &other) const
return true;
if (d) {
if (other.d) {
- QProcessEnvironmentPrivate::OrderedMutexLocker locker(d, other.d);
return d->vars == other.d->vars;
} else {
return isEmpty();
@@ -322,7 +322,6 @@ bool QProcessEnvironment::contains(const QString &name) const
{
if (!d)
return false;
- QProcessEnvironmentPrivate::MutexLocker locker(d);
return d->vars.contains(d->prepareName(name));
}
@@ -373,7 +372,6 @@ QString QProcessEnvironment::value(const QString &name, const QString &defaultVa
if (!d)
return defaultValue;
- QProcessEnvironmentPrivate::MutexLocker locker(d);
const auto it = d->vars.constFind(d->prepareName(name));
if (it == d->vars.constEnd())
return defaultValue;
@@ -398,7 +396,6 @@ QStringList QProcessEnvironment::toStringList() const
{
if (!d)
return QStringList();
- QProcessEnvironmentPrivate::MutexLocker locker(d);
return d->toList();
}
@@ -412,7 +409,6 @@ QStringList QProcessEnvironment::keys() const
{
if (!d)
return QStringList();
- QProcessEnvironmentPrivate::MutexLocker locker(d);
return d->keys();
}
@@ -429,7 +425,6 @@ void QProcessEnvironment::insert(const QProcessEnvironment &e)
return;
// our re-impl of detach() detaches from null
- QProcessEnvironmentPrivate::MutexLocker locker(e.d);
d->insert(*e.d);
}
diff --git a/src/corelib/io/qprocess_p.h b/src/corelib/io/qprocess_p.h
index d02e87837c..2587530c09 100644
--- a/src/corelib/io/qprocess_p.h
+++ b/src/corelib/io/qprocess_p.h
@@ -146,16 +146,22 @@ public:
inline QString nameToString(const Key &name) const { return name; }
inline Value prepareValue(const QString &value) const { return value; }
inline QString valueToString(const Value &value) const { return value; }
- struct MutexLocker {
- MutexLocker(const QProcessEnvironmentPrivate *) {}
+#else
+ struct NameMapMutexLocker : public QMutexLocker
+ {
+ NameMapMutexLocker(const QProcessEnvironmentPrivate *d) : QMutexLocker(&d->nameMapMutex) {}
};
- struct OrderedMutexLocker {
- OrderedMutexLocker(const QProcessEnvironmentPrivate *,
- const QProcessEnvironmentPrivate *) {}
+ struct OrderedNameMapMutexLocker : public QOrderedMutexLocker
+ {
+ OrderedNameMapMutexLocker(const QProcessEnvironmentPrivate *d1,
+ const QProcessEnvironmentPrivate *d2)
+ : QOrderedMutexLocker(&d1->nameMapMutex, &d2->nameMapMutex)
+ {}
};
-#else
+
inline Key prepareName(const QString &name) const
{
+ const NameMapMutexLocker locker(this);
Key &ent = nameMap[name];
if (ent.isEmpty())
ent = name.toLocal8Bit();
@@ -164,40 +170,27 @@ public:
inline QString nameToString(const Key &name) const
{
const QString sname = QString::fromLocal8Bit(name);
- nameMap[sname] = name;
+ {
+ const NameMapMutexLocker locker(this);
+ nameMap[sname] = name;
+ }
return sname;
}
inline Value prepareValue(const QString &value) const { return Value(value); }
inline QString valueToString(const Value &value) const { return value.string(); }
- struct MutexLocker : public QMutexLocker
- {
- MutexLocker(const QProcessEnvironmentPrivate *d) : QMutexLocker(&d->mutex) {}
- };
- struct OrderedMutexLocker : public QOrderedMutexLocker
- {
- OrderedMutexLocker(const QProcessEnvironmentPrivate *d1,
- const QProcessEnvironmentPrivate *d2) :
- QOrderedMutexLocker(&d1->mutex, &d2->mutex)
- {}
- };
-
QProcessEnvironmentPrivate() : QSharedData() {}
QProcessEnvironmentPrivate(const QProcessEnvironmentPrivate &other) :
- QSharedData()
+ QSharedData(), vars(other.vars)
{
- // This being locked ensures that the functions that only assign
- // d pointers don't need explicit locking.
// We don't need to lock our own mutex, as this object is new and
// consequently not shared. For the same reason, non-const methods
// do not need a lock, as they detach objects (however, we need to
// ensure that they really detach before using prepareName()).
- MutexLocker locker(&other);
- vars = other.vars;
+ NameMapMutexLocker locker(&other);
nameMap = other.nameMap;
- // We need to detach our members, so that our mutex can protect them.
- // As we are being detached, they likely would be detached a moment later anyway.
- vars.detach();
+ // We need to detach our nameMap, so that our mutex can protect it.
+ // As we are being detached, it likely would be detached a moment later anyway.
nameMap.detach();
}
#endif
@@ -208,8 +201,7 @@ public:
#ifdef Q_OS_UNIX
typedef QHash<QString, Key> NameHash;
mutable NameHash nameMap;
-
- mutable QMutex mutex;
+ mutable QMutex nameMapMutex;
#endif
static QProcessEnvironment fromList(const QStringList &list);
diff --git a/src/corelib/io/qprocess_unix.cpp b/src/corelib/io/qprocess_unix.cpp
index 1d5b76a8a4..951fc4ccaa 100644
--- a/src/corelib/io/qprocess_unix.cpp
+++ b/src/corelib/io/qprocess_unix.cpp
@@ -438,7 +438,6 @@ void QProcessPrivate::startProcess()
int envc = 0;
char **envp = 0;
if (environment.d.constData()) {
- QProcessEnvironmentPrivate::MutexLocker locker(environment.d);
envp = _q_dupEnvironment(environment.d.constData()->vars, &envc);
}
@@ -970,7 +969,6 @@ bool QProcessPrivate::startDetached(qint64 *pid)
int envc = 0;
char **envp = nullptr;
if (environment.d.constData()) {
- QProcessEnvironmentPrivate::MutexLocker locker(environment.d);
envp = _q_dupEnvironment(environment.d.constData()->vars, &envc);
}
diff --git a/src/corelib/io/qresource.cpp b/src/corelib/io/qresource.cpp
index fcc5b69179..52b746d04a 100644
--- a/src/corelib/io/qresource.cpp
+++ b/src/corelib/io/qresource.cpp
@@ -1,7 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2018 The Qt Company Ltd.
-** Copyright (C) 2018 Intel Corporation.
+** Copyright (C) 2019 Intel Corporation.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtCore module of the Qt Toolkit.
@@ -279,14 +279,14 @@ static inline QStringList *resourceSearchPaths()
This enum is used by compressionAlgorithm() to indicate which algorithm the
RCC tool used to compress the payload.
- \value NoCompression Contents are not compressed (isCompressed() is false).
+ \value NoCompression Contents are not compressed
\value ZlibCompression Contents are compressed using \l{zlib}{https://zlib.net} and can
be decompressed using the qUncompress() function.
\value ZstdCompression Contents are compressed using \l{zstd}{https://zstd.net}. To
decompress, use the \c{ZSTD_decompress} function from the zstd
library.
- \sa compressionAlgorithm(), isCompressed()
+ \sa compressionAlgorithm()
*/
class QResourcePrivate {
@@ -551,13 +551,20 @@ bool QResource::isValid() const
\sa isDir()
*/
-
+#if QT_DEPRECATED_SINCE(5, 13)
/*!
+ \obsolete
+
Returns \c true if the resource represents a file and the data backing it
is in a compressed format, false otherwise. If the data is compressed,
check compressionAlgorithm() to verify what algorithm to use to decompress
the data.
+ \note This function is deprecated and can be replaced with
+ \code
+ compressionAlgorithm() != NoCompression
+ \endcode
+
\sa data(), compressionAlgorithm(), isFile()
*/
@@ -565,6 +572,7 @@ bool QResource::isCompressed() const
{
return compressionAlgorithm() != NoCompression;
}
+#endif
/*!
\since 5.13
@@ -582,7 +590,7 @@ bool QResource::isCompressed() const
See \l{http://facebook.github.io/zstd/zstd_manual.html}{Zstandard manual}.
- \sa isCompressed(), data(), isFile()
+ \sa data(), isFile()
*/
QResource::Compression QResource::compressionAlgorithm() const
{
@@ -606,11 +614,11 @@ qint64 QResource::size() const
/*!
Returns direct access to a read only segment of data that this resource
- represents. If the resource is compressed the data returns is
- compressed and qUncompress() must be used to access the data. If the
- resource is a directory \nullptr is returned.
+ represents. If the resource is compressed the data returned is compressed
+ and the appropriate library functions must be used to access the data. If
+ the resource is a directory \nullptr is returned.
- \sa size(), isCompressed(), isFile()
+ \sa size(), compressionAlgorithm(), isFile()
*/
const uchar *QResource::data() const
@@ -940,12 +948,15 @@ bool QResourceRoot::mappingRootSubdir(const QString &path, QString *match) const
Q_CORE_EXPORT bool qRegisterResourceData(int version, const unsigned char *tree,
const unsigned char *name, const unsigned char *data)
{
+ if (resourceGlobalData.isDestroyed())
+ return false;
QMutexLocker lock(resourceMutex());
- if (version >= 0x01 && version <= 0x3 && resourceList()) {
+ ResourceList *list = resourceList();
+ if (version >= 0x01 && version <= 0x3) {
bool found = false;
QResourceRoot res(version, tree, name, data);
- for(int i = 0; i < resourceList()->size(); ++i) {
- if(*resourceList()->at(i) == res) {
+ for (int i = 0; i < list->size(); ++i) {
+ if (*list->at(i) == res) {
found = true;
break;
}
@@ -953,7 +964,7 @@ Q_CORE_EXPORT bool qRegisterResourceData(int version, const unsigned char *tree,
if(!found) {
QResourceRoot *root = new QResourceRoot(version, tree, name, data);
root->ref.ref();
- resourceList()->append(root);
+ list->append(root);
}
return true;
}
@@ -967,11 +978,12 @@ Q_CORE_EXPORT bool qUnregisterResourceData(int version, const unsigned char *tre
return false;
QMutexLocker lock(resourceMutex());
- if (version >= 0x01 && version <= 0x3 && resourceList()) {
+ if (version >= 0x01 && version <= 0x3) {
QResourceRoot res(version, tree, name, data);
- for(int i = 0; i < resourceList()->size(); ) {
- if(*resourceList()->at(i) == res) {
- QResourceRoot *root = resourceList()->takeAt(i);
+ ResourceList *list = resourceList();
+ for (int i = 0; i < list->size(); ) {
+ if (*list->at(i) == res) {
+ QResourceRoot *root = list->takeAt(i);
if(!root->ref.deref())
delete root;
} else {
@@ -1217,7 +1229,7 @@ QResource::unregisterResource(const QString &rccFilename, const QString &resourc
if(res->type() == QResourceRoot::Resource_File) {
QDynamicFileResourceRoot *root = reinterpret_cast<QDynamicFileResourceRoot*>(res);
if (root->mappingFile() == rccFilename && root->mappingRoot() == r) {
- resourceList()->removeAt(i);
+ list->removeAt(i);
if(!root->ref.deref()) {
delete root;
return true;
@@ -1288,7 +1300,7 @@ QResource::unregisterResource(const uchar *rccData, const QString &resourceRoot)
if(res->type() == QResourceRoot::Resource_Buffer) {
QDynamicBufferResourceRoot *root = reinterpret_cast<QDynamicBufferResourceRoot*>(res);
if (root->mappingBuffer() == rccData && root->mappingRoot() == r) {
- resourceList()->removeAt(i);
+ list->removeAt(i);
if(!root->ref.deref()) {
delete root;
return true;
@@ -1366,9 +1378,15 @@ bool QResourceFileEngine::open(QIODevice::OpenMode flags)
qWarning("QResourceFileEngine::open: Missing file name");
return false;
}
- if(flags & QIODevice::WriteOnly)
+ if (flags & QIODevice::WriteOnly)
return false;
- d->uncompress();
+ if (d->resource.compressionAlgorithm() != QResource::NoCompression) {
+ d->uncompress();
+ if (d->uncompressed.isNull()) {
+ d->errorString = QSystemError::stdString(EIO);
+ return false;
+ }
+ }
if (!d->resource.isValid()) {
d->errorString = QSystemError::stdString(ENOENT);
return false;
@@ -1395,7 +1413,7 @@ qint64 QResourceFileEngine::read(char *data, qint64 len)
len = size()-d->offset;
if(len <= 0)
return 0;
- if(d->resource.isCompressed())
+ if (!d->uncompressed.isNull())
memcpy(data, d->uncompressed.constData()+d->offset, len);
else
memcpy(data, d->resource.data()+d->offset, len);
@@ -1431,9 +1449,9 @@ bool QResourceFileEngine::link(const QString &)
qint64 QResourceFileEngine::size() const
{
Q_D(const QResourceFileEngine);
- if(!d->resource.isValid())
+ if (!d->resource.isValid())
return 0;
- if (d->resource.isCompressed()) {
+ if (d->resource.compressionAlgorithm() != QResource::NoCompression) {
d->uncompress();
return d->uncompressed.size();
}
@@ -1596,7 +1614,7 @@ uchar *QResourceFileEnginePrivate::map(qint64 offset, qint64 size, QFile::Memory
Q_UNUSED(flags);
qint64 max = resource.size();
- if (resource.isCompressed()) {
+ if (resource.compressionAlgorithm() != QResource::NoCompression) {
uncompress();
max = uncompressed.size();
}
@@ -1609,7 +1627,7 @@ uchar *QResourceFileEnginePrivate::map(qint64 offset, qint64 size, QFile::Memory
}
const uchar *address = resource.data();
- if (resource.isCompressed())
+ if (resource.compressionAlgorithm() != QResource::NoCompression)
address = reinterpret_cast<const uchar *>(uncompressed.constData());
return const_cast<uchar *>(address) + offset;
diff --git a/src/corelib/io/qresource.h b/src/corelib/io/qresource.h
index 5e798de436..5ee8d5d266 100644
--- a/src/corelib/io/qresource.h
+++ b/src/corelib/io/qresource.h
@@ -72,7 +72,6 @@ public:
bool isValid() const;
- bool isCompressed() const;
Compression compressionAlgorithm() const;
qint64 size() const;
const uchar *data() const;
@@ -84,6 +83,10 @@ public:
QT_DEPRECATED_X("Use QDir::searchPaths() instead")
static QStringList searchPaths();
#endif
+#if QT_DEPRECATED_SINCE(5, 15)
+ QT_DEPRECATED_VERSION_X_5_15("Use QResource::compressionAlgorithm() instead")
+ bool isCompressed() const;
+#endif
static bool registerResource(const QString &rccFilename, const QString &resourceRoot=QString());
static bool unregisterResource(const QString &rccFilename, const QString &resourceRoot=QString());
diff --git a/src/corelib/io/qsavefile.cpp b/src/corelib/io/qsavefile.cpp
index 915d0a0a00..f41e6302a2 100644
--- a/src/corelib/io/qsavefile.cpp
+++ b/src/corelib/io/qsavefile.cpp
@@ -150,8 +150,7 @@ QSaveFile::~QSaveFile()
QFileDevice::close();
if (d->fileEngine) {
d->fileEngine->remove();
- delete d->fileEngine;
- d->fileEngine = nullptr;
+ d->fileEngine.reset();
}
}
@@ -197,6 +196,7 @@ bool QSaveFile::open(OpenMode mode)
return false;
}
unsetError();
+ d->writeError = QFileDevice::NoError;
if ((mode & (ReadOnly | WriteOnly)) == 0) {
qWarning("QSaveFile::open: Open mode not specified");
return false;
@@ -234,7 +234,7 @@ bool QSaveFile::open(OpenMode mode)
}
auto openDirectly = [&]() {
- d->fileEngine = QAbstractFileEngine::create(d->finalFileName);
+ d->fileEngine.reset(QAbstractFileEngine::create(d->finalFileName));
if (d->fileEngine->open(mode | QIODevice::Unbuffered)) {
d->useTemporaryFile = false;
QFileDevice::open(mode);
@@ -251,8 +251,7 @@ bool QSaveFile::open(OpenMode mode)
if (openDirectly())
return true;
d->setError(d->fileEngine->error(), d->fileEngine->errorString());
- delete d->fileEngine;
- d->fileEngine = nullptr;
+ d->fileEngine.reset();
} else {
QString msg =
QSaveFile::tr("QSaveFile cannot open '%1' without direct write fallback "
@@ -264,18 +263,17 @@ bool QSaveFile::open(OpenMode mode)
}
#endif
- d->fileEngine = new QTemporaryFileEngine(&d->finalFileName, QTemporaryFileEngine::Win32NonShared);
+ d->fileEngine.reset(new QTemporaryFileEngine(&d->finalFileName, QTemporaryFileEngine::Win32NonShared));
// if the target file exists, we'll copy its permissions below,
// but until then, let's ensure the temporary file is not accessible
// to a third party
int perm = (existingFile.exists() ? 0600 : 0666);
- static_cast<QTemporaryFileEngine *>(d->fileEngine)->initialize(d->finalFileName, perm);
+ static_cast<QTemporaryFileEngine *>(d->fileEngine.get())->initialize(d->finalFileName, perm);
// Same as in QFile: QIODevice provides the buffering, so there's no need to request it from the file engine.
if (!d->fileEngine->open(mode | QIODevice::Unbuffered)) {
QFileDevice::FileError err = d->fileEngine->error();
#ifdef Q_OS_UNIX
if (d->directWriteFallback && err == QFileDevice::OpenError && errno == EACCES) {
- delete d->fileEngine;
if (openDirectly())
return true;
err = d->fileEngine->error();
@@ -284,8 +282,7 @@ bool QSaveFile::open(OpenMode mode)
if (err == QFileDevice::UnspecifiedError)
err = QFileDevice::OpenError;
d->setError(err, d->fileEngine->errorString());
- delete d->fileEngine;
- d->fileEngine = nullptr;
+ d->fileEngine.reset();
return false;
}
@@ -331,30 +328,26 @@ bool QSaveFile::commit()
}
QFileDevice::close(); // calls flush()
+ const auto fe = std::move(d->fileEngine);
+
// Sync to disk if possible. Ignore errors (e.g. not supported).
- d->fileEngine->syncToDisk();
+ fe->syncToDisk();
if (d->useTemporaryFile) {
if (d->writeError != QFileDevice::NoError) {
- d->fileEngine->remove();
+ fe->remove();
d->writeError = QFileDevice::NoError;
- delete d->fileEngine;
- d->fileEngine = nullptr;
return false;
}
// atomically replace old file with new file
// Can't use QFile::rename for that, must use the file engine directly
- Q_ASSERT(d->fileEngine);
- if (!d->fileEngine->renameOverwrite(d->finalFileName)) {
- d->setError(d->fileEngine->error(), d->fileEngine->errorString());
- d->fileEngine->remove();
- delete d->fileEngine;
- d->fileEngine = nullptr;
+ Q_ASSERT(fe);
+ if (!fe->renameOverwrite(d->finalFileName)) {
+ d->setError(fe->error(), fe->errorString());
+ fe->remove();
return false;
}
}
- delete d->fileEngine;
- d->fileEngine = nullptr;
return true;
}
diff --git a/src/corelib/io/qstandardpaths.cpp b/src/corelib/io/qstandardpaths.cpp
index dbf650d5f6..f56fef7f8e 100644
--- a/src/corelib/io/qstandardpaths.cpp
+++ b/src/corelib/io/qstandardpaths.cpp
@@ -297,7 +297,7 @@ QT_BEGIN_NAMESPACE
\li "<APPROOT>/tmp"
\row \li HomeLocation
\li "<APPROOT>/files"
- \li "<APPROOT>" (not writable)
+ \li system defined
\row \li DataLocation
\li "<APPROOT>/files", "<USER>/<APPNAME>/files"
\li "<APPROOT>/Library/Application Support"
diff --git a/src/corelib/io/qstandardpaths_unix.cpp b/src/corelib/io/qstandardpaths_unix.cpp
index f4f8787968..6425890e3f 100644
--- a/src/corelib/io/qstandardpaths_unix.cpp
+++ b/src/corelib/io/qstandardpaths_unix.cpp
@@ -71,6 +71,28 @@ static void appendOrganizationAndApp(QString &path)
#endif
}
+#if QT_CONFIG(regularexpression)
+static QLatin1String xdg_key_name(QStandardPaths::StandardLocation type)
+{
+ switch (type) {
+ case QStandardPaths::DesktopLocation:
+ return QLatin1String("DESKTOP");
+ case QStandardPaths::DocumentsLocation:
+ return QLatin1String("DOCUMENTS");
+ case QStandardPaths::PicturesLocation:
+ return QLatin1String("PICTURES");
+ case QStandardPaths::MusicLocation:
+ return QLatin1String("MUSIC");
+ case QStandardPaths::MoviesLocation:
+ return QLatin1String("VIDEOS");
+ case QStandardPaths::DownloadLocation:
+ return QLatin1String("DOWNLOAD");
+ default:
+ return QLatin1String();
+ }
+}
+#endif
+
QString QStandardPaths::writableLocation(StandardLocation type)
{
switch (type) {
@@ -182,61 +204,32 @@ QString QStandardPaths::writableLocation(StandardLocation type)
if (xdgConfigHome.isEmpty())
xdgConfigHome = QDir::homePath() + QLatin1String("/.config");
QFile file(xdgConfigHome + QLatin1String("/user-dirs.dirs"));
- if (!isTestModeEnabled() && file.open(QIODevice::ReadOnly)) {
- QHash<QString, QString> lines;
+ const QLatin1String key = xdg_key_name(type);
+ if (!key.isEmpty() && !isTestModeEnabled() && file.open(QIODevice::ReadOnly)) {
QTextStream stream(&file);
// Only look for lines like: XDG_DESKTOP_DIR="$HOME/Desktop"
QRegularExpression exp(QLatin1String("^XDG_(.*)_DIR=(.*)$"));
+ QString result;
while (!stream.atEnd()) {
const QString &line = stream.readLine();
QRegularExpressionMatch match = exp.match(line);
- if (match.hasMatch()) {
- const QStringList lst = match.capturedTexts();
- const QString key = lst.at(1);
- QString value = lst.at(2);
+ if (match.hasMatch() && match.capturedView(1) == key) {
+ QStringView value = match.capturedView(2);
if (value.length() > 2
&& value.startsWith(QLatin1Char('\"'))
&& value.endsWith(QLatin1Char('\"')))
value = value.mid(1, value.length() - 2);
- // Store the key and value: "DESKTOP", "$HOME/Desktop"
- lines[key] = value;
- }
- }
-
- QString key;
- switch (type) {
- case DesktopLocation:
- key = QLatin1String("DESKTOP");
- break;
- case DocumentsLocation:
- key = QLatin1String("DOCUMENTS");
- break;
- case PicturesLocation:
- key = QLatin1String("PICTURES");
- break;
- case MusicLocation:
- key = QLatin1String("MUSIC");
- break;
- case MoviesLocation:
- key = QLatin1String("VIDEOS");
- break;
- case DownloadLocation:
- key = QLatin1String("DOWNLOAD");
- break;
- default:
- break;
- }
- if (!key.isEmpty()) {
- QString value = lines.value(key);
- if (!value.isEmpty()) {
// value can start with $HOME
if (value.startsWith(QLatin1String("$HOME")))
- value = QDir::homePath() + value.midRef(5);
- if (value.length() > 1 && value.endsWith(QLatin1Char('/')))
- value.chop(1);
- return value;
+ result = QDir::homePath() + value.mid(5);
+ else
+ result = value.toString();
+ if (result.length() > 1 && result.endsWith(QLatin1Char('/')))
+ result.chop(1);
}
}
+ if (!result.isNull())
+ return result;
}
#endif // QT_CONFIG(regularexpression)
diff --git a/src/corelib/io/qstorageinfo_unix.cpp b/src/corelib/io/qstorageinfo_unix.cpp
index 4669c20711..1e72241e68 100644
--- a/src/corelib/io/qstorageinfo_unix.cpp
+++ b/src/corelib/io/qstorageinfo_unix.cpp
@@ -468,8 +468,18 @@ inline bool QStorageIterator::next()
size_t len = strlen(buffer.data());
if (len == 0)
return false;
- if (ptr[len - 1] == '\n')
- ptr[len - 1] = '\0';
+ while (Q_UNLIKELY(ptr[len - 1] != '\n' && !feof(fp))) {
+ // buffer wasn't large enough. Enlarge and try again.
+ // (we're readidng from the kernel, so OOM is unlikely)
+ buffer.resize((buffer.size() + 4096) & ~4095);
+ ptr = buffer.data();
+ if (fgets(ptr + len, buffer.size() - len, fp) == nullptr)
+ return false;
+
+ len += strlen(ptr + len);
+ Q_ASSERT(len < size_t(buffer.size()));
+ }
+ ptr[len - 1] = '\0';
// parse the line
bool ok;
diff --git a/src/corelib/io/qtemporaryfile.cpp b/src/corelib/io/qtemporaryfile.cpp
index c89ad06a1f..acd31f4d84 100644
--- a/src/corelib/io/qtemporaryfile.cpp
+++ b/src/corelib/io/qtemporaryfile.cpp
@@ -544,10 +544,10 @@ QTemporaryFilePrivate::~QTemporaryFilePrivate()
QAbstractFileEngine *QTemporaryFilePrivate::engine() const
{
if (!fileEngine) {
- fileEngine = new QTemporaryFileEngine(&templateName);
+ fileEngine.reset(new QTemporaryFileEngine(&templateName));
resetFileEngine();
}
- return fileEngine;
+ return fileEngine.get();
}
void QTemporaryFilePrivate::resetFileEngine() const
@@ -555,7 +555,7 @@ void QTemporaryFilePrivate::resetFileEngine() const
if (!fileEngine)
return;
- QTemporaryFileEngine *tef = static_cast<QTemporaryFileEngine *>(fileEngine);
+ QTemporaryFileEngine *tef = static_cast<QTemporaryFileEngine *>(fileEngine.get());
if (fileName.isEmpty())
tef->initialize(templateName, 0600);
else
@@ -568,7 +568,7 @@ void QTemporaryFilePrivate::materializeUnnamedFile()
if (!fileName.isEmpty() || !fileEngine)
return;
- auto *tef = static_cast<QTemporaryFileEngine *>(fileEngine);
+ auto *tef = static_cast<QTemporaryFileEngine *>(fileEngine.get());
fileName = tef->fileName(QAbstractFileEngine::DefaultName);
#endif
}
@@ -792,7 +792,7 @@ void QTemporaryFile::setAutoRemove(bool b)
QString QTemporaryFile::fileName() const
{
Q_D(const QTemporaryFile);
- auto tef = static_cast<QTemporaryFileEngine *>(d->fileEngine);
+ auto tef = static_cast<QTemporaryFileEngine *>(d->fileEngine.get());
if (tef && tef->isReallyOpen())
const_cast<QTemporaryFilePrivate *>(d)->materializeUnnamedFile();
@@ -841,7 +841,7 @@ void QTemporaryFile::setFileTemplate(const QString &name)
bool QTemporaryFile::rename(const QString &newName)
{
Q_D(QTemporaryFile);
- auto tef = static_cast<QTemporaryFileEngine *>(d->fileEngine);
+ auto tef = static_cast<QTemporaryFileEngine *>(d->fileEngine.get());
if (!tef || !tef->isReallyOpen() || !tef->filePathWasTemplate)
return QFile::rename(newName);
@@ -947,7 +947,7 @@ QTemporaryFile *QTemporaryFile::createNativeFile(QFile &file)
bool QTemporaryFile::open(OpenMode flags)
{
Q_D(QTemporaryFile);
- auto tef = static_cast<QTemporaryFileEngine *>(d->fileEngine);
+ auto tef = static_cast<QTemporaryFileEngine *>(d->fileEngine.get());
if (tef && tef->isReallyOpen()) {
setOpenMode(flags);
return true;
@@ -961,7 +961,7 @@ bool QTemporaryFile::open(OpenMode flags)
d->resetFileEngine();
if (QFile::open(flags)) {
- tef = static_cast<QTemporaryFileEngine *>(d->fileEngine);
+ tef = static_cast<QTemporaryFileEngine *>(d->fileEngine.get());
if (tef->isUnnamedFile())
d->fileName.clear();
else
diff --git a/src/corelib/io/qtldurl.cpp b/src/corelib/io/qtldurl.cpp
index a934d19fa2..912609ec91 100644
--- a/src/corelib/io/qtldurl.cpp
+++ b/src/corelib/io/qtldurl.cpp
@@ -59,9 +59,9 @@ enum TLDMatchType {
static bool containsTLDEntry(QStringView entry, TLDMatchType match)
{
const QStringView matchSymbols[] = {
- QStringViewLiteral(""),
- QStringViewLiteral("*"),
- QStringViewLiteral("!"),
+ u"",
+ u"*",
+ u"!",
};
const auto symbol = matchSymbols[match];
int index = qt_hash(entry, qt_hash(symbol)) % tldCount;
diff --git a/src/corelib/io/qurl.cpp b/src/corelib/io/qurl.cpp
index d9ebc6c750..878e007fb0 100644
--- a/src/corelib/io/qurl.cpp
+++ b/src/corelib/io/qurl.cpp
@@ -1010,7 +1010,7 @@ inline bool QUrlPrivate::setScheme(const QString &value, int len, bool doSetErro
for (int i = needsLowercasing; i >= 0; --i) {
ushort c = schemeData[i].unicode();
if (c >= 'A' && c <= 'Z')
- schemeData[i] = c + 0x20;
+ schemeData[i] = QChar(c + 0x20);
}
}
diff --git a/src/corelib/io/qurlidna.cpp b/src/corelib/io/qurlidna.cpp
index 2f89d22660..a2f0caa606 100644
--- a/src/corelib/io/qurlidna.cpp
+++ b/src/corelib/io/qurlidna.cpp
@@ -2220,9 +2220,8 @@ Q_AUTOTEST_EXPORT void qt_punycodeEncoder(const QChar *s, int ucLength, QString
bool skipped = false;
// copy all basic code points verbatim to output.
for (uint j = 0; j < (uint) ucLength; ++j) {
- ushort js = s[j].unicode();
- if (js < 0x80)
- *d++ = js;
+ if (s[j].unicode() < 0x80)
+ *d++ = s[j];
else
skipped = true;
}
diff --git a/src/corelib/io/qurlquery.cpp b/src/corelib/io/qurlquery.cpp
index 36a2880bf1..8d80a2d8bd 100644
--- a/src/corelib/io/qurlquery.cpp
+++ b/src/corelib/io/qurlquery.cpp
@@ -146,7 +146,7 @@ QT_BEGIN_NAMESPACE
*/
/*!
- \fn QUrlQuery(std::initializer_list<QPair<QString, QString>> list)
+ \fn QUrlQuery::QUrlQuery(std::initializer_list<QPair<QString, QString>> list)
\since 5.13
@@ -293,9 +293,9 @@ void QUrlQueryPrivate::setQuery(const QString &query)
const QChar *delimiter = nullptr;
while (pos != end) {
// scan for the component parts of this pair
- if (!delimiter && pos->unicode() == valueDelimiter)
+ if (!delimiter && *pos == valueDelimiter)
delimiter = pos;
- if (pos->unicode() == pairDelimiter)
+ if (*pos == pairDelimiter)
break;
++pos;
}
@@ -584,8 +584,8 @@ QString QUrlQuery::query(QUrl::ComponentFormattingOptions encoding) const
*/
void QUrlQuery::setQueryDelimiters(QChar valueDelimiter, QChar pairDelimiter)
{
- d->valueDelimiter = valueDelimiter.unicode();
- d->pairDelimiter = pairDelimiter.unicode();
+ d->valueDelimiter = valueDelimiter;
+ d->pairDelimiter = pairDelimiter;
}
/*!