--nextPart3833703.OtbTieZC0A Content-Type: multipart/mixed; boundary="Boundary-01=_fAV2HWbf+VyjLRK" Content-Transfer-Encoding: 7bit Content-Disposition: inline --Boundary-01=_fAV2HWbf+VyjLRK Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Content-Disposition: inline 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 t= he > 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=20 Ralf's original code because there's at least one file engine that is queri= ed=20 first (the resource file engine). =2D-=20 =C2=A0 Thiago Macieira =C2=A0- =C2=A0thiago (AT) macieira.info - thiago (AT= ) kde.org =C2=A0 =C2=A0 PGP/GPG: 0x6EF45358; fingerprint: =C2=A0 =C2=A0 E067 918B B660 DBD1 105C =C2=A0966C 33F5 F005 6EF4 5358 --Boundary-01=_fAV2HWbf+VyjLRK Content-Type: text/x-diff; charset="utf-8"; name="0001-Fixes-QDir-isAbsolutePath-somewhat-faster.patch" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="0001-Fixes-QDir-isAbsolutePath-somewhat-faster.patch" =46rom 7b960efa4645fd5f3558734bf86a20d93936e646 Mon Sep 17 00:00:00 2001 =46rom: Thiago Macieira 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 =3D "//depot/qt/4.4/": change =3D 301646] =2D-- src/corelib/io/qabstractfileengine.cpp | 62 +++++++++++++++++++++++-----= =2D-- 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/qabstr= actfileengine.cpp index 81081fe..468f1eb 100644 =2D-- a/src/corelib/io/qabstractfileengine.cpp +++ b/src/corelib/io/qabstractfileengine.cpp @@ -123,29 +123,20 @@ QAbstractFileEngineHandler::~QAbstractFileEngineHandl= er() \sa QAbstractFileEngine::create() */ =20 =2D/*! =2D Creates and returns a QAbstractFileEngine suitable for processing \a =2D fileName. =2D =2D You should not need to call this function; use QFile, QFileInfo or =2D QDir directly instead. =20 =2D If you reimplemnt this function, it should only return file =2D engines that knows how to handle \a fileName; otherwise, it should =2D return 0. =2D =2D \sa QAbstractFileEngineHandler =2D*/ =2DQAbstractFileEngine *QAbstractFileEngine::create(const QString &fileName) +static QAbstractFileEngine *createSpecialized(const QString &fileName) { =2D QMutexLocker locker(fileEngineHandlerMutex()); =2D // check for registered handlers that can load the file for (int i =3D 0; i < fileEngineHandlers()->size(); i++) { if (QAbstractFileEngine *ret =3D fileEngineHandlers()->at(i)->crea= te(fileName)) return ret; } =20 + 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 =3D fileName.indexOf(QLatin1Char(':')); @@ -156,7 +147,7 @@ QAbstractFileEngine *QAbstractFileEngine::create(const = QString &fileName) for (int i =3D 0; i < paths.count(); i++) { QString path =3D paths.at(i); path.append(fileNameWithoutPrefix); =2D QAbstractFileEngine *engine =3D create(path); + QAbstractFileEngine *engine =3D QAbstractFileEngine::creat= e(path); if (engine && (engine->fileFlags(QAbstractFileEngine::Flag= sMask) & QAbstractFileEngine::ExistsFlag)) { return engine; } @@ -166,6 +157,45 @@ QAbstractFileEngine *QAbstractFileEngine::create(const= QString &fileName) } #endif =20 + return 0; // not a search path or no match +} + +QAbstractFileEngine *QAbstractFileEnginePrivate::createNonDefault(const QS= tring &fileName) +{ + QMutexLocker locker(fileEngineHandlerMutex()); + QAbstractFileEngine *engine; + + engine =3D createSpecialized(fileName); + if (engine) + return engine; + + engine =3D 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 =3D 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/qabstr= actfileengine_p.h index f57e141..a4e4794 100644 =2D-- a/src/corelib/io/qabstractfileengine_p.h +++ b/src/corelib/io/qabstractfileengine_p.h @@ -44,6 +44,9 @@ public: =20 QAbstractFileEngine *q_ptr; Q_DECLARE_PUBLIC(QAbstractFileEngine) + + + static QAbstractFileEngine *createNonDefault(const QString &fileName); }; =20 QT_END_NAMESPACE diff --git a/src/corelib/io/qdir.cpp b/src/corelib/io/qdir.cpp index 5fab886..60c3e1b 100644 =2D-- a/src/corelib/io/qdir.cpp +++ b/src/corelib/io/qdir.cpp @@ -2130,7 +2130,7 @@ QString QDir::cleanPath(const QString &path) =20 bool QDir::isRelativePath(const QString &path) { =2D return QFileInfo(path).isRelative(); + return QFileInfo::isRelative(path); } =20 /*! diff --git a/src/corelib/io/qfileinfo.cpp b/src/corelib/io/qfileinfo.cpp index 5346525..db0d79c 100644 =2D-- a/src/corelib/io/qfileinfo.cpp +++ b/src/corelib/io/qfileinfo.cpp @@ -676,6 +676,23 @@ QFileInfo::isRelative() const return d->data->fileEngine->isRelativePath(); } =20 +/*! + Returns true if \a path is relative; returns false if it is + absolute. + + \sa isAbsolute() +*/ + +bool QFileInfo::isRelative(const QString &path) +{ + QAbstractFileEngine *engine =3D QAbstractFileEnginePrivate::createNonD= efault(path); + if (engine) { + bool result =3D engine->isRelativePath(); + delete engine; + return result; + } + return QFSFileEngine::isRelativePath(path); +} =20 /*! Converts the file's path to an absolute path if it is not already in t= hat form. diff --git a/src/corelib/io/qfileinfo.h b/src/corelib/io/qfileinfo.h index 78655b0..beb8e1a 100644 =2D-- a/src/corelib/io/qfileinfo.h +++ b/src/corelib/io/qfileinfo.h @@ -102,6 +102,9 @@ public: bool caching() const; void setCaching(bool on); =20 + static bool isRelative(const QString &path); + static inline bool isAbsolute(const QString &path) { return !isRelativ= e(path); } + #ifdef QT3_SUPPORT enum Permission { ReadOwner =3D QFile::ReadOwner, WriteOwner =3D QFile::WriteOwner, = ExeOwner =3D QFile::ExeOwner, diff --git a/src/corelib/io/qfsfileengine.cpp b/src/corelib/io/qfsfileengin= e.cpp index 2e6ddfb..4d33e58 100644 =2D-- a/src/corelib/io/qfsfileengine.cpp +++ b/src/corelib/io/qfsfileengine.cpp @@ -836,4 +836,22 @@ bool QFSFileEngine::supportsExtension(Extension extens= ion) const return false; } =20 +bool QFSFileEngine::isRelativePath(const QString &path) +{ + if (path.size() =3D=3D 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() >=3D 2 + && ((path.at(0).isLetter() && path.at(1) =3D=3D QLatin1Ch= ar(':')) + || (path.at(0) =3D=3D QLatin1Char('/') && path.at(1) = =3D=3D QLatin1Char('/'))))); // drive, e.g. a: +#else + return path[0] !=3D QLatin1Char('/'); +#endif +} + + + QT_END_NAMESPACE diff --git a/src/corelib/io/qfsfileengine.h b/src/corelib/io/qfsfileengine.h index 9fa9e81..fb322da 100644 =2D-- 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(); =2D + static bool isRelativePath(const QString &path); + static inline bool isAbsolutePath(const QString &path) { return !isRel= ativePath(path); } protected: QFSFileEngine(QFSFileEnginePrivate &dd); }; diff --git a/src/corelib/io/qfsfileengine_unix.cpp b/src/corelib/io/qfsfile= engine_unix.cpp index 024b6c3..0e73eb2 100644 =2D-- 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); =2D int len =3D d->filePath.length(); =2D if (len =3D=3D 0) =2D return true; =2D return d->filePath[0] !=3D QLatin1Char('/'); + return isRelativePath(d->filePath); } =20 uint QFSFileEngine::ownerId(FileOwner own) const diff --git a/src/corelib/io/qfsfileengine_win.cpp b/src/corelib/io/qfsfilee= ngine_win.cpp index 37b6e92..20b18ce 100644 =2D-- 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); =2D return !(d->filePath.startsWith(QLatin1Char('/')) =2D || (d->filePath.length() >=3D 2 =2D && ((d->filePath.at(0).isLetter() && d->filePath.at(1) =3D=3D QL= atin1Char(':')) =2D || (d->filePath.at(0) =3D=3D QLatin1Char('/') && d->filePath.at(= 1) =3D=3D QLatin1Char('/'))))); // drive, e.g. a: + return isRelativePath(d->filePath); } =20 /*! =2D-=20 1.5.4.rc4.25.g81cc --Boundary-01=_fAV2HWbf+VyjLRK-- --nextPart3833703.OtbTieZC0A Content-Type: application/pgp-signature; name=signature.asc Content-Description: This is a digitally signed message part. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.8 (GNU/Linux) iD8DBQBH2VAfM/XwBW70U1gRAj65AKCpt6wdz8duHIzpie0r6NCNzMGN4wCePs8/ Pon/ymtzeoDiq3AtK3wE8IE= =TrdR -----END PGP SIGNATURE----- --nextPart3833703.OtbTieZC0A--