[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-core-devel
Subject:    Re: 'lightweight' QDir::isAbsolutePath replacement ?
From:       Thiago Macieira <thiago () kde ! org>
Date:       2008-03-13 16:02:39
Message-ID: 200803131702.39712.thiago () kde ! org
[Download RAW message or body]

[Attachment #2 (multipart/mixed)]


On Tuesday 11 March 2008 14:01:47 Thiago Macieira wrote:
> So I don't think we can escape the creation of a file engine. The best I
> can do is go through the attempts to create, but in case of fallback to the
> default file engine, not create it.
>
> I'll work on this a little more.

Here's the patch it will appear in tonight's snapshot. It can't be as fast as 
Ralf's original code because there's at least one file engine that is queried 
first (the resource file engine).

-- 
   Thiago Macieira   -   thiago (AT) macieira.info - thiago (AT) kde.org
      PGP/GPG: 0x6EF45358; fingerprint:
      E067 918B B660 DBD1 105C   966C 33F5 F005 6EF4 5358

["0001-Fixes-QDir-isAbsolutePath-somewhat-faster.patch" (text/x-diff)]

From 7b960efa4645fd5f3558734bf86a20d93936e646 Mon Sep 17 00:00:00 2001
From: Thiago Macieira <tjmaciei@trolltech.com>
Date: Thu, 13 Mar 2008 16:52:20 +0100
Subject: [PATCH] Fixes:    QDir::isAbsolutePath somewhat faster
 Task:     None, original patch submitted by Ralf Habacker
 RevBy:    Andreas
 AutoTest: all existing pass
 Details:  QDir::isAbsolutePath created a QFileInfo temporary
 (which creates a QFSFileEngine) then calls a function in
 QFSFileEngine that the first one or two characters in the
 string.
 Improvements:
  - don't create the QFileInfo temporary
  - only create a QAbstractFileEngine object if it's not QFSFileEngine.

[git-p4: depot-paths = "//depot/qt/4.4/": change = 301646]
---
 src/corelib/io/qabstractfileengine.cpp |   62 +++++++++++++++++++++++--------
 src/corelib/io/qabstractfileengine_p.h |    3 ++
 src/corelib/io/qdir.cpp                |    2 +-
 src/corelib/io/qfileinfo.cpp           |   17 +++++++++
 src/corelib/io/qfileinfo.h             |    3 ++
 src/corelib/io/qfsfileengine.cpp       |   18 +++++++++
 src/corelib/io/qfsfileengine.h         |    3 +-
 src/corelib/io/qfsfileengine_unix.cpp  |    5 +--
 src/corelib/io/qfsfileengine_win.cpp   |    5 +--
 9 files changed, 92 insertions(+), 26 deletions(-)

diff --git a/src/corelib/io/qabstractfileengine.cpp \
b/src/corelib/io/qabstractfileengine.cpp index 81081fe..468f1eb 100644
--- a/src/corelib/io/qabstractfileengine.cpp
+++ b/src/corelib/io/qabstractfileengine.cpp
@@ -123,29 +123,20 @@ QAbstractFileEngineHandler::~QAbstractFileEngineHandler()
     \sa QAbstractFileEngine::create()
 */
 
-/*!
-    Creates and returns a QAbstractFileEngine suitable for processing \a
-    fileName.
-
-    You should not need to call this function; use QFile, QFileInfo or
-    QDir directly instead.
 
-    If you reimplemnt this function, it should only return file
-    engines that knows how to handle \a fileName; otherwise, it should
-    return 0.
-
-    \sa QAbstractFileEngineHandler
-*/
-QAbstractFileEngine *QAbstractFileEngine::create(const QString &fileName)
+static QAbstractFileEngine *createSpecialized(const QString &fileName)
 {
-    QMutexLocker locker(fileEngineHandlerMutex());
-
     // check for registered handlers that can load the file
     for (int i = 0; i < fileEngineHandlers()->size(); i++) {
         if (QAbstractFileEngine *ret = \
fileEngineHandlers()->at(i)->create(fileName))  return ret;
     }
 
+    return 0;                   // cannot find a specialized file engine
+}
+
+static QAbstractFileEngine *createForSearchPath(const QString &fileName)
+{
 #ifdef QT_BUILD_CORE_LIB
     if (!fileName.startsWith(QLatin1Char('/'))) {
         int prefixSeparator = fileName.indexOf(QLatin1Char(':'));
@@ -156,7 +147,7 @@ QAbstractFileEngine *QAbstractFileEngine::create(const QString \
&fileName)  for (int i = 0; i < paths.count(); i++) {
                 QString path = paths.at(i);
                 path.append(fileNameWithoutPrefix);
-                QAbstractFileEngine *engine = create(path);
+                QAbstractFileEngine *engine = QAbstractFileEngine::create(path);
                 if (engine && (engine->fileFlags(QAbstractFileEngine::FlagsMask) & \
QAbstractFileEngine::ExistsFlag)) {  return engine;
                 }
@@ -166,6 +157,45 @@ QAbstractFileEngine *QAbstractFileEngine::create(const QString \
&fileName)  }
 #endif
 
+    return 0;                   // not a search path or no match
+}
+
+QAbstractFileEngine *QAbstractFileEnginePrivate::createNonDefault(const QString \
&fileName) +{
+    QMutexLocker locker(fileEngineHandlerMutex());
+    QAbstractFileEngine *engine;
+
+    engine = createSpecialized(fileName);
+    if (engine)
+        return engine;
+
+    engine = createForSearchPath(fileName);
+    if (engine)
+        return engine;
+
+    return 0;
+}
+
+/*!
+    Creates and returns a QAbstractFileEngine suitable for processing \a
+    fileName.
+
+    You should not need to call this function; use QFile, QFileInfo or
+    QDir directly instead.
+
+    If you reimplemnt this function, it should only return file
+    engines that knows how to handle \a fileName; otherwise, it should
+    return 0.
+
+    \sa QAbstractFileEngineHandler
+*/
+QAbstractFileEngine *QAbstractFileEngine::create(const QString &fileName)
+{
+    QAbstractFileEngine *engine;
+    engine = QAbstractFileEnginePrivate::createNonDefault(fileName);
+    if (engine)
+        return engine;
+
     // fall back to regular file engine
     return new QFSFileEngine(fileName);
 }
diff --git a/src/corelib/io/qabstractfileengine_p.h \
b/src/corelib/io/qabstractfileengine_p.h index f57e141..a4e4794 100644
--- a/src/corelib/io/qabstractfileengine_p.h
+++ b/src/corelib/io/qabstractfileengine_p.h
@@ -44,6 +44,9 @@ public:
 
     QAbstractFileEngine *q_ptr;
     Q_DECLARE_PUBLIC(QAbstractFileEngine)
+
+
+    static QAbstractFileEngine *createNonDefault(const QString &fileName);
 };
 
 QT_END_NAMESPACE
diff --git a/src/corelib/io/qdir.cpp b/src/corelib/io/qdir.cpp
index 5fab886..60c3e1b 100644
--- a/src/corelib/io/qdir.cpp
+++ b/src/corelib/io/qdir.cpp
@@ -2130,7 +2130,7 @@ QString QDir::cleanPath(const QString &path)
 
 bool QDir::isRelativePath(const QString &path)
 {
-    return QFileInfo(path).isRelative();
+    return QFileInfo::isRelative(path);
 }
 
 /*!
diff --git a/src/corelib/io/qfileinfo.cpp b/src/corelib/io/qfileinfo.cpp
index 5346525..db0d79c 100644
--- a/src/corelib/io/qfileinfo.cpp
+++ b/src/corelib/io/qfileinfo.cpp
@@ -676,6 +676,23 @@ QFileInfo::isRelative() const
     return d->data->fileEngine->isRelativePath();
 }
 
+/*!
+    Returns true if \a path is relative; returns false if it is
+    absolute.
+
+    \sa isAbsolute()
+*/
+
+bool QFileInfo::isRelative(const QString &path)
+{
+    QAbstractFileEngine *engine = \
QAbstractFileEnginePrivate::createNonDefault(path); +    if (engine) {
+        bool result = engine->isRelativePath();
+        delete engine;
+        return result;
+    }
+    return QFSFileEngine::isRelativePath(path);
+}
 
 /*!
     Converts the file's path to an absolute path if it is not already in that form.
diff --git a/src/corelib/io/qfileinfo.h b/src/corelib/io/qfileinfo.h
index 78655b0..beb8e1a 100644
--- a/src/corelib/io/qfileinfo.h
+++ b/src/corelib/io/qfileinfo.h
@@ -102,6 +102,9 @@ public:
     bool caching() const;
     void setCaching(bool on);
 
+    static bool isRelative(const QString &path);
+    static inline bool isAbsolute(const QString &path) { return !isRelative(path); }
+
 #ifdef QT3_SUPPORT
     enum Permission {
         ReadOwner = QFile::ReadOwner, WriteOwner = QFile::WriteOwner, ExeOwner = \
                QFile::ExeOwner,
diff --git a/src/corelib/io/qfsfileengine.cpp b/src/corelib/io/qfsfileengine.cpp
index 2e6ddfb..4d33e58 100644
--- a/src/corelib/io/qfsfileengine.cpp
+++ b/src/corelib/io/qfsfileengine.cpp
@@ -836,4 +836,22 @@ bool QFSFileEngine::supportsExtension(Extension extension) const
     return false;
 }
 
+bool QFSFileEngine::isRelativePath(const QString &path)
+{
+    if (path.size() == 0)
+        return true;
+#ifdef Q_OS_WIN
+    // ### This code looks wrong
+    // "a:" and "c:foo" are relative, aren't they?
+    return !(path.startsWith(QLatin1Char('/'))
+             || (path.length() >= 2
+                 && ((path.at(0).isLetter() && path.at(1) == QLatin1Char(':'))
+                     || (path.at(0) == QLatin1Char('/') && path.at(1) == \
QLatin1Char('/'))))); // drive, e.g. a: +#else
+    return path[0] != QLatin1Char('/');
+#endif
+}
+
+
+
 QT_END_NAMESPACE
diff --git a/src/corelib/io/qfsfileengine.h b/src/corelib/io/qfsfileengine.h
index 9fa9e81..fb322da 100644
--- a/src/corelib/io/qfsfileengine.h
+++ b/src/corelib/io/qfsfileengine.h
@@ -77,7 +77,8 @@ public:
     static QString rootPath();
     static QString tempPath();
     static QFileInfoList drives();
-
+    static bool isRelativePath(const QString &path);
+    static inline bool isAbsolutePath(const QString &path) { return \
!isRelativePath(path); }  protected:
     QFSFileEngine(QFSFileEnginePrivate &dd);
 };
diff --git a/src/corelib/io/qfsfileengine_unix.cpp \
b/src/corelib/io/qfsfileengine_unix.cpp index 024b6c3..0e73eb2 100644
--- a/src/corelib/io/qfsfileengine_unix.cpp
+++ b/src/corelib/io/qfsfileengine_unix.cpp
@@ -758,10 +758,7 @@ QString QFSFileEngine::fileName(FileName file) const
 bool QFSFileEngine::isRelativePath() const
 {
     Q_D(const QFSFileEngine);
-    int len = d->filePath.length();
-    if (len == 0)
-        return true;
-    return d->filePath[0] != QLatin1Char('/');
+    return isRelativePath(d->filePath);
 }
 
 uint QFSFileEngine::ownerId(FileOwner own) const
diff --git a/src/corelib/io/qfsfileengine_win.cpp \
b/src/corelib/io/qfsfileengine_win.cpp index 37b6e92..20b18ce 100644
--- a/src/corelib/io/qfsfileengine_win.cpp
+++ b/src/corelib/io/qfsfileengine_win.cpp
@@ -1871,10 +1871,7 @@ QString QFSFileEngine::fileName(FileName file) const
 bool QFSFileEngine::isRelativePath() const
 {
     Q_D(const QFSFileEngine);
-    return !(d->filePath.startsWith(QLatin1Char('/'))
-        || (d->filePath.length() >= 2
-        && ((d->filePath.at(0).isLetter() && d->filePath.at(1) == QLatin1Char(':'))
-        || (d->filePath.at(0) == QLatin1Char('/') && d->filePath.at(1) == \
QLatin1Char('/')))));                // drive, e.g. a: +    return \
isRelativePath(d->filePath);  }
 
 /*!
-- 
1.5.4.rc4.25.g81cc


["signature.asc" (application/pgp-signature)]

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic