diff options
Diffstat (limited to 'src/corelib/io/qfilesystementry.cpp')
-rw-r--r-- | src/corelib/io/qfilesystementry.cpp | 147 |
1 files changed, 71 insertions, 76 deletions
diff --git a/src/corelib/io/qfilesystementry.cpp b/src/corelib/io/qfilesystementry.cpp index 9b474b25b1..ac1691d30e 100644 --- a/src/corelib/io/qfilesystementry.cpp +++ b/src/corelib/io/qfilesystementry.cpp @@ -1,41 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #include "qfilesystementry_p.h" @@ -48,14 +12,20 @@ QT_BEGIN_NAMESPACE +using namespace Qt::StringLiterals; + +// Assigned to m_lastSeparator and m_firstDotInFileName to indicate resolveFilePath() +// hasn't been called yet +constexpr int Uninitialized = -2; + #ifdef Q_OS_WIN static bool isUncRoot(const QString &server) { QString localPath = QDir::toNativeSeparators(server); - if (!localPath.startsWith(QLatin1String("\\\\"))) + if (!localPath.startsWith("\\\\"_L1)) return false; - int idx = localPath.indexOf(QLatin1Char('\\'), 2); + int idx = localPath.indexOf(u'\\', 2); if (idx == -1 || idx + 1 == localPath.length()) return true; @@ -65,8 +35,8 @@ static bool isUncRoot(const QString &server) static inline QString fixIfRelativeUncPath(const QString &path) { QString currentPath = QDir::currentPath(); - if (currentPath.startsWith(QLatin1String("//"))) - return currentPath % QChar(QLatin1Char('/')) % path; + if (currentPath.startsWith("//"_L1)) + return currentPath % QChar(u'/') % path; return path; } #endif @@ -85,8 +55,8 @@ QFileSystemEntry::QFileSystemEntry() */ QFileSystemEntry::QFileSystemEntry(const QString &filePath) : m_filePath(QDir::fromNativeSeparators(filePath)), - m_lastSeparator(-2), - m_firstDotInFileName(-2), + m_lastSeparator(Uninitialized), + m_firstDotInFileName(Uninitialized), m_lastDotInFileName(0) { } @@ -98,8 +68,8 @@ QFileSystemEntry::QFileSystemEntry(const QString &filePath) */ QFileSystemEntry::QFileSystemEntry(const QString &filePath, FromInternalPath /* dummy */) : m_filePath(filePath), - m_lastSeparator(-2), - m_firstDotInFileName(-2), + m_lastSeparator(Uninitialized), + m_firstDotInFileName(Uninitialized), m_lastDotInFileName(0) { } @@ -110,8 +80,8 @@ QFileSystemEntry::QFileSystemEntry(const QString &filePath, FromInternalPath /* */ QFileSystemEntry::QFileSystemEntry(const NativePath &nativeFilePath, FromNativePath /* dummy */) : m_nativeFilePath(nativeFilePath), - m_lastSeparator(-2), - m_firstDotInFileName(-2), + m_lastSeparator(Uninitialized), + m_firstDotInFileName(Uninitialized), m_lastDotInFileName(0) { } @@ -119,8 +89,8 @@ QFileSystemEntry::QFileSystemEntry(const NativePath &nativeFilePath, FromNativeP QFileSystemEntry::QFileSystemEntry(const QString &filePath, const NativePath &nativeFilePath) : m_filePath(QDir::fromNativeSeparators(filePath)), m_nativeFilePath(nativeFilePath), - m_lastSeparator(-2), - m_firstDotInFileName(-2), + m_lastSeparator(Uninitialized), + m_firstDotInFileName(Uninitialized), m_lastDotInFileName(0) { } @@ -140,14 +110,8 @@ QFileSystemEntry::NativePath QFileSystemEntry::nativeFilePath() const void QFileSystemEntry::resolveFilePath() const { if (m_filePath.isEmpty() && !m_nativeFilePath.isEmpty()) { -#if defined(QFILESYSTEMENTRY_NATIVE_PATH_IS_UTF16) - m_filePath = QDir::fromNativeSeparators(m_nativeFilePath); #ifdef Q_OS_WIN - if (m_filePath.startsWith(QLatin1String("//?/UNC/"))) - m_filePath = m_filePath.remove(2,6); - if (m_filePath.startsWith(QLatin1String("//?/"))) - m_filePath = m_filePath.remove(0,4); -#endif + m_filePath = QDir::fromNativeSeparators(m_nativeFilePath); #else m_filePath = QDir::fromNativeSeparators(QFile::decodeName(m_nativeFilePath)); #endif @@ -162,8 +126,6 @@ void QFileSystemEntry::resolveNativeFilePath() const if (isRelative()) filePath = fixIfRelativeUncPath(m_filePath); m_nativeFilePath = QFSFileEnginePrivate::longFileName(QDir::toNativeSeparators(filePath)); -#elif defined(QFILESYSTEMENTRY_NATIVE_PATH_IS_UTF16) - m_nativeFilePath = QDir::toNativeSeparators(m_filePath); #else m_nativeFilePath = QFile::encodeName(QDir::toNativeSeparators(m_filePath)); #endif @@ -174,7 +136,7 @@ QString QFileSystemEntry::fileName() const { findLastSeparator(); #if defined(Q_OS_WIN) - if (m_lastSeparator == -1 && m_filePath.length() >= 2 && m_filePath.at(1) == QLatin1Char(':')) + if (m_lastSeparator == -1 && m_filePath.length() >= 2 && m_filePath.at(1) == u':') return m_filePath.mid(2); #endif return m_filePath.mid(m_lastSeparator + 1); @@ -185,15 +147,15 @@ QString QFileSystemEntry::path() const findLastSeparator(); if (m_lastSeparator == -1) { #if defined(Q_OS_WIN) - if (m_filePath.length() >= 2 && m_filePath.at(1) == QLatin1Char(':')) + if (m_filePath.length() >= 2 && m_filePath.at(1) == u':') return m_filePath.left(2); #endif - return QString(QLatin1Char('.')); + return QString(u'.'); } if (m_lastSeparator == 0) - return QString(QLatin1Char('/')); + return QString(u'/'); #if defined(Q_OS_WIN) - if (m_lastSeparator == 2 && m_filePath.at(1) == QLatin1Char(':')) + if (m_lastSeparator == 2 && m_filePath.at(1) == u':') return m_filePath.left(m_lastSeparator + 1); #endif return m_filePath.left(m_lastSeparator); @@ -209,7 +171,7 @@ QString QFileSystemEntry::baseName() const length--; } #if defined(Q_OS_WIN) - if (m_lastSeparator == -1 && m_filePath.length() >= 2 && m_filePath.at(1) == QLatin1Char(':')) + if (m_lastSeparator == -1 && m_filePath.length() >= 2 && m_filePath.at(1) == u':') return m_filePath.mid(2, length - 2); #endif return m_filePath.mid(m_lastSeparator + 1, length); @@ -225,7 +187,7 @@ QString QFileSystemEntry::completeBaseName() const length--; } #if defined(Q_OS_WIN) - if (m_lastSeparator == -1 && m_filePath.length() >= 2 && m_filePath.at(1) == QLatin1Char(':')) + if (m_lastSeparator == -1 && m_filePath.length() >= 2 && m_filePath.at(1) == u':') return m_filePath.mid(2, length - 2); #endif return m_filePath.mid(m_lastSeparator + 1, length); @@ -267,8 +229,8 @@ bool QFileSystemEntry::isAbsolute() const && m_filePath.at(1).unicode() == ':' && m_filePath.at(2).unicode() == '/') || (m_filePath.length() >= 2 - && m_filePath.at(0) == QLatin1Char('/') - && m_filePath.at(1) == QLatin1Char('/'))); + && m_filePath.at(0) == u'/' + && m_filePath.at(1) == u'/')); } #else bool QFileSystemEntry::isRelative() const @@ -293,14 +255,42 @@ bool QFileSystemEntry::isDriveRoot() const bool QFileSystemEntry::isDriveRootPath(const QString &path) { return (path.length() == 3 - && path.at(0).isLetter() && path.at(1) == QLatin1Char(':') - && path.at(2) == QLatin1Char('/')); + && path.at(0).isLetter() && path.at(1) == u':' + && path.at(2) == u'/'); +} + +QString QFileSystemEntry::removeUncOrLongPathPrefix(QString path) +{ + constexpr qsizetype minPrefixSize = 4; + if (path.size() < minPrefixSize) + return path; + + auto data = path.data(); + const auto slash = path[0]; + if (slash != u'\\' && slash != u'/') + return path; + + // check for "//?/" or "/??/" + if (data[2] == u'?' && data[3] == slash && (data[1] == slash || data[1] == u'?')) { + path = path.sliced(minPrefixSize); + + // check for a possible "UNC/" prefix left-over + if (path.size() >= 4) { + data = path.data(); + if (data[0] == u'U' && data[1] == u'N' && data[2] == u'C' && data[3] == slash) { + data[2] = slash; + return path.sliced(2); + } + } + } + + return path; } #endif // Q_OS_WIN bool QFileSystemEntry::isRootPath(const QString &path) { - if (path == QLatin1String("/") + if (path == "/"_L1 #if defined(Q_OS_WIN) || isDriveRootPath(path) || isUncRoot(path) @@ -317,19 +307,24 @@ bool QFileSystemEntry::isRoot() const return isRootPath(m_filePath); } +bool QFileSystemEntry::isEmpty() const +{ + return m_filePath.isEmpty() && m_nativeFilePath.isEmpty(); +} + // private methods void QFileSystemEntry::findLastSeparator() const { - if (m_lastSeparator == -2) { + if (m_lastSeparator == Uninitialized) { resolveFilePath(); - m_lastSeparator = m_filePath.lastIndexOf(QLatin1Char('/')); + m_lastSeparator = m_filePath.lastIndexOf(u'/'); } } void QFileSystemEntry::findFileNameSeparators() const { - if (m_firstDotInFileName == -2) { + if (m_firstDotInFileName == Uninitialized) { resolveFilePath(); int firstDotInFileName = -1; int lastDotInFileName = -1; @@ -382,7 +377,7 @@ bool QFileSystemEntry::isClean() const bool dotok = true; // checking for ".." or "." starts to relative paths bool slashok = true; for (QString::const_iterator iter = m_filePath.constBegin(); iter != m_filePath.constEnd(); ++iter) { - if (*iter == QLatin1Char('/')) { + if (*iter == u'/') { if (dots == 1 || dots == 2) return false; // path contains "./" or "../" if (!slashok) @@ -392,7 +387,7 @@ bool QFileSystemEntry::isClean() const slashok = false; } else if (dotok) { slashok = true; - if (*iter == QLatin1Char('.')) { + if (*iter == u'.') { dots++; if (dots > 2) dotok = false; |