diff options
Diffstat (limited to 'src/corelib/io')
-rw-r--r-- | src/corelib/io/qdir.cpp | 4 | ||||
-rw-r--r-- | src/corelib/io/qfilesystemengine_unix.cpp | 2 | ||||
-rw-r--r-- | src/corelib/io/qfilesystemwatcher_fsevents.mm | 2 | ||||
-rw-r--r-- | src/corelib/io/qfsfileengine_win.cpp | 23 | ||||
-rw-r--r-- | src/corelib/io/qprocess_win.cpp | 21 | ||||
-rw-r--r-- | src/corelib/io/qsettings.cpp | 6 | ||||
-rw-r--r-- | src/corelib/io/qurlrecode.cpp | 124 |
7 files changed, 151 insertions, 31 deletions
diff --git a/src/corelib/io/qdir.cpp b/src/corelib/io/qdir.cpp index e4d384e4ca..06eacf5455 100644 --- a/src/corelib/io/qdir.cpp +++ b/src/corelib/io/qdir.cpp @@ -2035,7 +2035,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. @@ -2044,7 +2044,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 diff --git a/src/corelib/io/qfilesystemengine_unix.cpp b/src/corelib/io/qfilesystemengine_unix.cpp index be6ce48d0c..0ffc4ca634 100644 --- a/src/corelib/io/qfilesystemengine_unix.cpp +++ b/src/corelib/io/qfilesystemengine_unix.cpp @@ -1534,7 +1534,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/qfsfileengine_win.cpp b/src/corelib/io/qfsfileengine_win.cpp index 8199f6a846..93cfd93d7e 100644 --- a/src/corelib/io/qfsfileengine_win.cpp +++ b/src/corelib/io/qfsfileengine_win.cpp @@ -591,7 +591,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 +599,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 +635,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/qprocess_win.cpp b/src/corelib/io/qprocess_win.cpp index b1ec2c560c..2e4b5d9cef 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/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/qurlrecode.cpp b/src/corelib/io/qurlrecode.cpp index a9b23babc0..0c7b1df716 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,100 @@ 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); + + if (output) + _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); + + if (output) { + _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); + + // speculatively store everything + if (output) + _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; + + if (output) + _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; + if (output) + output += idx; + + return !mask; +} +#else +static bool simdCheckNonEncoded(...) +{ + return true; +} +#endif + /*! \since 5.0 \internal @@ -501,13 +596,22 @@ static int decode(QString &appendTo, const ushort *begin, const ushort *end) const ushort *input = begin; ushort *output = 0; while (input != end) { - if (*input != '%') { - if (output) - *output++ = *input; - ++input; - continue; + if (simdCheckNonEncoded(output, input, end)) { + ushort uc = 0; + while (input != end) { + uc = *input; + if (uc == '%') + break; + if (output) + *output++ = uc; + ++input; + } + + if (uc != '%') + break; // we're done } + // something was encoded if (Q_UNLIKELY(end - input < 3 || !isHex(input[1]) || !isHex(input[2]))) { // badly-encoded data appendTo.resize(origSize + (end - begin)); @@ -603,6 +707,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 +730,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()); } |