Utils: Replace FilePath::m_root member by a int m_rootLen

... and keep the string data as part of m_path.

Change-Id: Iaa43183906b59a419ddd78ed0102fe48c686bbb4
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
This commit is contained in:
hjk
2022-08-11 16:32:19 +02:00
parent 14a64254da
commit a8145ff6c9
2 changed files with 53 additions and 49 deletions

View File

@@ -181,11 +181,11 @@ static QString hostEncoded(QString host)
QString FilePath::toString() const QString FilePath::toString() const
{ {
if (m_scheme.isEmpty()) if (m_scheme.isEmpty())
return m_root + m_path; return m_path;
if (!m_root.isEmpty()) if (isRelativePath())
return specialPath(SpecialPathComponent::RootPath) + "/" + m_scheme + "/" + hostEncoded(m_host) + m_root + m_path; return specialPath(SpecialPathComponent::RootPath) + "/" + m_scheme + "/" + hostEncoded(m_host) + "/./" + m_path;
return specialPath(SpecialPathComponent::RootPath) + "/" + m_scheme + "/" + hostEncoded(m_host) + "/./" + m_path; return specialPath(SpecialPathComponent::RootPath) + "/" + m_scheme + "/" + hostEncoded(m_host) + m_path;
} }
QString FilePath::toFSPathString() const QString FilePath::toFSPathString() const
@@ -199,7 +199,7 @@ QUrl FilePath::toUrl() const
QUrl url; QUrl url;
url.setScheme(m_scheme); url.setScheme(m_scheme);
url.setHost(m_host); url.setHost(m_host);
url.setPath(m_root + m_path); url.setPath(m_path);
return url; return url;
} }
@@ -209,9 +209,9 @@ QUrl FilePath::toUrl() const
QString FilePath::toUserOutput() const QString FilePath::toUserOutput() const
{ {
if (needsDevice()) { if (needsDevice()) {
if (!m_root.isEmpty()) if (root().empty())
return m_scheme + "://" + hostEncoded(m_host) + path(); return m_scheme + "://" + hostEncoded(m_host) + "/./" + m_path;
return m_scheme + "://" + hostEncoded(m_host) + "/./" + path(); return m_scheme + "://" + hostEncoded(m_host) + m_path;
} }
QString tmp = toString(); QString tmp = toString();
@@ -233,8 +233,9 @@ QString FilePath::nativePath() const
QString FilePath::fileName() const QString FilePath::fileName() const
{ {
const QChar slash = QLatin1Char('/'); // FIXME: Performance
return m_path.mid(m_path.lastIndexOf(slash) + 1); QStringView fp = pathWithoutRoot();
return fp.mid(fp.lastIndexOf('/') + 1).toString();
} }
QString FilePath::fileNameWithPathComponents(int pathComponents) const QString FilePath::fileNameWithPathComponents(int pathComponents) const
@@ -333,12 +334,17 @@ QStringView FilePath::host() const
QString FilePath::path() const QString FilePath::path() const
{ {
return m_root + m_path; return m_path;
}
QStringView FilePath::pathWithoutRoot() const
{
return QStringView{m_path}.mid(m_rootLen);
} }
QStringView FilePath::root() const QStringView FilePath::root() const
{ {
return m_root; return QStringView{m_path}.first(m_rootLen);
} }
void FilePath::setParts(const QStringView scheme, const QStringView host, const QStringView path) void FilePath::setParts(const QStringView scheme, const QStringView host, const QStringView path)
@@ -798,29 +804,29 @@ void FilePath::setRootAndPath(QStringView path, OsType osType)
: std::nullopt; : std::nullopt;
if (path.startsWith(QLatin1String("/./"))) { if (path.startsWith(QLatin1String("/./"))) {
m_root = ""; m_rootLen = 0;
path = path.mid(3); m_path = path.mid(3).toString();
m_path = path.toString();
} else if (windowsDriveAndPath ) { } else if (windowsDriveAndPath ) {
if (windowsDriveAndPath->first.isEmpty()) if (windowsDriveAndPath->first.isEmpty()) {
m_root.clear(); m_rootLen = 0;
else m_path = windowsDriveAndPath->second.toString();
m_root = windowsDriveAndPath->first.toString() + '/'; } else {
m_rootLen = windowsDriveAndPath->first.size() + 1; // 1 for "/"
m_path = windowsDriveAndPath->second.toString(); m_path = windowsDriveAndPath->first.toString() + '/' + windowsDriveAndPath->second.toString();
}
} else if (path.startsWith('/')) { } else if (path.startsWith('/')) {
m_root = "/"; m_rootLen = 1;
m_path = path.mid(1).toString(); m_path = path.toString();
} else if (path.startsWith(':')) { } else if (path.startsWith(':')) {
if (path.length() > 1 && path[1] == '/') { if (path.length() > 1 && path[1] == '/') {
m_root = ":/"; m_rootLen = 2;
m_path = path.mid(2).toString(); m_path = path.toString();
} else { } else {
m_root = ":"; m_rootLen = 1;
m_path = path.mid(1).toString(); m_path = path.toString();
} }
} else { } else {
m_root.clear(); m_rootLen = 0;
m_path = path.toString(); m_path = path.toString();
} }
} }
@@ -857,14 +863,15 @@ void FilePath::setFromStringAndOs(const QString &filename, OsType osType)
return; return;
} }
m_path.clear(); m_path = slash;
m_root = slash; m_rootLen = 1;
return; return;
} }
m_scheme.clear(); m_scheme.clear();
m_host.clear(); m_host.clear();
m_path = filename; m_path = filename;
m_rootLen = 0;
return; return;
} }
} }
@@ -935,8 +942,7 @@ QVariant FilePath::toVariant() const
bool FilePath::operator==(const FilePath &other) const bool FilePath::operator==(const FilePath &other) const
{ {
return QString::compare(m_root, other.m_root, caseSensitivity()) == 0 return QString::compare(m_path, other.m_path, caseSensitivity()) == 0
&& QString::compare(m_path, other.m_path, caseSensitivity()) == 0
&& m_host == other.m_host && m_host == other.m_host
&& m_scheme == other.m_scheme; && m_scheme == other.m_scheme;
} }
@@ -948,8 +954,7 @@ bool FilePath::operator!=(const FilePath &other) const
bool FilePath::operator<(const FilePath &other) const bool FilePath::operator<(const FilePath &other) const
{ {
const int rootCmp = QString::compare(m_root, other.m_root, caseSensitivity()); const int cmp = QString::compare(m_path, other.m_path, caseSensitivity());
const int cmp = rootCmp == 0 ? QString::compare(m_path, other.m_path, caseSensitivity()) : rootCmp;
if (cmp != 0) if (cmp != 0)
return cmp < 0; return cmp < 0;
if (m_host != other.m_host) if (m_host != other.m_host)
@@ -982,7 +987,7 @@ bool FilePath::isChildOf(const FilePath &s) const
{ {
if (s.isEmpty()) if (s.isEmpty())
return false; return false;
if (s.m_root != m_root) if (s.m_rootLen != m_rootLen)
return false; return false;
if (!m_path.startsWith(s.m_path, caseSensitivity())) if (!m_path.startsWith(s.m_path, caseSensitivity()))
return false; return false;
@@ -1019,7 +1024,7 @@ bool FilePath::startsWithDriveLetter() const
{ {
if (needsDevice() || !HostOsInfo::isWindowsHost()) if (needsDevice() || !HostOsInfo::isWindowsHost())
return false; return false;
return m_root.length() >= 2 && m_root.at(0).isLetter() && m_root.at(1) == ':'; return root().size() >= 2 && m_path.at(0).isLetter() && m_path.at(1) == ':';
} }
/*! /*!
@@ -1162,8 +1167,8 @@ FilePath FilePath::onDevice(const FilePath &deviceTemplate) const
FilePath res; FilePath res;
res.m_scheme = deviceTemplate.m_scheme; res.m_scheme = deviceTemplate.m_scheme;
res.m_host = deviceTemplate.m_host; res.m_host = deviceTemplate.m_host;
res.m_root = m_root;
res.m_path = m_path; res.m_path = m_path;
res.m_rootLen = m_rootLen;
res.setRootAndPath(res.mapToDevicePath(), res.osType()); res.setRootAndPath(res.mapToDevicePath(), res.osType());
return res; return res;
} }
@@ -1554,10 +1559,7 @@ FilePath FilePath::operator/(const QString &str) const
*/ */
void FilePath::clear() void FilePath::clear()
{ {
m_path.clear(); *this = {};
m_root.clear();
m_host.clear();
m_scheme.clear();
} }
/*! /*!
@@ -1567,7 +1569,7 @@ void FilePath::clear()
*/ */
bool FilePath::isEmpty() const bool FilePath::isEmpty() const
{ {
return root().isEmpty() && path().isEmpty(); return m_path.isEmpty();
} }
/*! /*!
@@ -1595,7 +1597,7 @@ QString FilePath::shortNativePath() const
*/ */
bool FilePath::isRelativePath() const bool FilePath::isRelativePath() const
{ {
return root().isEmpty(); return m_rootLen == 0;
} }
/*! /*!
@@ -1605,9 +1607,9 @@ bool FilePath::isRelativePath() const
*/ */
FilePath FilePath::resolvePath(const FilePath &tail) const FilePath FilePath::resolvePath(const FilePath &tail) const
{ {
if (!tail.root().isEmpty()) if (tail.isRelativePath())
return tail; return pathAppended(tail.pathWithoutRoot().toString());
return pathAppended(tail.path()); return tail;
} }
/*! /*!

View File

@@ -70,9 +70,9 @@ public:
QStringView scheme() const; QStringView scheme() const;
QStringView host() const; QStringView host() const;
QString path() const; QString path() const;
QStringView root() const;
void setParts(const QStringView scheme, const QStringView host, const QStringView path); void setParts(const QStringView scheme, const QStringView host, const QStringView path);
void setPath(const QStringView path);
QString fileName() const; QString fileName() const;
QString fileNameWithPathComponents(int pathComponents) const; QString fileNameWithPathComponents(int pathComponents) const;
@@ -207,12 +207,14 @@ private:
void setRootAndPath(QStringView path, OsType osType); void setRootAndPath(QStringView path, OsType osType);
void setFromString(const QString &filepath); void setFromString(const QString &filepath);
void setFromStringAndOs(const QString &filepath, OsType osType); void setFromStringAndOs(const QString &filepath, OsType osType);
QStringView root() const;
[[nodiscard]] QString mapToDevicePath() const; [[nodiscard]] QString mapToDevicePath() const;
[[nodiscard]] QStringView pathWithoutRoot() const;
QString m_scheme; QString m_scheme;
QString m_host; // May contain raw slashes. QString m_host; // May contain raw slashes.
QString m_path; QString m_path; // Includes the root bits
QString m_root; int m_rootLen = 0;
}; };
inline size_t qHash(const Utils::FilePath &a, uint seed = 0) inline size_t qHash(const Utils::FilePath &a, uint seed = 0)