From e02ce5c0e02ad7a830f11d281b2641362a1df2c0 Mon Sep 17 00:00:00 2001 From: Ivailo Monev Date: Sat, 11 Jan 2020 02:29:34 +0000 Subject: [PATCH] cleanup file engine, notably the Qt resource part this is fixes QTBUG-11223, I also would like to take it step further and make the resources requests prefixed with "qrc:/" so that the check when to use QResourceFileEngine is even more reliable but that will require backwards incompatible change so it will be done in future release. Signed-off-by: Ivailo Monev --- README | 2 +- src/core/io/qabstractfileengine.cpp | 75 ++------ src/core/io/qabstractfileengine_p.h | 2 - src/core/io/qdir.cpp | 89 +-------- src/core/io/qdir.h | 4 - src/core/io/qdiriterator.cpp | 2 +- src/core/io/qfileinfo_p.h | 9 +- src/core/io/qfilesystemengine.cpp | 96 ---------- src/core/io/qfilesystemengine_p.h | 3 - src/core/io/qfsfileengine.cpp | 16 -- src/core/io/qfsfileengine.h | 2 - src/core/io/qresource.cpp | 189 ++++--------------- src/core/io/qresource.h | 4 +- src/core/io/qresource_p.h | 3 - src/tools/rcc/rcc.cpp | 10 +- tests/auto/qdir/searchdir/subdir1/picker.png | 1 - tests/auto/qdir/searchdir/subdir2/picker.png | 1 - tests/auto/qdir/tst_qdir.cpp | 106 ----------- tests/auto/qfileinfo/tst_qfileinfo.cpp | 4 +- 19 files changed, 71 insertions(+), 547 deletions(-) delete mode 100644 tests/auto/qdir/searchdir/subdir1/picker.png delete mode 100644 tests/auto/qdir/searchdir/subdir2/picker.png diff --git a/README b/README index 25d6744d8..bcf6f71cf 100644 --- a/README +++ b/README @@ -79,7 +79,7 @@ QTBUG-25114, QTBUG-24672, QTBUG-23524 (WIP), QTBUG-56088, QTBUG-42189, QTBUG-39285, QTBUG-18173, QTBUG-28968, QTBUG-34336, QTBUG-40974, QTBUG-44286, QTBUG-12564, QTBUG-20028, QTBUG-71967, QTBUG-70956, QTBUG-71446, QTBUG-61307, QTBUG-27287, QTBUG-25143, QTBUG-22833, QTBUG-57399, QTBUG-59159, QTBUG-15773, -QTBUG-70506, QTBUG-46054 +QTBUG-70506, QTBUG-46054, QTBUG-11223 Unless you use QMake and QDoc porting to Katie or even supporting it along with Qt4 in the same codebase is trivial and requires only minor changes because diff --git a/src/core/io/qabstractfileengine.cpp b/src/core/io/qabstractfileengine.cpp index a093eb721..2420fa0dd 100644 --- a/src/core/io/qabstractfileengine.cpp +++ b/src/core/io/qabstractfileengine.cpp @@ -39,6 +39,9 @@ // built-in handlers #include "qfsfileengine.h" #include "qdiriterator.h" +#ifndef QT_BOOTSTRAPPED +# include "qresource_p.h" +#endif #include "qfilesystementry_p.h" #include "qfilesystemmetadata_p.h" @@ -90,25 +93,6 @@ QT_BEGIN_NAMESPACE \sa QAbstractFileEngine, QAbstractFileEngine::create() */ -static bool qt_file_engine_handlers_in_use = false; - -/* - All application-wide handlers are stored in this list. The mutex must be - acquired to ensure thread safety. - */ -Q_GLOBAL_STATIC_WITH_ARGS(QReadWriteLock, fileEngineHandlerMutex, (QReadWriteLock::Recursive)) -static bool qt_abstractfileenginehandlerlist_shutDown = false; -class QAbstractFileEngineHandlerList : public QList -{ -public: - ~QAbstractFileEngineHandlerList() - { - QWriteLocker locker(fileEngineHandlerMutex()); - qt_abstractfileenginehandlerlist_shutDown = true; - } -}; -Q_GLOBAL_STATIC(QAbstractFileEngineHandlerList, fileEngineHandlers) - /*! Constructs a file handler and registers it with Qt. Once created this handler's create() function will be called (along with all the other @@ -120,9 +104,6 @@ Q_GLOBAL_STATIC(QAbstractFileEngineHandlerList, fileEngineHandlers) */ QAbstractFileEngineHandler::QAbstractFileEngineHandler() { - QWriteLocker locker(fileEngineHandlerMutex()); - qt_file_engine_handlers_in_use = true; - fileEngineHandlers()->prepend(this); } /*! @@ -131,36 +112,6 @@ QAbstractFileEngineHandler::QAbstractFileEngineHandler() */ QAbstractFileEngineHandler::~QAbstractFileEngineHandler() { - QWriteLocker locker(fileEngineHandlerMutex()); - // Remove this handler from the handler list only if the list is valid. - if (!qt_abstractfileenginehandlerlist_shutDown) { - QAbstractFileEngineHandlerList *handlers = fileEngineHandlers(); - handlers->removeOne(this); - if (handlers->isEmpty()) - qt_file_engine_handlers_in_use = false; - } -} - -/* - \ìnternal - - Handles calls to custom file engine handlers. -*/ -QAbstractFileEngine *qt_custom_file_engine_handler_create(const QString &path) -{ - if (qt_file_engine_handlers_in_use) { - QReadLocker locker(fileEngineHandlerMutex()); - - // check for registered handlers that can load the file - QAbstractFileEngineHandlerList *handlers = fileEngineHandlers(); - for (int i = 0; i < handlers->size(); i++) { - QAbstractFileEngine *engine = handlers->at(i)->create(path); - if (engine) - return engine; - } - } - - return 0; } /*! @@ -191,17 +142,17 @@ QAbstractFileEngine *qt_custom_file_engine_handler_create(const QString &path) */ QAbstractFileEngine *QAbstractFileEngine::create(const QString &fileName) { - QFileSystemEntry entry(fileName); - QFileSystemMetaData metaData; - QAbstractFileEngine *engine = QFileSystemEngine::resolveEntryAndCreateLegacyEngine(entry, metaData); - -#ifndef QT_NO_FSFILEENGINE - if (!engine) - // fall back to regular file engine - return new QFSFileEngine(entry.filePath()); +#ifndef QT_BOOTSTRAPPED + // check if a resource file is being handled + if(fileName.startsWith(":/")) + return new QResourceFileEngine(fileName); +#endif +#ifndef QT_NO_FSFILEENGINE + // fall back to regular file engine + return new QFSFileEngine(fileName); +#else + return Q_NULLPTR; #endif - - return engine; } /*! diff --git a/src/core/io/qabstractfileengine_p.h b/src/core/io/qabstractfileengine_p.h index 50e3267cf..d49ef45f4 100644 --- a/src/core/io/qabstractfileengine_p.h +++ b/src/core/io/qabstractfileengine_p.h @@ -65,8 +65,6 @@ public: Q_DECLARE_PUBLIC(QAbstractFileEngine) }; -QAbstractFileEngine *qt_custom_file_engine_handler_create(const QString &path); - QT_END_NAMESPACE #endif // QABSTRACTFILEENGINE_P_H diff --git a/src/core/io/qdir.cpp b/src/core/io/qdir.cpp index 63b2b038e..b18399cd2 100644 --- a/src/core/io/qdir.cpp +++ b/src/core/io/qdir.cpp @@ -60,15 +60,6 @@ QT_BEGIN_NAMESPACE -#ifndef QT_BOOTSTRAPPED -struct QCoreGlobalData { - QMap dirSearchPaths; - QReadWriteLock dirSearchPathsLock; -}; - -Q_GLOBAL_STATIC(QCoreGlobalData, globalData) -#endif - //************* QDirPrivate QDirPrivate::QDirPrivate(const QString &path, const QStringList &nameFilters_, QDir::SortFlags sort_, QDir::Filters filters_) : QSharedData() @@ -99,7 +90,7 @@ QDirPrivate::QDirPrivate(const QDirPrivate ©) , nameFilters(copy.nameFilters) , sort(copy.sort) , filters(copy.filters) - , fileEngine(0) + , fileEngine(Q_NULLPTR) , fileListsInitialized(false) , dirEntry(copy.dirEntry) , metaData(copy.metaData) @@ -155,7 +146,7 @@ inline void QDirPrivate::setPath(const QString &path) p.truncate(p.length() - 1); } - dirEntry = QFileSystemEntry(p); + dirEntry = QFileSystemEntry(QDir::fromNativeSeparators(path)); metaData.clear(); initFileEngine(); clearFileLists(); @@ -316,7 +307,7 @@ inline void QDirPrivate::initFileLists(const QDir &dir) const inline void QDirPrivate::initFileEngine() { delete fileEngine; - fileEngine = QFileSystemEngine::resolveEntryAndCreateLegacyEngine(dirEntry, metaData); + fileEngine = QAbstractFileEngine::create(dirEntry.filePath()); } /*! @@ -855,80 +846,6 @@ void QDir::setNameFilters(const QStringList &nameFilters) d->nameFilters = nameFilters; } -#ifndef QT_BOOTSTRAPPED -/*! - \since 4.3 - - Sets or replaces Qt's search paths for file names with the prefix \a prefix - to \a searchPaths. - - To specify a prefix for a file name, prepend the prefix followed by a single - colon (e.g., "images:undo.png", "xmldocs:books.xml"). \a prefix can only - contain letters or numbers (e.g., it cannot contain a colon, nor a slash). - - Qt uses this search path to locate files with a known prefix. The search - path entries are tested in order, starting with the first entry. - - \snippet doc/src/snippets/code/src_corelib_io_qdir.cpp 8 - - File name prefix must be at least 2 characters long to avoid conflicts with - Windows drive letters. - - Search paths may contain paths to \l{The Qt Resource System}. -*/ -void QDir::setSearchPaths(const QString &prefix, const QStringList &searchPaths) -{ - if (Q_UNLIKELY(prefix.length() < 2)) { - qWarning("QDir::setSearchPaths: Prefix must be longer than 1 character"); - return; - } - - for (int i = 0; i < prefix.count(); ++i) { - if (!prefix.at(i).isLetterOrNumber()) { - qWarning("QDir::setSearchPaths: Prefix can only contain letters or numbers"); - return; - } - } - - QWriteLocker lock(&globalData()->dirSearchPathsLock); - if (searchPaths.isEmpty()) { - globalData()->dirSearchPaths.remove(prefix); - } else { - globalData()->dirSearchPaths.insert(prefix, searchPaths); - } -} - -/*! - \since 4.3 - - Adds \a path to the search path for \a prefix. - - \sa setSearchPaths() -*/ -void QDir::addSearchPath(const QString &prefix, const QString &path) -{ - if (path.isEmpty()) - return; - - QWriteLocker lock(&globalData()->dirSearchPathsLock); - globalData()->dirSearchPaths[prefix] += path; -} - -/*! - \since 4.3 - - Returns the search paths for \a prefix. - - \sa setSearchPaths(), addSearchPath() -*/ -QStringList QDir::searchPaths(const QString &prefix) -{ - QReadLocker lock(&globalData()->dirSearchPathsLock); - return globalData()->dirSearchPaths.value(prefix); -} - -#endif // QT_BOOTSTRAPPED - /*! Returns the value set by setFilter() */ diff --git a/src/core/io/qdir.h b/src/core/io/qdir.h index c94cd2e01..fa4b33387 100644 --- a/src/core/io/qdir.h +++ b/src/core/io/qdir.h @@ -112,10 +112,6 @@ public: QString absolutePath() const; QString canonicalPath() const; - static void setSearchPaths(const QString &prefix, const QStringList &searchPaths); - static void addSearchPath(const QString &prefix, const QString &path); - static QStringList searchPaths(const QString &prefix); - QString dirName() const; QString filePath(const QString &fileName) const; QString absoluteFilePath(const QString &fileName) const; diff --git a/src/core/io/qdiriterator.cpp b/src/core/io/qdiriterator.cpp index c8742d19c..915e3229b 100644 --- a/src/core/io/qdiriterator.cpp +++ b/src/core/io/qdiriterator.cpp @@ -163,7 +163,7 @@ QDirIteratorPrivate::QDirIteratorPrivate(const QFileSystemEntry &entry, const QS #endif QFileSystemMetaData metaData; if (resolveEngine) - engine.reset(QFileSystemEngine::resolveEntryAndCreateLegacyEngine(dirEntry, metaData)); + engine.reset(QAbstractFileEngine::create(dirEntry.filePath())); QFileInfo fileInfo(new QFileInfoPrivate(dirEntry, metaData)); // Populate fields for hasNext() and next() diff --git a/src/core/io/qfileinfo_p.h b/src/core/io/qfileinfo_p.h index 51de8588f..df4e9e5e9 100644 --- a/src/core/io/qfileinfo_p.h +++ b/src/core/io/qfileinfo_p.h @@ -69,7 +69,7 @@ public: : QSharedData(copy), fileEntry(copy.fileEntry), metaData(copy.metaData), - fileEngine(QFileSystemEngine::resolveEntryAndCreateLegacyEngine(fileEntry, metaData)), + fileEngine(QAbstractFileEngine::create(fileEntry.filePath())), #ifndef QT_NO_FSFILEENGINE isDefaultConstructed(false), #else @@ -78,8 +78,9 @@ public: cache_enabled(copy.cache_enabled), fileFlags(0), cachedFlags(0), fileSize(0) {} inline QFileInfoPrivate(const QString &file) - : fileEntry(file), - fileEngine(QFileSystemEngine::resolveEntryAndCreateLegacyEngine(fileEntry, metaData)), + : QSharedData(), + fileEntry(file), + fileEngine(QAbstractFileEngine::create(file)), #ifndef QT_NO_FSFILEENGINE isDefaultConstructed(false), #else @@ -93,7 +94,7 @@ public: : QSharedData(), fileEntry(file), metaData(data), - fileEngine(QFileSystemEngine::resolveEntryAndCreateLegacyEngine(fileEntry, metaData)), + fileEngine(QAbstractFileEngine::create(fileEntry.filePath())), isDefaultConstructed(false), cache_enabled(true), fileFlags(0), cachedFlags(0), fileSize(0) { diff --git a/src/core/io/qfilesystemengine.cpp b/src/core/io/qfilesystemengine.cpp index e1bfcfe8d..184ac1c71 100644 --- a/src/core/io/qfilesystemengine.cpp +++ b/src/core/io/qfilesystemengine.cpp @@ -42,102 +42,6 @@ QT_BEGIN_NAMESPACE -static inline bool _q_checkEntry(QFileSystemEntry &entry, QFileSystemMetaData &data, bool resolvingEntry) -{ - if (resolvingEntry) { - if (!QFileSystemEngine::fillMetaData(entry, data, QFileSystemMetaData::ExistsAttribute) - || !data.exists()) { - data.clear(); - return false; - } - } - - return true; -} - -static inline bool _q_checkEntry(QAbstractFileEngine *&engine, bool resolvingEntry) -{ - if (resolvingEntry) { - if (!(engine->fileFlags(QAbstractFileEngine::FlagsMask) & QAbstractFileEngine::ExistsFlag)) { - delete engine; - engine = 0; - return false; - } - } - - return true; -} - -static bool _q_resolveEntryAndCreateLegacyEngine_recursive(QFileSystemEntry &entry, QFileSystemMetaData &data, - QAbstractFileEngine *&engine, bool resolvingEntry = false) -{ - QString const &filePath = entry.filePath(); - if ((engine = qt_custom_file_engine_handler_create(filePath))) - return _q_checkEntry(engine, resolvingEntry); - -#ifndef QT_BOOTSTRAPPED - for (int prefixSeparator = 0; prefixSeparator < filePath.size(); ++prefixSeparator) { - QChar const ch = filePath[prefixSeparator]; - if (ch == QLatin1Char('/')) - break; - - if (ch == QLatin1Char(':')) { - if (prefixSeparator == 0) { - engine = new QResourceFileEngine(filePath); - return _q_checkEntry(engine, resolvingEntry); - } - - if (prefixSeparator == 1) - break; - - const QStringList &paths = QDir::searchPaths(filePath.left(prefixSeparator)); - for (int i = 0; i < paths.count(); i++) { - entry = QFileSystemEntry(QDir::cleanPath(paths.at(i) + QLatin1Char('/') + filePath.mid(prefixSeparator + 1))); - // Recurse! - if (_q_resolveEntryAndCreateLegacyEngine_recursive(entry, data, engine, true)) - return true; - } - - // entry may have been clobbered at this point. - return false; - } - - // There's no need to fully validate the prefix here. Consulting the - // unicode tables could be expensive and validation is already - // performed in QDir::setSearchPaths. - // - // if (!ch.isLetterOrNumber()) - // break; - } -#endif // QT_BOOTSTRAPPED - - return _q_checkEntry(entry, data, resolvingEntry); -} - -/*! - \internal - - Resolves the \a entry (see QDir::searchPaths) and returns an engine for - it, but never a QFSFileEngine. - - Returns a file engine that can be used to access the entry. Returns 0 if - QFileSystemEngine API should be used to query and interact with the file - system object. -*/ -QAbstractFileEngine *QFileSystemEngine::resolveEntryAndCreateLegacyEngine( - QFileSystemEntry &entry, QFileSystemMetaData &data) { - QFileSystemEntry copy = entry; - QAbstractFileEngine *engine = 0; - - if (_q_resolveEntryAndCreateLegacyEngine_recursive(copy, data, engine)) - // Reset entry to resolved copy. - entry = copy; - else - data.clear(); - - return engine; -} - //these unix functions are in this file, because they are shared by symbian port //for open C file handles. #ifdef Q_OS_UNIX diff --git a/src/core/io/qfilesystemengine_p.h b/src/core/io/qfilesystemengine_p.h index db45ced64..30ed6d6db 100644 --- a/src/core/io/qfilesystemengine_p.h +++ b/src/core/io/qfilesystemengine_p.h @@ -87,9 +87,6 @@ public: static bool setCurrentPath(const QFileSystemEntry &entry); static QFileSystemEntry currentPath(); - - static QAbstractFileEngine *resolveEntryAndCreateLegacyEngine(QFileSystemEntry &entry, - QFileSystemMetaData &data); }; QT_END_NAMESPACE diff --git a/src/core/io/qfsfileengine.cpp b/src/core/io/qfsfileengine.cpp index b5aabe9d3..5e43ef78c 100644 --- a/src/core/io/qfsfileengine.cpp +++ b/src/core/io/qfsfileengine.cpp @@ -693,24 +693,8 @@ QAbstractFileEngine::Iterator *QFSFileEngine::beginEntryList(QDir::Filters filte { return new QFSFileEngineIterator(filters, filterNames); } - -/*! - \internal -*/ -QAbstractFileEngine::Iterator *QFSFileEngine::endEntryList() -{ - return 0; -} #endif -/*! - \internal -*/ -QStringList QFSFileEngine::entryList(QDir::Filters filters, const QStringList &filterNames) const -{ - return QAbstractFileEngine::entryList(filters, filterNames); -} - /*! \reimp */ diff --git a/src/core/io/qfsfileengine.h b/src/core/io/qfsfileengine.h index e03cadade..0bf1c7714 100644 --- a/src/core/io/qfsfileengine.h +++ b/src/core/io/qfsfileengine.h @@ -70,7 +70,6 @@ public: bool setSize(qint64 size); bool caseSensitive() const; bool isRelativePath() const; - QStringList entryList(QDir::Filters filters, const QStringList &filterNames) const; FileFlags fileFlags(FileFlags type) const; bool setPermissions(uint perms); QString fileName(FileName file) const; @@ -82,7 +81,6 @@ public: #ifndef QT_NO_FILESYSTEMITERATOR Iterator *beginEntryList(QDir::Filters filters, const QStringList &filterNames); - Iterator *endEntryList(); #endif qint64 read(char *data, qint64 maxlen); diff --git a/src/core/io/qresource.cpp b/src/core/io/qresource.cpp index 9c943b4b9..13653f119 100644 --- a/src/core/io/qresource.cpp +++ b/src/core/io/qresource.cpp @@ -129,8 +129,6 @@ Q_GLOBAL_STATIC_WITH_ARGS(QMutex, resourceMutex, (QMutex::Recursive)) typedef QList ResourceList; Q_GLOBAL_STATIC(ResourceList, resourceList) -Q_GLOBAL_STATIC(QStringList, resourceSearchPaths) - /*! \class QResource \brief The QResource class provides an interface for reading directly from resources. @@ -153,8 +151,7 @@ Q_GLOBAL_STATIC(QStringList, resourceSearchPaths) A QResource can either be loaded with an absolute path, either treated as a file system rooted with a \c{/} character, or in resource notation - rooted with a \c{:} character. A relative resource can also be opened - which will be found in the list of paths returned by QDir::searchPaths(). + rooted with a \c{:} character. A QResource that is representing a file will have data backing it, this data can possibly be compressed, in which case qUncompress() must be @@ -249,7 +246,7 @@ QResourcePrivate::load(const QString &file) size = 0; compressed = false; } - } else if(res->isContainer(node) != container) { + } else if(Q_UNLIKELY(res->isContainer(node) != container)) { qWarning("QResourceInfo: Resource [%s] has both data and children!", file.toLatin1().constData()); } res->ref.ref(); @@ -272,29 +269,12 @@ QResourcePrivate::ensureInitialized() const if(!related.isEmpty()) return; QResourcePrivate *that = const_cast(this); - if(fileName == QLatin1String(":")) - that->fileName += QLatin1Char('/'); that->absoluteFilePath = fileName; - if(!that->absoluteFilePath.startsWith(QLatin1Char(':'))) - that->absoluteFilePath.prepend(QLatin1Char(':')); + if(!that->absoluteFilePath.startsWith(QLatin1String(":/"))) + that->absoluteFilePath.prepend(QLatin1String(":/")); - QString path = fileName; - if(path.startsWith(QLatin1Char(':'))) - path = path.mid(1); - - if(path.startsWith(QLatin1Char('/'))) { - that->load(path); - } else { - QMutexLocker lock(resourceMutex()); - QStringList searchPaths = *resourceSearchPaths(); - searchPaths << QLatin1String(""); - for(int i = 0; i < searchPaths.size(); ++i) { - const QString searchPath(searchPaths.at(i) + QLatin1Char('/') + path); - if(that->load(searchPath)) { - that->absoluteFilePath = QLatin1Char(':') + searchPath; - break; - } - } + if(fileName.startsWith(QLatin1String(":/"))) { + that->load(fileName.mid(1)); } } @@ -308,14 +288,12 @@ QResourcePrivate::ensureChildren() const QString path = absoluteFilePath, k; if(path.startsWith(QLatin1Char(':'))) path = path.mid(1); - QSet kids; QString cleaned = QDir::cleanPath(path); for(int i = 0; i < related.size(); ++i) { QResourceRoot *res = related.at(i); if(res->mappingRootSubdir(path, &k) && !k.isEmpty()) { - if(!kids.contains(k)) { - children += k; - kids.insert(k); + if(!children.contains(k)) { + children.append(k); } } else { const int node = res->findNode(cleaned); @@ -323,9 +301,8 @@ QResourcePrivate::ensureChildren() const QStringList related_children = res->children(node); for(int kid = 0; kid < related_children.size(); ++kid) { k = related_children.at(kid); - if(!kids.contains(k)) { - children += k; - kids.insert(k); + if(!children.contains(k)) { + children.append(k); } } } @@ -337,7 +314,7 @@ QResourcePrivate::ensureChildren() const Constructs a QResource pointing to \a file. \a locale is used to load a specific localization of a resource data. - \sa QFileInfo, QDir::searchPaths(), setFileName(), setLocale() + \sa QFileInfo, setFileName(), setLocale() */ QResource::QResource(const QString &file, const QLocale &locale) : d_ptr(new QResourcePrivate()) @@ -381,9 +358,7 @@ QLocale QResource::locale() const } /*! - Sets a QResource to point to \a file. \a file can either be absolute, - in which case it is opened directly, if relative then the file will be - tried to be found in QDir::searchPaths(). + Sets a QResource to point to \a file. \a file should be absolute. \sa absoluteFilePath() */ @@ -410,8 +385,7 @@ QString QResource::fileName() const } /*! - Returns the real path that this QResource represents, if the resource - was found via the QDir::searchPaths() it will be indicated in the path. + Returns the real path that this QResource represents. \sa fileName() */ @@ -517,48 +491,6 @@ QStringList QResource::children() const return d->children; } -/*! - \obsolete - - Use QDir::addSearchPath() with a prefix instead. - - Adds \a path to the search paths searched in to find resources that are - not specified with an absolute path. The \a path must be an absolute - path (start with \c{/}). - - The default search path is to search only in the root (\c{:/}). The last - path added will be consulted first upon next QResource creation. -*/ -void -QResource::addSearchPath(const QString &path) -{ - if (!path.startsWith(QLatin1Char('/'))) { - qWarning("QResource::addSearchPath: Search paths must be absolute (start with /) [%s]", - path.toLocal8Bit().data()); - return; - } - QMutexLocker lock(resourceMutex()); - resourceSearchPaths()->prepend(path); -} - -/*! - \obsolete - - Use QDir::searchPaths() instead. - - Returns the current search path list. This list is consulted when - creating a relative resource. - - \sa QDir::addSearchPath() QDir::setSearchPaths() -*/ - -QStringList -QResource::searchPaths() -{ - QMutexLocker lock(resourceMutex()); - return *resourceSearchPaths(); -} - inline int QResourceRoot::hash(int node) const { if(!node) //root @@ -805,7 +737,7 @@ Q_CORE_EXPORT bool qRegisterResourceData(int version, const unsigned char *tree, const unsigned char *name, const unsigned char *data) { QMutexLocker lock(resourceMutex()); - if(version == 0x01 && resourceList()) { + if(version == Q_RCC_OUTPUT_REVISION && resourceList()) { bool found = false; QResourceRoot res(tree, name, data); for(int i = 0; i < resourceList()->size(); ++i) { @@ -828,7 +760,7 @@ Q_CORE_EXPORT bool qUnregisterResourceData(int version, const unsigned char *tre const unsigned char *name, const unsigned char *data) { QMutexLocker lock(resourceMutex()); - if(version == 0x01 && resourceList()) { + if(version == Q_RCC_OUTPUT_REVISION && resourceList()) { QResourceRoot res(tree, name, data); for(int i = 0; i < resourceList()->size(); ) { if(*resourceList()->at(i) == res) { @@ -885,7 +817,7 @@ public: (b[offset+2] << 8) + (b[offset+3] << 0); offset += 4; - if(version == 0x01) { + if(version == Q_RCC_OUTPUT_REVISION) { buffer = b; setSource(b+tree_offset, b+name_offset, b+data_offset); return true; @@ -909,12 +841,9 @@ public: bool registerSelf(const QString &f) { QFile file(f); - if (!file.exists()) - return false; - unsigned int data_len = file.size(); - uchar *data = new uchar[data_len]; - if (file.open(QIODevice::ReadOnly)) { + unsigned int data_len = file.size(); + uchar *data = new uchar[data_len]; if (data_len != (uint)file.read((char*)data, data_len)) { delete [] data; data = 0; @@ -929,17 +858,6 @@ public: } }; -static QString qt_resource_fixResourceRoot(QString r) { - if(!r.isEmpty()) { - if(r.startsWith(QLatin1Char(':'))) - r = r.mid(1); - if(!r.isEmpty()) - r = QDir::cleanPath(r); - } - return r; -} - - /*! \fn bool QResource::registerResource(const QString &rccFileName, const QString &mapRoot) @@ -953,14 +871,13 @@ static QString qt_resource_fixResourceRoot(QString r) { bool QResource::registerResource(const QString &rccFilename, const QString &resourceRoot) { - QString r = qt_resource_fixResourceRoot(resourceRoot); - if(!r.isEmpty() && r[0] != QLatin1Char('/')) { - qWarning("QDir::registerResource: Registering a resource [%s] must be rooted in an absolute path (start with /) [%s]", + if(Q_UNLIKELY(!resourceRoot.startsWith(QLatin1String(":/")))) { + qWarning("QResource::registerResource: Registering a resource [%s] must be rooted in an absolute path (start with :/) [%s]", rccFilename.toLocal8Bit().data(), resourceRoot.toLocal8Bit().data()); return false; } - QDynamicFileResourceRoot *root = new QDynamicFileResourceRoot(r); + QDynamicFileResourceRoot *root = new QDynamicFileResourceRoot(resourceRoot); if(root->registerSelf(rccFilename)) { root->ref.ref(); QMutexLocker lock(resourceMutex()); @@ -985,15 +902,13 @@ QResource::registerResource(const QString &rccFilename, const QString &resourceR bool QResource::unregisterResource(const QString &rccFilename, const QString &resourceRoot) { - QString r = qt_resource_fixResourceRoot(resourceRoot); - QMutexLocker lock(resourceMutex()); ResourceList *list = resourceList(); for(int i = 0; i < list->size(); ++i) { QResourceRoot *res = list->at(i); if(res->type() == QResourceRoot::Resource_File) { - QDynamicFileResourceRoot *root = reinterpret_cast(res); - if(root->mappingFile() == rccFilename && root->mappingRoot() == r) { + QDynamicFileResourceRoot *root = reinterpret_cast(res); + if(root->mappingFile() == rccFilename && root->mappingRoot() == resourceRoot) { resourceList()->removeAt(i); if(!root->ref.deref()) { delete root; @@ -1001,7 +916,7 @@ QResource::unregisterResource(const QString &rccFilename, const QString &resourc } return false; } - } + } } return false; } @@ -1024,14 +939,13 @@ QResource::unregisterResource(const QString &rccFilename, const QString &resourc bool QResource::registerResource(const uchar *rccData, const QString &resourceRoot) { - QString r = qt_resource_fixResourceRoot(resourceRoot); - if(!r.isEmpty() && r[0] != QLatin1Char('/')) { - qWarning("QDir::registerResource: Registering a resource [%p] must be rooted in an absolute path (start with /) [%s]", + if(Q_UNLIKELY(!resourceRoot.startsWith(QLatin1String(":/")))) { + qWarning("QResource::registerResource: Registering a resource [%p] must be rooted in an absolute path (start with :/) [%s]", rccData, resourceRoot.toLocal8Bit().data()); return false; } - QDynamicBufferResourceRoot *root = new QDynamicBufferResourceRoot(r); + QDynamicBufferResourceRoot *root = new QDynamicBufferResourceRoot(resourceRoot); if(root->registerSelf(rccData)) { root->ref.ref(); QMutexLocker lock(resourceMutex()); @@ -1056,23 +970,21 @@ QResource::registerResource(const uchar *rccData, const QString &resourceRoot) bool QResource::unregisterResource(const uchar *rccData, const QString &resourceRoot) { - QString r = qt_resource_fixResourceRoot(resourceRoot); - QMutexLocker lock(resourceMutex()); ResourceList *list = resourceList(); for(int i = 0; i < list->size(); ++i) { QResourceRoot *res = list->at(i); if(res->type() == QResourceRoot::Resource_Buffer) { - QDynamicBufferResourceRoot *root = reinterpret_cast(res); - if(root->mappingBuffer() == rccData && root->mappingRoot() == r) { + QDynamicBufferResourceRoot *root = reinterpret_cast(res); + if(root->mappingBuffer() == rccData && root->mappingRoot() == resourceRoot) { resourceList()->removeAt(i); if(!root->ref.deref()) { delete root; return true; } - return false; + return false; } - } + } } return false; } @@ -1107,11 +1019,6 @@ bool QResourceFileEngine::setSize(qint64) return false; } -QStringList QResourceFileEngine::entryList(QDir::Filters filters, const QStringList &filterNames) const -{ - return QAbstractFileEngine::entryList(filters, filterNames); -} - bool QResourceFileEngine::caseSensitive() const { return true; @@ -1123,11 +1030,7 @@ QResourceFileEngine::QResourceFileEngine(const QString &file) : Q_D(QResourceFileEngine); d->resource.setFileName(file); if(d->resource.isCompressed() && d->resource.size()) { -#ifndef QT_NO_COMPRESS d->uncompressed = qFastUncompress(reinterpret_cast(d->resource.data()), d->resource.size()); -#else - Q_ASSERT(!"QResourceFileEngine::open: Qt built without support for compression"); -#endif } } @@ -1144,7 +1047,7 @@ void QResourceFileEngine::setFileName(const QString &file) bool QResourceFileEngine::open(QIODevice::OpenMode flags) { Q_D(QResourceFileEngine); - if (d->resource.fileName().isEmpty()) { + if (Q_UNLIKELY(d->resource.fileName().isEmpty())) { qWarning("QResourceFileEngine::open: Missing file name"); return false; } @@ -1280,20 +1183,18 @@ bool QResourceFileEngine::setPermissions(uint) QString QResourceFileEngine::fileName(FileName file) const { Q_D(const QResourceFileEngine); + const QString filepath = d->resource.fileName(); if(file == BaseName) { - int slash = d->resource.fileName().lastIndexOf(QLatin1Char('/')); - if (slash == -1) - return d->resource.fileName(); - return d->resource.fileName().mid(slash + 1); - } else if(file == PathName || file == AbsolutePathName) { - const QString path = (file == AbsolutePathName) ? d->resource.absoluteFilePath() : d->resource.fileName(); - const int slash = path.lastIndexOf(QLatin1Char('/')); + int slash = filepath.lastIndexOf(QLatin1Char('/')); if (slash == -1) - return QLatin1String(":"); - else if (slash <= 1) + return filepath; + return filepath.mid(slash + 1); + } else if(file == PathName || file == AbsolutePathName) { + const QString path = (file == AbsolutePathName) ? d->resource.absoluteFilePath() : filepath; + const int slash = path.lastIndexOf(QLatin1Char('/')); + if (slash <= 1 || slash == path.size()) return QLatin1String(":/"); return path.left(slash); - } else if(file == CanonicalName || file == CanonicalPathName) { const QString absoluteFilePath = d->resource.absoluteFilePath(); if(file == CanonicalPathName) { @@ -1303,7 +1204,7 @@ QString QResourceFileEngine::fileName(FileName file) const } return absoluteFilePath; } - return d->resource.fileName(); + return filepath; } bool QResourceFileEngine::isRelativePath() const @@ -1336,14 +1237,6 @@ QAbstractFileEngine::Iterator *QResourceFileEngine::beginEntryList(QDir::Filters return new QResourceFileEngineIterator(filters, filterNames); } -/*! - \internal -*/ -QAbstractFileEngine::Iterator *QResourceFileEngine::endEntryList() -{ - return 0; -} - bool QResourceFileEngine::extension(Extension extension, const ExtensionOption *option, ExtensionReturn *output) { Q_D(QResourceFileEngine); diff --git a/src/core/io/qresource.h b/src/core/io/qresource.h index 39daf0a4c..d1429e744 100644 --- a/src/core/io/qresource.h +++ b/src/core/io/qresource.h @@ -41,6 +41,7 @@ QT_BEGIN_HEADER QT_BEGIN_NAMESPACE +#define Q_RCC_OUTPUT_REVISION 0x02 class QResourcePrivate; @@ -63,9 +64,6 @@ public: qint64 size() const; const uchar *data() const; - static void addSearchPath(const QString &path); - static QStringList searchPaths(); - static bool registerResource(const QString &rccFilename, const QString &resourceRoot=QString()); static bool unregisterResource(const QString &rccFilename, const QString &resourceRoot=QString()); diff --git a/src/core/io/qresource_p.h b/src/core/io/qresource_p.h index 69ed2265c..aab76a414 100644 --- a/src/core/io/qresource_p.h +++ b/src/core/io/qresource_p.h @@ -84,8 +84,6 @@ public: virtual bool setSize(qint64 size); - virtual QStringList entryList(QDir::Filters filters, const QStringList &filterNames) const; - virtual bool caseSensitive() const; virtual FileFlags fileFlags(FileFlags type) const; @@ -100,7 +98,6 @@ public: virtual QDateTime fileTime(FileTime time) const; virtual Iterator *beginEntryList(QDir::Filters filters, const QStringList &filterNames); - virtual Iterator *endEntryList(); bool extension(Extension extension, const ExtensionOption *option = Q_NULLPTR, ExtensionReturn *output = Q_NULLPTR); bool supportsExtension(Extension extension) const; diff --git a/src/tools/rcc/rcc.cpp b/src/tools/rcc/rcc.cpp index 467f09c33..dca323d52 100644 --- a/src/tools/rcc/rcc.cpp +++ b/src/tools/rcc/rcc.cpp @@ -145,7 +145,7 @@ RCCFileInfo::~RCCFileInfo() QString RCCFileInfo::resourceName() const { - QString resource = m_name; + QString resource = (m_name.isEmpty() ? QLatin1String("/") : m_name); for (RCCFileInfo *p = m_parent; p; p = p->m_parent) resource = resource.prepend(p->m_name + QLatin1Char('/')); return QLatin1Char(':') + resource; @@ -735,7 +735,7 @@ bool RCCResourceLibrary::writeHeader() writeString("\n**\n"); writeString("** WARNING! All changes made in this file will be lost!\n"); writeString( "*****************************************************************************/\n\n"); - writeString("#include \n\n"); + writeString("#include \n\n"); } else if (m_format == Binary) { writeString("qres"); writeNumber4(0); @@ -907,7 +907,7 @@ bool RCCResourceLibrary::writeInitializer() { if (m_format == C_Code) { QByteArray initLatin = m_initName.toLatin1(); - QByteArray resourceDataString = "\n (0x01, qt_resource_struct_" + initLatin + + QByteArray resourceDataString = "\n (Q_RCC_OUTPUT_REVISION, qt_resource_struct_" + initLatin + ", qt_resource_name_" + initLatin + ", qt_resource_data_" + initLatin + ");\n"; //write("\nQT_BEGIN_NAMESPACE\n"); @@ -958,10 +958,10 @@ bool RCCResourceLibrary::writeInitializer() } else if (m_format == Binary) { int i = 4; char *p = m_out.data(); - p[i++] = 0; // 0x01 + p[i++] = 0; // Q_RCC_OUTPUT_REVISION p[i++] = 0; p[i++] = 0; - p[i++] = 1; + p[i++] = 2; p[i++] = (m_treeOffset >> 24) & 0xff; p[i++] = (m_treeOffset >> 16) & 0xff; diff --git a/tests/auto/qdir/searchdir/subdir1/picker.png b/tests/auto/qdir/searchdir/subdir1/picker.png deleted file mode 100644 index 52eee4fe2..000000000 --- a/tests/auto/qdir/searchdir/subdir1/picker.png +++ /dev/null @@ -1 +0,0 @@ -mostly empty diff --git a/tests/auto/qdir/searchdir/subdir2/picker.png b/tests/auto/qdir/searchdir/subdir2/picker.png deleted file mode 100644 index 52eee4fe2..000000000 --- a/tests/auto/qdir/searchdir/subdir2/picker.png +++ /dev/null @@ -1 +0,0 @@ -mostly empty diff --git a/tests/auto/qdir/tst_qdir.cpp b/tests/auto/qdir/tst_qdir.cpp index 309c4e440..940a12ef2 100644 --- a/tests/auto/qdir/tst_qdir.cpp +++ b/tests/auto/qdir/tst_qdir.cpp @@ -139,11 +139,6 @@ private slots: void nativeSeparators(); - void searchPaths(); - void searchPaths_data(); - - void entryListWithSearchPaths(); - void longFileName_data(); void longFileName(); @@ -1130,107 +1125,6 @@ void tst_QDir::nativeSeparators() QCOMPARE(QDir::fromNativeSeparators(QLatin1String("\\")), QString("\\")); } -void tst_QDir::searchPaths_data() -{ - QTest::addColumn("filename"); - QTest::addColumn("searchPathPrefixes"); - QTest::addColumn("searchPaths"); - QTest::addColumn("expectedAbsolutePath"); - - QString srcdir = SRCDIR; - if (srcdir.isEmpty()) - srcdir = QDir::currentPath(); - else - srcdir.chop(1); // remove ending slash - QString searchDir = srcdir + "/searchdir"; - - // sanity - QTest::newRow("nopath") << "picker.png" << QString() << QString() << QString(); - QTest::newRow("emptysearchpath") << "subdir1/picker.png" << QString() << QString() << QString(); - QTest::newRow("searchpathwithoutprefix") << SRCDIR "searchdir/subdir1/picker.png" << QString("searchpath") << QString("searchdir") << (searchDir+"/subdir1/picker.png"); - - // new - QTest::newRow("novalidsearchpath") << "searchpath:subdir1/picker.png" << QString() << QString() << QString(); - QTest::newRow("invalidsearchpath") << "searchpath:subdir1/picker.png" << QString("invalid") << QString("invalid") << QString(); - QTest::newRow("onlyvalidsearchpath") << "searchpath:subdir1/picker.png" << QString("searchpath") << QString(SRCDIR "searchdir") << (searchDir+"/subdir1/picker.png"); - QTest::newRow("validandinvalidsearchpath") << "searchpath:subdir1/picker.png" << QString("invalid;searchpath") << QString("invalid;" SRCDIR "searchdir") << (searchDir+"/subdir1/picker.png"); - QTest::newRow("precedence1") << "searchpath:picker.png" << QString("invalid;searchpath") << QString("invalid;" SRCDIR "searchdir/subdir1," SRCDIR "searchdir/subdir2") << (searchDir+"/subdir1/picker.png"); - QTest::newRow("precedence2") << "searchpath:picker.png" << QString("invalid;searchpath") << QString("invalid;" SRCDIR "searchdir/subdir2," SRCDIR "searchdir/subdir1") << (searchDir+"/subdir2/picker.png"); - QTest::newRow("precedence3") << "searchpath2:picker.png" << QString("searchpath1;searchpath2") << QString(SRCDIR "searchdir/subdir1;" SRCDIR "searchdir/subdir2") << (searchDir+"/subdir2/picker.png"); - - // re -} - -void tst_QDir::searchPaths() -{ - QFETCH(QString, filename); - QFETCH(QString, searchPathPrefixes); - QStringList searchPathPrefixList = searchPathPrefixes.split(";", QString::SkipEmptyParts); - QFETCH(QString, searchPaths); - QStringList searchPathsList = searchPaths.split(";", QString::SkipEmptyParts); - QFETCH(QString, expectedAbsolutePath); - bool exists = !expectedAbsolutePath.isEmpty(); - - for (int i = 0; i < searchPathPrefixList.count(); ++i) { - QDir::setSearchPaths(searchPathPrefixList.at(i), searchPathsList.at(i).split(",")); - } - for (int i = 0; i < searchPathPrefixList.count(); ++i) { - QVERIFY(QDir::searchPaths(searchPathPrefixList.at(i)) == searchPathsList.at(i).split(",")); - } - - QCOMPARE(QFile(filename).exists(), exists); - QCOMPARE(QFileInfo(filename).exists(), exists); - - if (exists) { - QCOMPARE(QFileInfo(filename).absoluteFilePath(), expectedAbsolutePath); - } - - for (int i = 0; i < searchPathPrefixList.count(); ++i) { - QDir::setSearchPaths(searchPathPrefixList.at(i), QStringList()); - } - for (int i = 0; i < searchPathPrefixList.count(); ++i) { - QVERIFY(QDir::searchPaths(searchPathPrefixList.at(i)).isEmpty()); - } - - for (int i = 0; i < searchPathPrefixList.count(); ++i) { - foreach (QString path, searchPathsList.at(i).split(",")) { - QDir::addSearchPath(searchPathPrefixList.at(i), path); - } - } - for (int i = 0; i < searchPathPrefixList.count(); ++i) { - QVERIFY(QDir::searchPaths(searchPathPrefixList.at(i)) == searchPathsList.at(i).split(",")); - } - - QCOMPARE(QFile(filename).exists(), exists); - QCOMPARE(QFileInfo(filename).exists(), exists); - - if (exists) { - QCOMPARE(QFileInfo(filename).absoluteFilePath(), expectedAbsolutePath); - } - - for (int i = 0; i < searchPathPrefixList.count(); ++i) { - QDir::setSearchPaths(searchPathPrefixList.at(i), QStringList()); - } - for (int i = 0; i < searchPathPrefixList.count(); ++i) { - QVERIFY(QDir::searchPaths(searchPathPrefixList.at(i)).isEmpty()); - } -} - -void tst_QDir::entryListWithSearchPaths() -{ - QDir realDir(":/tst_qdir/resources/entryList"); - QVERIFY(realDir.exists()); - QVERIFY(!realDir.entryList().isEmpty()); - QVERIFY(realDir.entryList().contains("file3.data")); - - QDir::setSearchPaths("searchpath", QStringList(":/tst_qdir/resources")); - QDir dir("searchpath:entryList/"); - QCOMPARE(dir.path(), QString(":/tst_qdir/resources/entryList")); - QVERIFY(dir.exists()); - QStringList entryList = dir.entryList(); - QVERIFY(entryList.contains("file3.data")); -} - void tst_QDir::longFileName_data() { QTest::addColumn("length"); diff --git a/tests/auto/qfileinfo/tst_qfileinfo.cpp b/tests/auto/qfileinfo/tst_qfileinfo.cpp index 86655e4af..0e366e6b2 100644 --- a/tests/auto/qfileinfo/tst_qfileinfo.cpp +++ b/tests/auto/qfileinfo/tst_qfileinfo.cpp @@ -887,9 +887,7 @@ void tst_QFileInfo::isLocalFs() QFileInfo info(path); QFileInfoPrivate *privateInfo = getPrivate(info); - QCOMPARE((privateInfo->fileEngine == 0), isLocalFs); - if (privateInfo->fileEngine) - QCOMPARE(bool(privateInfo->fileEngine->fileFlags(QAbstractFileEngine::LocalDiskFlag) + QCOMPARE(bool(privateInfo->fileEngine->fileFlags(QAbstractFileEngine::LocalDiskFlag) & QAbstractFileEngine::LocalDiskFlag), isLocalFs); }