From 206f49020bce11e142c4290b6655ac7c15592b43 Mon Sep 17 00:00:00 2001 From: Prasanth Ullattil Date: Fri, 17 Sep 2010 15:04:27 +0200 Subject: Differntiate different types of absolute paths on windows. QFileSystemEntry now differentiates between various types of absolute paths on Windows and Symbian. The new behavior is shown the table below. Anybody who uses this class should NOT treat that !isRelative() == isAbsolute(). The differentiation is puerly for internal use by the windows and symbian implementations of QFileSystemEngine. |============================================| |Filename isRelative isAbsolute | |============================================| | Somefile.txt 1 0 | | Some/file.txt 1 0 | | a:Somefile.txt 0 0 | | /Somefile.txt 0 0 | | a:/somefile.txt 0 1 | | //abc/somefile.txt 0 1 | |============================================| Reviewed-by: Joao Reviewed-by: Shane Kearns --- src/corelib/io/qfilesystemengine_symbian.cpp | 2 +- src/corelib/io/qfilesystemengine_win.cpp | 20 ++++----- src/corelib/io/qfilesystementry.cpp | 30 ++++++++++---- src/corelib/io/qfilesystementry_p.h | 4 +- .../auto/qfilesystementry/tst_qfilesystementry.cpp | 47 ++++++++++++++++++---- 5 files changed, 74 insertions(+), 29 deletions(-) diff --git a/src/corelib/io/qfilesystemengine_symbian.cpp b/src/corelib/io/qfilesystemengine_symbian.cpp index 02b4c48..b4f0f88 100644 --- a/src/corelib/io/qfilesystemengine_symbian.cpp +++ b/src/corelib/io/qfilesystemengine_symbian.cpp @@ -114,7 +114,7 @@ QFileSystemEntry QFileSystemEngine::absoluteName(const QFileSystemEntry &entry) const bool isDriveRelative = (orig.size() > 2 && orig.at(1).unicode() == ':' && orig.at(2).unicode() != '/'); const bool isDirty = (orig.contains(QLatin1String("/../")) || orig.contains(QLatin1String("/./")) || orig.endsWith(QLatin1String("/..")) || orig.endsWith(QLatin1String("/."))); - const bool isAbsolute = entry.isAbsolute(); + const bool isAbsolute = !entry.isRelative(); if (isAbsolute && !(needsDrive || isDriveLetter || isDriveRelative || isDirty)) return entry; diff --git a/src/corelib/io/qfilesystemengine_win.cpp b/src/corelib/io/qfilesystemengine_win.cpp index 8526cf2..119ed7c 100644 --- a/src/corelib/io/qfilesystemengine_win.cpp +++ b/src/corelib/io/qfilesystemengine_win.cpp @@ -545,18 +545,18 @@ QFileSystemEntry QFileSystemEngine::absoluteName(const QFileSystemEntry &entry) if (!entry.isRelative()) { #if !defined(Q_OS_WINCE) - if (entry.filePath().startsWith(QLatin1Char('/')) || // It's a absolute path to the current drive, so \a.txt -> Z:\a.txt - entry.filePath().size() == 2 || // It's a drive letter that needs to get a working dir appended - (entry.filePath().size() > 2 && entry.filePath().at(2) != QLatin1Char('/')) || // It's a drive-relative path, so Z:a.txt -> Z:\currentpath\a.txt - entry.filePath().contains(QLatin1String("/../")) || entry.filePath().contains(QLatin1String("/./")) || - entry.filePath().endsWith(QLatin1String("/..")) || entry.filePath().endsWith(QLatin1String("/."))) - { - ret = QDir::fromNativeSeparators(nativeAbsoluteFilePath(entry.filePath())); - } else -#endif - { + if (entry.isAbsolute() + && !entry.filePath().contains(QLatin1String("/../")) + && !entry.filePath().contains(QLatin1String("/./")) + && !entry.filePath().endsWith(QLatin1String("/..")) + && !entry.filePath().endsWith(QLatin1String("/."))) { ret = entry.filePath(); + } else { + ret = QDir::fromNativeSeparators(nativeAbsoluteFilePath(entry.filePath())); } +#else + ret = entry.filePath(); +#endif } else { ret = QDir::cleanPath(QDir::currentPath() + QLatin1Char('/') + entry.filePath()); } diff --git a/src/corelib/io/qfilesystementry.cpp b/src/corelib/io/qfilesystementry.cpp index 733a226..10b59fd 100644 --- a/src/corelib/io/qfilesystementry.cpp +++ b/src/corelib/io/qfilesystementry.cpp @@ -225,17 +225,33 @@ QString QFileSystemEntry::completeSuffix() const return m_filePath.mid(qMax((qint16)0, m_lastSeparator) + m_firstDotInFileName + 1); } +#if defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN) +bool QFileSystemEntry::isRelative() const +{ + resolveFilePath(); + return (m_filePath.isEmpty() || (!m_filePath.isEmpty() && (m_filePath[0].unicode() != '/') + && (!(m_filePath.length() >= 2 && m_filePath[1].unicode() == ':')))); +} + bool QFileSystemEntry::isAbsolute() const { resolveFilePath(); - return (!m_filePath.isEmpty() && (m_filePath[0].unicode() == '/') -#if defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN) - || (m_filePath.length() >= 2 - && ((m_filePath[0].isLetter() && m_filePath[1].unicode() == ':') - || (m_filePath.at(0) == QLatin1Char('/') && m_filePath.at(1) == QLatin1Char('/')))) -#endif - ); + return (!m_filePath.isEmpty() && ((m_filePath.length() >= 3 + && (m_filePath[0].isLetter() && m_filePath[1].unicode() == ':' && m_filePath[2].unicode() == '/')) + || (m_filePath.length() >= 2 && (m_filePath.at(0) == QLatin1Char('/') && m_filePath.at(1) == QLatin1Char('/'))))); +} +#else +bool QFileSystemEntry::isRelative() const +{ + return !isAbsolute(); +} + +bool QFileSystemEntry::isAbsolute() const +{ + resolveFilePath(); + return (!m_filePath.isEmpty() && (m_filePath[0].unicode() == '/')); } +#endif #if defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN) bool QFileSystemEntry::isDriveRoot() const diff --git a/src/corelib/io/qfilesystementry_p.h b/src/corelib/io/qfilesystementry_p.h index 5a41782..7a9c2a5 100644 --- a/src/corelib/io/qfilesystementry_p.h +++ b/src/corelib/io/qfilesystementry_p.h @@ -88,9 +88,7 @@ public: QString suffix() const; QString completeSuffix() const; bool isAbsolute() const; - bool isRelative() const { - return !isAbsolute(); - } + bool isRelative() const; #if defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN) bool isDriveRoot() const; diff --git a/tests/auto/qfilesystementry/tst_qfilesystementry.cpp b/tests/auto/qfilesystementry/tst_qfilesystementry.cpp index 49afab6..4375f99 100644 --- a/tests/auto/qfilesystementry/tst_qfilesystementry.cpp +++ b/tests/auto/qfilesystementry/tst_qfilesystementry.cpp @@ -64,6 +64,10 @@ private slots: void baseName(); void completeBaseName_data(); void completeBaseName(); +#if defined(WIN_STUFF) + void absoluteOrRelative_data(); + void absoluteOrRelative(); +#endif }; #if defined(WIN_STUFF) @@ -78,6 +82,7 @@ void tst_QFileSystemEntry::getSetCheck_data() QTest::addColumn("suffix"); QTest::addColumn("completeSuffix"); QTest::addColumn("absolute"); + QTest::addColumn("relative"); QString absPrefix = QLatin1String("\\\\?\\"); QString relPrefix = absPrefix @@ -88,33 +93,33 @@ void tst_QFileSystemEntry::getSetCheck_data() << QString("A:\\home\\qt\\in\\a\\dir.tar.gz") << absPrefix + QString("A:\\home\\qt\\in\\a\\dir.tar.gz") << "A:/home/qt/in/a/dir.tar.gz" - << "dir.tar.gz" << "dir" << "dir.tar" << "gz" << "tar.gz" << true; + << "dir.tar.gz" << "dir" << "dir.tar" << "gz" << "tar.gz" << true << false; QTest::newRow("relative") << QString("in\\a\\dir.tar.gz") << relPrefix + QString("in\\a\\dir.tar.gz") << "in/a/dir.tar.gz" - << "dir.tar.gz" << "dir" << "dir.tar" << "gz" << "tar.gz" << false; + << "dir.tar.gz" << "dir" << "dir.tar" << "gz" << "tar.gz" << false <("path"); + QTest::addColumn("isAbsolute"); + QTest::addColumn("isRelative"); + + QTest::newRow("data0") << "file.tar" << false << true; + QTest::newRow("data1") << "/path/file/file.tar.gz" << false << false; + QTest::newRow("data1") << "C:path/file/file.tar.gz" << false << false; + QTest::newRow("data3") << "C:/path/file" << true << false; + QTest::newRow("data3") << "//machine/share" << true << false; +} + +void tst_QFileSystemEntry::absoluteOrRelative() +{ + QFETCH(QString, path); + QFETCH(bool, isAbsolute); + QFETCH(bool, isRelative); + + QFileSystemEntry fi(path); + QCOMPARE(fi.isAbsolute(), isAbsolute); + QCOMPARE(fi.isRelative(), isRelative); +} +#endif QTEST_MAIN(tst_QFileSystemEntry) #include -- cgit v0.12