summaryrefslogtreecommitdiffstats
path: root/src/corelib/io
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/io')
-rw-r--r--src/corelib/io/qdebug.cpp16
-rw-r--r--src/corelib/io/qdebug.h13
-rw-r--r--src/corelib/io/qdebug_p.h2
-rw-r--r--src/corelib/io/qdir.cpp28
-rw-r--r--src/corelib/io/qdir.h2
-rw-r--r--src/corelib/io/qfilesystemengine_unix.cpp12
-rw-r--r--src/corelib/io/qfilesystemwatcher_fsevents.mm2
-rw-r--r--src/corelib/io/qfilesystemwatcher_win.cpp4
-rw-r--r--src/corelib/io/qfsfileengine_unix.cpp38
-rw-r--r--src/corelib/io/qfsfileengine_win.cpp24
-rw-r--r--src/corelib/io/qiodevice.cpp5
-rw-r--r--src/corelib/io/qloggingregistry.cpp14
-rw-r--r--src/corelib/io/qprocess_unix.cpp1
-rw-r--r--src/corelib/io/qprocess_win.cpp21
-rw-r--r--src/corelib/io/qresource.cpp10
-rw-r--r--src/corelib/io/qsettings.cpp6
-rw-r--r--src/corelib/io/qsettings_mac.cpp18
-rw-r--r--src/corelib/io/qsettings_win.cpp18
-rw-r--r--src/corelib/io/qsettings_winrt.cpp18
-rw-r--r--src/corelib/io/qurl.cpp66
-rw-r--r--src/corelib/io/qurlrecode.cpp142
21 files changed, 303 insertions, 157 deletions
diff --git a/src/corelib/io/qdebug.cpp b/src/corelib/io/qdebug.cpp
index 013d531581..2e825d2373 100644
--- a/src/corelib/io/qdebug.cpp
+++ b/src/corelib/io/qdebug.cpp
@@ -939,14 +939,18 @@ void qt_QMetaEnum_flagDebugOperator(QDebug &debug, size_t sizeofT, int value)
QDebug qt_QMetaEnum_debugOperator(QDebug &dbg, int value, const QMetaObject *meta, const char *name)
{
QDebugStateSaver saver(dbg);
+ dbg.nospace();
QMetaEnum me = meta->enumerator(meta->indexOfEnumerator(name));
const char *key = me.valueToKey(value);
- dbg.nospace() << meta->className() << "::" << name << '(';
- if (key)
+ if (key) {
+ if (const char *scope = me.scope())
+ dbg << scope << "::";
+ if (me.isScoped())
+ dbg << me.enumName() << "::";
dbg << key;
- else
- dbg << value;
- dbg << ')';
+ } else {
+ dbg << meta->className() << "::" << name << "(" << value << ")";
+ }
return dbg;
}
@@ -960,7 +964,7 @@ QDebug qt_QMetaEnum_flagDebugOperator(QDebug &debug, quint64 value, const QMetaO
const QMetaEnum me = meta->enumerator(meta->indexOfEnumerator(name));
if (const char *scope = me.scope())
debug << scope << "::";
- debug << me.name() << ">(" << me.valueToKeys(value) << ')';
+ debug << me.enumName() << ">(" << me.valueToKeys(value) << ')';
return debug;
}
#endif // !QT_NO_QOBJECT
diff --git a/src/corelib/io/qdebug.h b/src/corelib/io/qdebug.h
index ee8ef679a9..ae1869f89e 100644
--- a/src/corelib/io/qdebug.h
+++ b/src/corelib/io/qdebug.h
@@ -376,6 +376,19 @@ operator<<(QDebug dbg, T value)
return qt_QMetaEnum_debugOperator(dbg, typename QFlags<T>::Int(value), obj, name);
}
+template<typename T,
+ typename A = typename std::enable_if<std::is_enum<T>::value, void>::type,
+ typename B = typename std::enable_if<sizeof(T) <= sizeof(int), void>::type,
+ typename C = typename std::enable_if<!QtPrivate::IsQEnumHelper<T>::Value, void>::type,
+ typename D = typename std::enable_if<QtPrivate::IsQEnumHelper<QFlags<T>>::Value, void>::type>
+inline QDebug operator<<(QDebug dbg, T value)
+{
+ typedef QFlags<T> FlagsT;
+ const QMetaObject *obj = qt_getEnumMetaObject(FlagsT());
+ const char *name = qt_getEnumName(FlagsT());
+ return qt_QMetaEnum_debugOperator(dbg, typename FlagsT::Int(value), obj, name);
+}
+
template <class T>
inline typename std::enable_if<
QtPrivate::IsQEnumHelper<T>::Value || QtPrivate::IsQEnumHelper<QFlags<T> >::Value,
diff --git a/src/corelib/io/qdebug_p.h b/src/corelib/io/qdebug_p.h
index a1887655d2..dcb906d156 100644
--- a/src/corelib/io/qdebug_p.h
+++ b/src/corelib/io/qdebug_p.h
@@ -93,7 +93,7 @@ static inline void formatQEnum(QDebug &debug, QEnum value)
{
const QMetaObject *metaObject = qt_getEnumMetaObject(value);
const QMetaEnum me = metaObject->enumerator(metaObject->indexOfEnumerator(qt_getEnumName(value)));
- if (const char *key = me.valueToKey(value))
+ if (const char *key = me.valueToKey(int(value)))
debug << key;
else
debug << int(value);
diff --git a/src/corelib/io/qdir.cpp b/src/corelib/io/qdir.cpp
index 10aee73a2f..39422c3401 100644
--- a/src/corelib/io/qdir.cpp
+++ b/src/corelib/io/qdir.cpp
@@ -48,7 +48,9 @@
#include "qdiriterator.h"
#include "qdatetime.h"
#include "qstring.h"
-#include "qregexp.h"
+#if QT_CONFIG(regularexpression)
+# include <qregularexpression.h>
+#endif
#include "qvector.h"
#include "qvarlengtharray.h"
#include "qfilesystementry_p.h"
@@ -1038,7 +1040,7 @@ QStringList QDir::nameFilters() const
list of filters specified by \a nameFilters.
Each name filter is a wildcard (globbing) filter that understands
- \c{*} and \c{?} wildcards. (See \l{QRegExp wildcard matching}.)
+ \c{*} and \c{?} wildcards. (See \l{QRegularExpression wildcard matching}.)
For example, the following code sets three name filters on a QDir
to ensure that only files with extensions typically used for C++
@@ -2059,7 +2061,7 @@ QString QDir::homePath()
Returns the system's temporary directory.
- The directory is constructed using the absolute path of the temporary directory,
+ The directory is constructed using the absolute canonical path of the temporary directory,
ensuring that its path() will be the same as its absolutePath().
See tempPath() for details.
@@ -2068,7 +2070,7 @@ QString QDir::homePath()
*/
/*!
- Returns the absolute path of the system's temporary directory.
+ Returns the absolute canonical path of the system's temporary directory.
On Unix/Linux systems this is the path in the \c TMPDIR environment
variable or \c{/tmp} if \c TMPDIR is not defined. On Windows this is
@@ -2110,7 +2112,7 @@ QString QDir::rootPath()
return QFileSystemEngine::rootPath();
}
-#ifndef QT_NO_REGEXP
+#if QT_CONFIG(regularexpression)
/*!
\overload
@@ -2118,13 +2120,18 @@ QString QDir::rootPath()
patterns in the list of \a filters; otherwise returns \c false. The
matching is case insensitive.
- \sa {QRegExp wildcard matching}, QRegExp::exactMatch(), entryList(), entryInfoList()
+ \sa {QRegularExpression Wildcard matching}, QRegularExpression::wildcardToRegularExpression(),
+ entryList(), entryInfoList()
*/
bool QDir::match(const QStringList &filters, const QString &fileName)
{
for (QStringList::ConstIterator sit = filters.constBegin(); sit != filters.constEnd(); ++sit) {
- QRegExp rx(*sit, Qt::CaseInsensitive, QRegExp::Wildcard);
- if (rx.exactMatch(fileName))
+ QString wildcard = QRegularExpression::wildcardToRegularExpression(*sit);
+ // Insensitive exact match
+ // (see Notes for QRegExp Users in QRegularExpression's documentation)
+ QRegularExpression rx(QRegularExpression::anchoredPattern(wildcard),
+ QRegularExpression::CaseInsensitiveOption);
+ if (rx.match(fileName).hasMatch())
return true;
}
return false;
@@ -2136,13 +2143,14 @@ bool QDir::match(const QStringList &filters, const QString &fileName)
contain multiple patterns separated by spaces or semicolons.
The matching is case insensitive.
- \sa {QRegExp wildcard matching}, QRegExp::exactMatch(), entryList(), entryInfoList()
+ \sa {QRegularExpression wildcard matching}, QRegularExpression::wildcardToRegularExpression,
+ entryList(), entryInfoList()
*/
bool QDir::match(const QString &filter, const QString &fileName)
{
return match(nameFiltersFromString(filter), fileName);
}
-#endif // QT_NO_REGEXP
+#endif // QT_CONFIG(regularexpression)
/*!
\internal
diff --git a/src/corelib/io/qdir.h b/src/corelib/io/qdir.h
index 950a26f327..45c59d9e1d 100644
--- a/src/corelib/io/qdir.h
+++ b/src/corelib/io/qdir.h
@@ -206,7 +206,7 @@ public:
static inline QDir temp() { return QDir(tempPath()); }
static QString tempPath();
-#ifndef QT_NO_REGEXP
+#if QT_CONFIG(regularexpression)
static bool match(const QStringList &filters, const QString &fileName);
static bool match(const QString &filter, const QString &fileName);
#endif
diff --git a/src/corelib/io/qfilesystemengine_unix.cpp b/src/corelib/io/qfilesystemengine_unix.cpp
index deb4a9f220..835e6a6a44 100644
--- a/src/corelib/io/qfilesystemengine_unix.cpp
+++ b/src/corelib/io/qfilesystemengine_unix.cpp
@@ -774,7 +774,7 @@ QFileSystemEntry QFileSystemEngine::canonicalName(const QFileSystemEntry &entry,
QString canonicalPath = QDir::cleanPath(QFile::decodeName(ret));
free(ret);
return QFileSystemEntry(canonicalPath);
- } else if (errno == ENOENT) { // file doesn't exist
+ } else if (errno == ENOENT || errno == ENOTDIR) { // file doesn't exist
data.knownFlagsMask |= QFileSystemMetaData::ExistsAttribute;
data.entryFlags &= ~(QFileSystemMetaData::ExistsAttribute);
return QFileSystemEntry();
@@ -853,7 +853,7 @@ QByteArray QFileSystemEngine::id(int id)
//static
QString QFileSystemEngine::resolveUserName(uint userId)
{
-#if !defined(QT_NO_THREAD) && defined(_POSIX_THREAD_SAFE_FUNCTIONS) && !defined(Q_OS_OPENBSD)
+#if QT_CONFIG(thread) && defined(_POSIX_THREAD_SAFE_FUNCTIONS) && !defined(Q_OS_OPENBSD)
int size_max = sysconf(_SC_GETPW_R_SIZE_MAX);
if (size_max == -1)
size_max = 1024;
@@ -862,7 +862,7 @@ QString QFileSystemEngine::resolveUserName(uint userId)
#if !defined(Q_OS_INTEGRITY)
struct passwd *pw = 0;
-#if !defined(QT_NO_THREAD) && defined(_POSIX_THREAD_SAFE_FUNCTIONS) && !defined(Q_OS_OPENBSD) && !defined(Q_OS_VXWORKS)
+#if QT_CONFIG(thread) && defined(_POSIX_THREAD_SAFE_FUNCTIONS) && !defined(Q_OS_OPENBSD) && !defined(Q_OS_VXWORKS)
struct passwd entry;
getpwuid_r(userId, &entry, buf.data(), buf.size(), &pw);
#else
@@ -877,7 +877,7 @@ QString QFileSystemEngine::resolveUserName(uint userId)
//static
QString QFileSystemEngine::resolveGroupName(uint groupId)
{
-#if !defined(QT_NO_THREAD) && defined(_POSIX_THREAD_SAFE_FUNCTIONS) && !defined(Q_OS_OPENBSD)
+#if QT_CONFIG(thread) && defined(_POSIX_THREAD_SAFE_FUNCTIONS) && !defined(Q_OS_OPENBSD)
int size_max = sysconf(_SC_GETPW_R_SIZE_MAX);
if (size_max == -1)
size_max = 1024;
@@ -886,7 +886,7 @@ QString QFileSystemEngine::resolveGroupName(uint groupId)
#if !defined(Q_OS_INTEGRITY)
struct group *gr = 0;
-#if !defined(QT_NO_THREAD) && defined(_POSIX_THREAD_SAFE_FUNCTIONS) && !defined(Q_OS_OPENBSD) && !defined(Q_OS_VXWORKS) && (!defined(Q_OS_ANDROID) || defined(Q_OS_ANDROID) && (__ANDROID_API__ >= 24))
+#if QT_CONFIG(thread) && defined(_POSIX_THREAD_SAFE_FUNCTIONS) && !defined(Q_OS_OPENBSD) && !defined(Q_OS_VXWORKS) && (!defined(Q_OS_ANDROID) || defined(Q_OS_ANDROID) && (__ANDROID_API__ >= 24))
size_max = sysconf(_SC_GETGR_R_SIZE_MAX);
if (size_max == -1)
size_max = 1024;
@@ -1524,7 +1524,7 @@ QString QFileSystemEngine::tempPath()
temp = QLatin1String(_PATH_TMP);
}
}
- return QDir::cleanPath(temp);
+ return QDir(QDir::cleanPath(temp)).canonicalPath();
#endif
}
diff --git a/src/corelib/io/qfilesystemwatcher_fsevents.mm b/src/corelib/io/qfilesystemwatcher_fsevents.mm
index 0254d0f7a1..f68fb67d79 100644
--- a/src/corelib/io/qfilesystemwatcher_fsevents.mm
+++ b/src/corelib/io/qfilesystemwatcher_fsevents.mm
@@ -499,7 +499,7 @@ bool QFseventsFileSystemWatcherEngine::startStream()
DEBUG() << "Starting stream with paths" << watchingState.watchedPaths.keys();
- NSMutableArray *pathsToWatch = [NSMutableArray arrayWithCapacity:watchingState.watchedPaths.size()];
+ NSMutableArray<NSString *> *pathsToWatch = [NSMutableArray<NSString *> arrayWithCapacity:watchingState.watchedPaths.size()];
for (PathRefCounts::const_iterator i = watchingState.watchedPaths.begin(), ei = watchingState.watchedPaths.end(); i != ei; ++i)
[pathsToWatch addObject:i.key().toNSString()];
diff --git a/src/corelib/io/qfilesystemwatcher_win.cpp b/src/corelib/io/qfilesystemwatcher_win.cpp
index 9e43d11e71..3a49f4346b 100644
--- a/src/corelib/io/qfilesystemwatcher_win.cpp
+++ b/src/corelib/io/qfilesystemwatcher_win.cpp
@@ -57,6 +57,7 @@
# include <qcoreapplication.h>
# include <qdir.h>
# include <private/qeventdispatcher_win_p.h>
+# include <private/qthread_p.h>
# include <dbt.h>
# include <algorithm>
# include <vector>
@@ -308,7 +309,8 @@ void QWindowsRemovableDriveListener::addPath(const QString &p)
notify.dbch_size = sizeof(notify);
notify.dbch_devicetype = DBT_DEVTYP_HANDLE;
notify.dbch_handle = volumeHandle;
- QEventDispatcherWin32 *winEventDispatcher = static_cast<QEventDispatcherWin32 *>(QAbstractEventDispatcher::instance());
+ QThreadData *currentData = QThreadData::current();
+ QEventDispatcherWin32 *winEventDispatcher = static_cast<QEventDispatcherWin32 *>(currentData->ensureEventDispatcher());
re.devNotify = RegisterDeviceNotification(winEventDispatcher->internalHwnd(),
&notify, DEVICE_NOTIFY_WINDOW_HANDLE);
// Empirically found: The notifications also work when the handle is immediately
diff --git a/src/corelib/io/qfsfileengine_unix.cpp b/src/corelib/io/qfsfileengine_unix.cpp
index bbd262e2f9..90ad0126d6 100644
--- a/src/corelib/io/qfsfileengine_unix.cpp
+++ b/src/corelib/io/qfsfileengine_unix.cpp
@@ -82,12 +82,11 @@ static inline int openModeToOpenFlags(QIODevice::OpenMode mode)
if (QFSFileEnginePrivate::openModeCanCreate(mode))
oflags |= QT_OPEN_CREAT;
- if (mode & QFile::Append) {
+ if (mode & QFile::Truncate)
+ oflags |= QT_OPEN_TRUNC;
+
+ if (mode & QFile::Append)
oflags |= QT_OPEN_APPEND;
- } else if (mode & QFile::WriteOnly) {
- if ((mode & QFile::Truncate) || !(mode & QFile::ReadOnly))
- oflags |= QT_OPEN_TRUNC;
- }
if (mode & QFile::NewOnly)
oflags |= QT_OPEN_EXCL;
@@ -531,29 +530,32 @@ QByteArray QFSFileEngine::id() const
QString QFSFileEngine::fileName(FileName file) const
{
Q_D(const QFSFileEngine);
- if (file == BundleName) {
+ switch (file) {
+ case BundleName:
return QFileSystemEngine::bundleName(d->fileEntry);
- } else if (file == BaseName) {
+ case BaseName:
return d->fileEntry.fileName();
- } else if (file == PathName) {
+ case PathName:
return d->fileEntry.path();
- } else if (file == AbsoluteName || file == AbsolutePathName) {
+ case AbsoluteName:
+ case AbsolutePathName: {
QFileSystemEntry entry(QFileSystemEngine::absoluteName(d->fileEntry));
- if (file == AbsolutePathName) {
- return entry.path();
- }
- return entry.filePath();
- } else if (file == CanonicalName || file == CanonicalPathName) {
+ return file == AbsolutePathName ? entry.path() : entry.filePath();
+ }
+ case CanonicalName:
+ case CanonicalPathName: {
QFileSystemEntry entry(QFileSystemEngine::canonicalName(d->fileEntry, d->metaData));
- if (file == CanonicalPathName)
- return entry.path();
- return entry.filePath();
- } else if (file == LinkName) {
+ return file == CanonicalPathName ? entry.path() : entry.filePath();
+ }
+ case LinkName:
if (d->isSymlink()) {
QFileSystemEntry entry = QFileSystemEngine::getLinkTarget(d->fileEntry, d->metaData);
return entry.filePath();
}
return QString();
+ case DefaultName:
+ case NFileNames:
+ break;
}
return d->fileEntry.filePath();
}
diff --git a/src/corelib/io/qfsfileengine_win.cpp b/src/corelib/io/qfsfileengine_win.cpp
index 8199f6a846..9d3bfbba31 100644
--- a/src/corelib/io/qfsfileengine_win.cpp
+++ b/src/corelib/io/qfsfileengine_win.cpp
@@ -45,7 +45,6 @@
#include "qfile.h"
#include "qdir.h"
-#include "private/qmutexpool_p.h"
#include "qvarlengtharray.h"
#include "qdatetime.h"
#include "qt_windows.h"
@@ -591,7 +590,6 @@ bool QFSFileEnginePrivate::doStat(QFileSystemMetaData::MetaDataFlags flags) cons
bool QFSFileEngine::link(const QString &newName)
{
#if !defined(Q_OS_WINRT)
-# if QT_CONFIG(library)
bool ret = false;
QString linkName = newName;
@@ -600,23 +598,27 @@ bool QFSFileEngine::link(const QString &newName)
IShellLink *psl;
bool neededCoInit = false;
- HRESULT hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (void **)&psl);
+ HRESULT hres = CoCreateInstance(CLSID_ShellLink, nullptr, CLSCTX_INPROC_SERVER, IID_IShellLink,
+ reinterpret_cast<void **>(&psl));
if (hres == CO_E_NOTINITIALIZED) { // COM was not initialized
neededCoInit = true;
- CoInitialize(NULL);
- hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (void **)&psl);
+ CoInitialize(nullptr);
+ hres = CoCreateInstance(CLSID_ShellLink, nullptr, CLSCTX_INPROC_SERVER, IID_IShellLink,
+ reinterpret_cast<void **>(&psl));
}
if (SUCCEEDED(hres)) {
- hres = psl->SetPath((wchar_t *)fileName(AbsoluteName).replace(QLatin1Char('/'), QLatin1Char('\\')).utf16());
+ const QString nativeAbsoluteName = fileName(AbsoluteName).replace(QLatin1Char('/'), QLatin1Char('\\'));
+ hres = psl->SetPath(reinterpret_cast<const wchar_t *>(nativeAbsoluteName.utf16()));
if (SUCCEEDED(hres)) {
- hres = psl->SetWorkingDirectory((wchar_t *)fileName(AbsolutePathName).replace(QLatin1Char('/'), QLatin1Char('\\')).utf16());
+ const QString nativeAbsolutePathName = fileName(AbsolutePathName).replace(QLatin1Char('/'), QLatin1Char('\\'));
+ hres = psl->SetWorkingDirectory(reinterpret_cast<const wchar_t *>(nativeAbsolutePathName.utf16()));
if (SUCCEEDED(hres)) {
IPersistFile *ppf;
- hres = psl->QueryInterface(IID_IPersistFile, (void **)&ppf);
+ hres = psl->QueryInterface(IID_IPersistFile, reinterpret_cast<void **>(&ppf));
if (SUCCEEDED(hres)) {
- hres = ppf->Save((wchar_t*)linkName.utf16(), TRUE);
+ hres = ppf->Save(reinterpret_cast<const wchar_t *>(linkName.utf16()), TRUE);
if (SUCCEEDED(hres))
ret = true;
ppf->Release();
@@ -632,10 +634,6 @@ bool QFSFileEngine::link(const QString &newName)
CoUninitialize();
return ret;
-# else // QT_CONFIG(library)
- Q_UNUSED(newName);
- return false;
-# endif // QT_CONFIG(library)
#else // !Q_OS_WINRT
Q_UNUSED(newName);
Q_UNIMPLEMENTED();
diff --git a/src/corelib/io/qiodevice.cpp b/src/corelib/io/qiodevice.cpp
index 95a5fb27cf..5dd5f8031e 100644
--- a/src/corelib/io/qiodevice.cpp
+++ b/src/corelib/io/qiodevice.cpp
@@ -312,8 +312,9 @@ QIODevicePrivate::~QIODevicePrivate()
\value NotOpen The device is not open.
\value ReadOnly The device is open for reading.
- \value WriteOnly The device is open for writing. Note that this mode implies
- Truncate.
+ \value WriteOnly The device is open for writing. Note that, for file-system
+ subclasses (e.g. QFile), this mode implies Truncate unless
+ combined with ReadOnly, Append or NewOnly.
\value ReadWrite The device is open for reading and writing.
\value Append The device is opened in append mode so that all data is
written to the end of the file.
diff --git a/src/corelib/io/qloggingregistry.cpp b/src/corelib/io/qloggingregistry.cpp
index cd97268d71..9792d956cc 100644
--- a/src/corelib/io/qloggingregistry.cpp
+++ b/src/corelib/io/qloggingregistry.cpp
@@ -46,6 +46,11 @@
#include <QtCore/qdir.h>
#include <QtCore/qcoreapplication.h>
+#if QT_CONFIG(settings)
+#include <QtCore/qsettings.h>
+#include <QtCore/private/qsettings_p.h>
+#endif
+
// We can't use the default macros because this would lead to recursion.
// Instead let's define our own one that unconditionally logs...
#define debugMsg QMessageLogger(__FILE__, __LINE__, __FUNCTION__, "qt.core.logging").debug
@@ -230,7 +235,14 @@ void QLoggingSettingsParser::parseNextLine(QStringRef line)
int equalPos = line.indexOf(QLatin1Char('='));
if (equalPos != -1) {
if (line.lastIndexOf(QLatin1Char('=')) == equalPos) {
- const auto pattern = line.left(equalPos).trimmed();
+ const auto key = line.left(equalPos).trimmed();
+#if QT_CONFIG(settings)
+ QString tmp;
+ QSettingsPrivate::iniUnescapedKey(key.toUtf8(), 0, key.length(), tmp);
+ QStringRef pattern = QStringRef(&tmp, 0, tmp.length());
+#else
+ QStringRef pattern = key;
+#endif
const auto valueStr = line.mid(equalPos + 1).trimmed();
int value = -1;
if (valueStr == QLatin1String("true"))
diff --git a/src/corelib/io/qprocess_unix.cpp b/src/corelib/io/qprocess_unix.cpp
index 713af9bd40..7a2daa2a57 100644
--- a/src/corelib/io/qprocess_unix.cpp
+++ b/src/corelib/io/qprocess_unix.cpp
@@ -101,7 +101,6 @@ QT_END_NAMESPACE
#include <qdir.h>
#include <qlist.h>
#include <qmutex.h>
-#include <qsemaphore.h>
#include <qsocketnotifier.h>
#include <qthread.h>
#include <qelapsedtimer.h>
diff --git a/src/corelib/io/qprocess_win.cpp b/src/corelib/io/qprocess_win.cpp
index 8c4e5b41b4..1f7a49379d 100644
--- a/src/corelib/io/qprocess_win.cpp
+++ b/src/corelib/io/qprocess_win.cpp
@@ -149,7 +149,26 @@ static void qt_create_pipe(Q_PIPE *pipe, bool isInputPipe)
}
// Wait until connection is in place.
- ConnectNamedPipe(hServer, NULL);
+ OVERLAPPED overlapped;
+ ZeroMemory(&overlapped, sizeof(overlapped));
+ overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
+ if (ConnectNamedPipe(hServer, &overlapped) == 0) {
+ DWORD dwError = GetLastError();
+ switch (dwError) {
+ case ERROR_PIPE_CONNECTED:
+ break;
+ case ERROR_IO_PENDING:
+ WaitForSingleObject(overlapped.hEvent, INFINITE);
+ break;
+ default:
+ qErrnoWarning(dwError, "QProcess: ConnectNamedPipe failed.");
+ CloseHandle(overlapped.hEvent);
+ CloseHandle(hClient);
+ CloseHandle(hServer);
+ return;
+ }
+ }
+ CloseHandle(overlapped.hEvent);
if (isInputPipe) {
pipe[0] = hClient;
diff --git a/src/corelib/io/qresource.cpp b/src/corelib/io/qresource.cpp
index 7502fb57a3..367cd78d65 100644
--- a/src/corelib/io/qresource.cpp
+++ b/src/corelib/io/qresource.cpp
@@ -52,7 +52,9 @@
#include "qendian.h"
#include <qshareddata.h>
#include <qplatformdefs.h>
+#include <qendian.h>
#include "private/qabstractfileengine_p.h"
+#include "private/qsimd_p.h"
#include "private/qsystemerror_p.h"
#ifdef Q_OS_UNIX
@@ -629,17 +631,13 @@ inline QString QResourceRoot::name(int node) const
QString ret;
qint32 name_offset = qFromBigEndian<qint32>(tree + offset);
- const qint16 name_length = qFromBigEndian<qint16>(names + name_offset);
+ quint16 name_length = qFromBigEndian<qint16>(names + name_offset);
name_offset += 2;
name_offset += 4; //jump past hash
ret.resize(name_length);
QChar *strData = ret.data();
- for(int i = 0; i < name_length*2; i+=2) {
- QChar c(names[name_offset+i+1], names[name_offset+i]);
- *strData = c;
- ++strData;
- }
+ qFromBigEndian<ushort>(names + name_offset, name_length, strData);
return ret;
}
diff --git a/src/corelib/io/qsettings.cpp b/src/corelib/io/qsettings.cpp
index 4b1b9888d8..1134c6bb85 100644
--- a/src/corelib/io/qsettings.cpp
+++ b/src/corelib/io/qsettings.cpp
@@ -1694,10 +1694,10 @@ bool QConfFileSettingsPrivate::readIniFile(const QByteArray &data,
iniSection = iniSection.trimmed();
- if (qstricmp(iniSection.constData(), "general") == 0) {
+ if (iniSection.compare("general", Qt::CaseInsensitive) == 0) {
currentSection.clear();
} else {
- if (qstricmp(iniSection.constData(), "%general") == 0) {
+ if (iniSection.compare("%general", Qt::CaseInsensitive) == 0) {
currentSection = QLatin1String(iniSection.constData() + 1);
} else {
currentSection.clear();
@@ -1857,7 +1857,7 @@ bool QConfFileSettingsPrivate::writeIniFile(QIODevice &device, const ParsedSetti
if (realSection.isEmpty()) {
realSection = "[General]";
- } else if (qstricmp(realSection.constData(), "general") == 0) {
+ } else if (realSection.compare("general", Qt::CaseInsensitive) == 0) {
realSection = "[%General]";
} else {
realSection.prepend('[');
diff --git a/src/corelib/io/qsettings_mac.cpp b/src/corelib/io/qsettings_mac.cpp
index aa14d8435a..28f01eae4d 100644
--- a/src/corelib/io/qsettings_mac.cpp
+++ b/src/corelib/io/qsettings_mac.cpp
@@ -355,15 +355,15 @@ public:
const QString &application);
~QMacSettingsPrivate();
- void remove(const QString &key);
- void set(const QString &key, const QVariant &value);
- bool get(const QString &key, QVariant *value) const;
- QStringList children(const QString &prefix, ChildSpec spec) const;
- void clear();
- void sync();
- void flush();
- bool isWritable() const;
- QString fileName() const;
+ void remove(const QString &key) override;
+ void set(const QString &key, const QVariant &value) override;
+ bool get(const QString &key, QVariant *value) const override;
+ QStringList children(const QString &prefix, ChildSpec spec) const override;
+ void clear() override;
+ void sync() override;
+ void flush() override;
+ bool isWritable() const override;
+ QString fileName() const override;
private:
struct SearchDomain
diff --git a/src/corelib/io/qsettings_win.cpp b/src/corelib/io/qsettings_win.cpp
index edcae16776..43e1411c76 100644
--- a/src/corelib/io/qsettings_win.cpp
+++ b/src/corelib/io/qsettings_win.cpp
@@ -383,17 +383,17 @@ public:
QWinSettingsPrivate(QString rKey, REGSAM access = 0);
~QWinSettingsPrivate();
- void remove(const QString &uKey);
- void set(const QString &uKey, const QVariant &value);
- bool get(const QString &uKey, QVariant *value) const;
- QStringList children(const QString &uKey, ChildSpec spec) const;
- void clear();
- void sync();
- void flush();
- bool isWritable() const;
+ void remove(const QString &uKey) override;
+ void set(const QString &uKey, const QVariant &value) override;
+ bool get(const QString &uKey, QVariant *value) const override;
+ QStringList children(const QString &uKey, ChildSpec spec) const override;
+ void clear() override;
+ void sync() override;
+ void flush() override;
+ bool isWritable() const override;
HKEY writeHandle() const;
bool readKey(HKEY parentHandle, const QString &rSubKey, QVariant *value) const;
- QString fileName() const;
+ QString fileName() const override;
private:
RegistryKeyList regList; // list of registry locations to search for keys
diff --git a/src/corelib/io/qsettings_winrt.cpp b/src/corelib/io/qsettings_winrt.cpp
index 209b56d920..4c757f9dda 100644
--- a/src/corelib/io/qsettings_winrt.cpp
+++ b/src/corelib/io/qsettings_winrt.cpp
@@ -290,15 +290,15 @@ public:
QWinRTSettingsPrivate(const QString &rKey);
~QWinRTSettingsPrivate();
- void remove(const QString &uKey);
- void set(const QString &uKey, const QVariant &value);
- bool get(const QString &uKey, QVariant *value) const;
- QStringList children(const QString &uKey, ChildSpec spec) const;
- void clear();
- void sync();
- void flush();
- bool isWritable() const;
- QString fileName() const;
+ void remove(const QString &uKey) override;
+ void set(const QString &uKey, const QVariant &value) override;
+ bool get(const QString &uKey, QVariant *value) const override;
+ QStringList children(const QString &uKey, ChildSpec spec) const override;
+ void clear() override;
+ void sync() override;
+ void flush() override;
+ bool isWritable() const override;
+ QString fileName() const override;
private:
void init(QSettings::Scope scope);
diff --git a/src/corelib/io/qurl.cpp b/src/corelib/io/qurl.cpp
index 438924bd80..e531505877 100644
--- a/src/corelib/io/qurl.cpp
+++ b/src/corelib/io/qurl.cpp
@@ -472,16 +472,10 @@ static inline QString webDavSslTag()
return QStringLiteral("@SSL");
}
-#ifdef Q_COMPILER_CLASS_ENUM
-# define colon_uchar : uchar
-#else
-# define colon_uchar
-#endif
-
class QUrlPrivate
{
public:
- enum Section colon_uchar {
+ enum Section : uchar {
Scheme = 0x01,
UserName = 0x02,
Password = 0x04,
@@ -496,7 +490,7 @@ public:
FullUrl = 0xff
};
- enum Flags colon_uchar {
+ enum Flags : uchar {
IsLocalFile = 0x01
};
@@ -616,7 +610,6 @@ public:
// 32-bit: 2 bytes tail padding available
// 64-bit: 6 bytes tail padding available
};
-#undef colon_uchar
inline QUrlPrivate::QUrlPrivate()
: ref(1), port(-1),
@@ -1203,15 +1196,13 @@ inline void QUrlPrivate::setQuery(const QString &value, int from, int iend)
inline void QUrlPrivate::appendHost(QString &appendTo, QUrl::FormattingOptions options) const
{
- // EncodeUnicode is the only flag that matters
- if ((options & QUrl::FullyDecoded) == QUrl::FullyDecoded)
- options = 0;
- else
- options &= QUrl::EncodeUnicode;
if (host.isEmpty())
return;
if (host.at(0).unicode() == '[') {
- // IPv6Address and IPvFuture address never require any transformation
+ // IPv6 addresses might contain a zone-id which needs to be recoded
+ if (options != 0)
+ if (qt_urlRecode(appendTo, host.constBegin(), host.constEnd(), options, 0))
+ return;
appendTo += host;
} else {
// this is either an IPv4Address or a reg-name
@@ -1278,31 +1269,44 @@ static const QChar *parseIpFuture(QString &host, const QChar *begin, const QChar
// ONLY the IPv6 address is parsed here, WITHOUT the brackets
static const QChar *parseIp6(QString &host, const QChar *begin, const QChar *end, QUrl::ParsingMode mode)
{
- QIPAddressUtils::IPv6Address address;
- const QChar *ret = QIPAddressUtils::parseIp6(address, begin, end);
- if (ret) {
+ // ### Update to use QStringView once QStringView::indexOf and QStringView::lastIndexOf exists
+ QString decoded;
+ if (mode == QUrl::TolerantMode) {
// this struct is kept in automatic storage because it's only 4 bytes
const ushort decodeColon[] = { decode(':'), 0 };
+ if (qt_urlRecode(decoded, begin, end, QUrl::ComponentFormattingOption::PrettyDecoded, decodeColon) == 0)
+ decoded = QString(begin, end-begin);
+ } else {
+ decoded = QString(begin, end-begin);
+ }
- // IPv6 failed parsing, check if it was a percent-encoded character in
- // the middle and try again
- QString decoded;
- if (mode == QUrl::TolerantMode && qt_urlRecode(decoded, begin, end, 0, decodeColon)) {
- // recurse
- // if the parsing fails again, the qt_urlRecode above will return 0
- ret = parseIp6(host, decoded.constBegin(), decoded.constEnd(), mode);
+ const QLatin1String zoneIdIdentifier("%25");
+ QIPAddressUtils::IPv6Address address;
+ QString zoneId;
- // we can't return ret, otherwise it would be dangling
- return ret ? end : 0;
- }
+ const QChar *endBeforeZoneId = decoded.constEnd();
+
+ int zoneIdPosition = decoded.indexOf(zoneIdIdentifier);
+ if ((zoneIdPosition != -1) && (decoded.lastIndexOf(zoneIdIdentifier) == zoneIdPosition)) {
+ zoneId = decoded.mid(zoneIdPosition + zoneIdIdentifier.size());
+ endBeforeZoneId = decoded.constBegin() + zoneIdPosition;
- // no transformation, nothing to re-parse
- return ret;
+ if (zoneId.isEmpty())
+ return end;
}
- host.reserve(host.size() + (end - begin));
+ const QChar *ret = QIPAddressUtils::parseIp6(address, decoded.constBegin(), endBeforeZoneId);
+ if (ret)
+ return begin + (ret - decoded.constBegin());
+
+ host.reserve(host.size() + (decoded.constEnd() - decoded.constBegin()));
host += QLatin1Char('[');
QIPAddressUtils::toString(host, address);
+
+ if (!zoneId.isEmpty()) {
+ host += zoneIdIdentifier;
+ host += zoneId;
+ }
host += QLatin1Char(']');
return 0;
}
diff --git a/src/corelib/io/qurlrecode.cpp b/src/corelib/io/qurlrecode.cpp
index a9b23babc0..443ae18b21 100644
--- a/src/corelib/io/qurlrecode.cpp
+++ b/src/corelib/io/qurlrecode.cpp
@@ -40,6 +40,7 @@
#include "qurl.h"
#include "private/qutfcodec_p.h"
#include "private/qtools_p.h"
+#include "private/qsimd_p.h"
QT_BEGIN_NAMESPACE
@@ -474,6 +475,88 @@ non_trivial:
return 0;
}
+/*
+ * Returns true if the input it checked (if it checked anything) is not
+ * encoded. A return of false indicates there's a percent at \a input that
+ * needs to be decoded.
+ */
+#ifdef __SSE2__
+static bool simdCheckNonEncoded(ushort *&output, const ushort *&input, const ushort *end)
+{
+# ifdef __AVX2__
+ const __m256i percents256 = _mm256_broadcastw_epi16(_mm_cvtsi32_si128('%'));
+ const __m128i percents = _mm256_castsi256_si128(percents256);
+# else
+ const __m128i percents = _mm_set1_epi16('%');
+# endif
+
+ uint idx = 0;
+ quint32 mask = 0;
+ if (input + 16 <= end) {
+ qptrdiff offset = 0;
+ for ( ; input + offset + 16 <= end; offset += 16) {
+# ifdef __AVX2__
+ // do 32 bytes at a time using AVX2
+ __m256i data = _mm256_loadu_si256(reinterpret_cast<const __m256i *>(input + offset));
+ __m256i comparison = _mm256_cmpeq_epi16(data, percents256);
+ mask = _mm256_movemask_epi8(comparison);
+ _mm256_storeu_si256(reinterpret_cast<__m256i *>(output + offset), data);
+# else
+ // do 32 bytes at a time using unrolled SSE2
+ __m128i data1 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(input + offset));
+ __m128i data2 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(input + offset + 8));
+ __m128i comparison1 = _mm_cmpeq_epi16(data1, percents);
+ __m128i comparison2 = _mm_cmpeq_epi16(data2, percents);
+ uint mask1 = _mm_movemask_epi8(comparison1);
+ uint mask2 = _mm_movemask_epi8(comparison2);
+
+ _mm_storeu_si128(reinterpret_cast<__m128i *>(output + offset), data1);
+ if (!mask1)
+ _mm_storeu_si128(reinterpret_cast<__m128i *>(output + offset + 8), data2);
+ mask = mask1 | (mask2 << 16);
+# endif
+
+ if (mask) {
+ idx = qCountTrailingZeroBits(mask) / 2;
+ break;
+ }
+ }
+
+ input += offset;
+ if (output)
+ output += offset;
+ } else if (input + 8 <= end) {
+ // do 16 bytes at a time
+ __m128i data = _mm_loadu_si128(reinterpret_cast<const __m128i *>(input));
+ __m128i comparison = _mm_cmpeq_epi16(data, percents);
+ mask = _mm_movemask_epi8(comparison);
+ _mm_storeu_si128(reinterpret_cast<__m128i *>(output), data);
+ idx = qCountTrailingZeroBits(quint16(mask)) / 2;
+ } else if (input + 4 <= end) {
+ // do 8 bytes only
+ __m128i data = _mm_loadl_epi64(reinterpret_cast<const __m128i *>(input));
+ __m128i comparison = _mm_cmpeq_epi16(data, percents);
+ mask = _mm_movemask_epi8(comparison) & 0xffu;
+ _mm_storel_epi64(reinterpret_cast<__m128i *>(output), data);
+ idx = qCountTrailingZeroBits(quint8(mask)) / 2;
+ } else {
+ // no percents found (because we didn't check)
+ return true;
+ }
+
+ // advance to the next non-encoded
+ input += idx;
+ output += idx;
+
+ return !mask;
+}
+#else
+static bool simdCheckNonEncoded(...)
+{
+ return true;
+}
+#endif
+
/*!
\since 5.0
\internal
@@ -497,16 +580,21 @@ non_trivial:
*/
static int decode(QString &appendTo, const ushort *begin, const ushort *end)
{
+ // fast check whether there's anything to be decoded in the first place
+ const ushort *input = QtPrivate::qustrchr(QStringView(begin, end), '%');
+ if (Q_LIKELY(input == end))
+ return 0; // nothing to do, it was already decoded!
+
+ // detach
const int origSize = appendTo.size();
- const ushort *input = begin;
- ushort *output = 0;
+ appendTo.resize(origSize + (end - begin));
+ ushort *output = reinterpret_cast<ushort *>(appendTo.begin()) + origSize;
+ memcpy(static_cast<void *>(output), static_cast<const void *>(begin), (input - begin) * sizeof(ushort));
+ output += input - begin;
+
while (input != end) {
- if (*input != '%') {
- if (output)
- *output++ = *input;
- ++input;
- continue;
- }
+ // something was encoded
+ Q_ASSERT(*input == '%');
if (Q_UNLIKELY(end - input < 3 || !isHex(input[1]) || !isHex(input[2]))) {
// badly-encoded data
@@ -515,27 +603,27 @@ static int decode(QString &appendTo, const ushort *begin, const ushort *end)
return end - begin;
}
- if (Q_UNLIKELY(!output)) {
- // detach
- appendTo.resize(origSize + (end - begin));
- output = reinterpret_cast<ushort *>(appendTo.begin()) + origSize;
- memcpy(static_cast<void *>(output), static_cast<const void *>(begin), (input - begin) * sizeof(ushort));
- output += input - begin;
- }
-
++input;
*output++ = decodeNibble(input[0]) << 4 | decodeNibble(input[1]);
if (output[-1] >= 0x80)
output[-1] = QChar::ReplacementCharacter;
input += 2;
- }
- if (output) {
- int len = output - reinterpret_cast<ushort *>(appendTo.begin());
- appendTo.truncate(len);
- return len - origSize;
+ // search for the next percent, copying from input to output
+ if (simdCheckNonEncoded(output, input, end)) {
+ while (input != end) {
+ ushort uc = *input;
+ if (uc == '%')
+ break;
+ *output++ = uc;
+ ++input;
+ }
+ }
}
- return 0;
+
+ int len = output - reinterpret_cast<ushort *>(appendTo.begin());
+ appendTo.truncate(len);
+ return len - origSize;
}
template <size_t N>
@@ -603,6 +691,9 @@ qt_urlRecode(QString &appendTo, const QChar *begin, const QChar *end,
encoding, actionTable, false);
}
+// qstring.cpp
+bool qt_is_ascii(const char *&ptr, const char *end) Q_DECL_NOTHROW;
+
/*!
\internal
\since 5.0
@@ -623,12 +714,7 @@ QString qt_urlRecodeByteArray(const QByteArray &ba)
// control points below 0x20 are fine in QString
const char *in = ba.constData();
const char *const end = ba.constEnd();
- for ( ; in < end; ++in) {
- if (*in & 0x80)
- break;
- }
-
- if (in == end) {
+ if (qt_is_ascii(in, end)) {
// no non-ASCII found, we're safe to convert to QString
return QString::fromLatin1(ba, ba.size());
}