From 5a4092106ec37b627a409cc6e343d8e93fa3886b Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Tue, 3 Jan 2023 11:55:43 +0100 Subject: [PATCH] Utils: Remove old MIME database implementation The new one has been in use for long enough now, that we don't need the old one for regression testing anymore. Change-Id: I20a4a1dae483b1fee345ea4ec8e31509f6877047 Reviewed-by: Jarek Kobus --- src/libs/utils/CMakeLists.txt | 12 +- src/libs/utils/mimetypes/mimedatabase.cpp | 586 ------------ src/libs/utils/mimetypes/mimedatabase.h | 57 -- src/libs/utils/mimetypes/mimedatabase_p.h | 74 -- src/libs/utils/mimetypes/mimeglobpattern.cpp | 241 ----- src/libs/utils/mimetypes/mimeglobpattern_p.h | 135 --- src/libs/utils/mimetypes/mimemagicrule.cpp | 403 -------- src/libs/utils/mimetypes/mimemagicrule_p.h | 71 -- .../utils/mimetypes/mimemagicrulematcher.cpp | 67 -- .../utils/mimetypes/mimemagicrulematcher_p.h | 51 - src/libs/utils/mimetypes/mimeprovider.cpp | 871 ------------------ src/libs/utils/mimetypes/mimeprovider_p.h | 155 ---- src/libs/utils/mimetypes/mimetype.cpp | 423 --------- src/libs/utils/mimetypes/mimetype.h | 99 -- src/libs/utils/mimetypes/mimetype_p.h | 84 -- src/libs/utils/mimetypes/mimetypeparser.cpp | 325 ------- src/libs/utils/mimetypes/mimetypeparser_p.h | 91 -- src/libs/utils/mimetypes/mimeutils.cpp | 104 --- src/libs/utils/utils.qbs | 9 +- src/plugins/squish/squishplugin.cpp | 1 - 20 files changed, 5 insertions(+), 3854 deletions(-) delete mode 100644 src/libs/utils/mimetypes/mimedatabase.cpp delete mode 100644 src/libs/utils/mimetypes/mimedatabase.h delete mode 100644 src/libs/utils/mimetypes/mimedatabase_p.h delete mode 100644 src/libs/utils/mimetypes/mimeglobpattern.cpp delete mode 100644 src/libs/utils/mimetypes/mimeglobpattern_p.h delete mode 100644 src/libs/utils/mimetypes/mimemagicrule.cpp delete mode 100644 src/libs/utils/mimetypes/mimemagicrule_p.h delete mode 100644 src/libs/utils/mimetypes/mimemagicrulematcher.cpp delete mode 100644 src/libs/utils/mimetypes/mimemagicrulematcher_p.h delete mode 100644 src/libs/utils/mimetypes/mimeprovider.cpp delete mode 100644 src/libs/utils/mimetypes/mimeprovider_p.h delete mode 100644 src/libs/utils/mimetypes/mimetype.cpp delete mode 100644 src/libs/utils/mimetypes/mimetype.h delete mode 100644 src/libs/utils/mimetypes/mimetype_p.h delete mode 100644 src/libs/utils/mimetypes/mimetypeparser.cpp delete mode 100644 src/libs/utils/mimetypes/mimetypeparser_p.h delete mode 100644 src/libs/utils/mimetypes/mimeutils.cpp diff --git a/src/libs/utils/CMakeLists.txt b/src/libs/utils/CMakeLists.txt index 1354e282c18..0eccb86f0bd 100644 --- a/src/libs/utils/CMakeLists.txt +++ b/src/libs/utils/CMakeLists.txt @@ -195,17 +195,9 @@ add_qtc_library(Utils wizardpage.cpp wizardpage.h ) -option(QTC_USE_NEW_MIMEDATABASE "Use updated MIME database implementation" YES) - -if(QTC_USE_NEW_MIMEDATABASE) - set(mime_prefix "mimetypes2") -else() - set(mime_prefix "mimetypes") -endif() - extend_qtc_library(Utils - SOURCES_PREFIX ${mime_prefix} - PUBLIC_INCLUDES ${mime_prefix} + SOURCES_PREFIX mimetypes2 + PUBLIC_INCLUDES mimetypes2 SOURCES mimedatabase.cpp mimedatabase.h diff --git a/src/libs/utils/mimetypes/mimedatabase.cpp b/src/libs/utils/mimetypes/mimedatabase.cpp deleted file mode 100644 index 6ffe81d96d8..00000000000 --- a/src/libs/utils/mimetypes/mimedatabase.cpp +++ /dev/null @@ -1,586 +0,0 @@ -// Copyright (C) 2016 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR LGPL-3.0 - -#include // always first - -#include "mimedatabase.h" - -#include "mimedatabase_p.h" - -#include "mimemagicrule_p.h" -#include "mimeprovider_p.h" -#include "mimetype_p.h" - -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -using namespace Utils; -using namespace Utils::Internal; - -Q_GLOBAL_STATIC(MimeDatabasePrivate, staticMimeDatabase) - -MimeDatabasePrivate *MimeDatabasePrivate::instance() -{ - return staticMimeDatabase(); -} - -MimeDatabasePrivate::MimeDatabasePrivate() - : m_provider(nullptr), m_defaultMimeType(QLatin1String("application/octet-stream")) -{ -} - -MimeDatabasePrivate::~MimeDatabasePrivate() -{ - delete m_provider; - m_provider = nullptr; -} - -MimeProviderBase *MimeDatabasePrivate::provider() -{ - if (!m_provider) { -// MimeProviderBase *binaryProvider = new MimeBinaryProvider(this); -// if (binaryProvider->isValid()) { -// m_provider = binaryProvider; -// } else { -// delete binaryProvider; - m_provider = new MimeXMLProvider(this); -// } - } - return m_provider; -} - -void MimeDatabasePrivate::setProvider(MimeProviderBase *theProvider) -{ - delete m_provider; - m_provider = theProvider; -} - -/*! - \internal - Returns a MIME type or an invalid one if none found - */ -MimeType MimeDatabasePrivate::mimeTypeForName(const QString &nameOrAlias) -{ - return provider()->mimeTypeForName(provider()->resolveAlias(nameOrAlias)); -} - -QStringList MimeDatabasePrivate::mimeTypeForFileName(const QString &fileName, QString *foundSuffix) -{ - if (fileName.endsWith(QLatin1Char('/'))) - return QStringList("inode/directory"); - - const QStringList matchingMimeTypes = provider()->findByFileName(QFileInfo(fileName).fileName(), foundSuffix); - return matchingMimeTypes; -} - -static inline bool isTextFile(const QByteArray &data) -{ - // UTF16 byte order marks - static const char bigEndianBOM[] = "\xFE\xFF"; - static const char littleEndianBOM[] = "\xFF\xFE"; - if (data.startsWith(bigEndianBOM) || data.startsWith(littleEndianBOM)) - return true; - - // Check the first 32 bytes (see shared-mime spec) - const char *p = data.constData(); - const char *e = p + qMin(32, data.size()); - for ( ; p < e; ++p) { - if ((unsigned char)(*p) < 32 && *p != 9 && *p !=10 && *p != 13) - return false; - } - - return true; -} - -MimeType MimeDatabasePrivate::findByData(const QByteArray &data, int *accuracyPtr) -{ -// if (data.isEmpty()) { -// *accuracyPtr = 100; -// return mimeTypeForName(QLatin1String("application/x-zerosize")); -// } - - *accuracyPtr = 0; - MimeType candidate = provider()->findByMagic(data, accuracyPtr); - - if (candidate.isValid()) - return candidate; - - if (isTextFile(data)) { - *accuracyPtr = 5; - return mimeTypeForName(QLatin1String("text/plain")); - } - - return mimeTypeForName(defaultMimeType()); -} - -MimeType MimeDatabasePrivate::mimeTypeForFileNameAndData(const QString &fileName, QIODevice *device, int *accuracyPtr) -{ - // First, glob patterns are evaluated. If there is a match with max weight, - // this one is selected and we are done. Otherwise, the file contents are - // evaluated and the match with the highest value (either a magic priority or - // a glob pattern weight) is selected. Matching starts from max level (most - // specific) in both cases, even when there is already a suffix matching candidate. - *accuracyPtr = 0; - - // Pass 1) Try to match on the file name - QStringList candidatesByName = mimeTypeForFileName(fileName); - if (candidatesByName.count() == 1) { - *accuracyPtr = 100; - const MimeType mime = mimeTypeForName(candidatesByName.at(0)); - if (mime.isValid()) - return mime; - candidatesByName.clear(); - } - - // Extension is unknown, or matches multiple mimetypes. - // Pass 2) Match on content, if we can read the data - const bool openedByUs = !device->isOpen() && device->open(QIODevice::ReadOnly); - if (device->isOpen()) { - - // Read 16K in one go (QIODEVICE_BUFFERSIZE in qiodevice_p.h). - // This is much faster than seeking back and forth into QIODevice. - const QByteArray data = device->peek(16384); - - if (openedByUs) - device->close(); - - int magicAccuracy = 0; - MimeType candidateByData(findByData(data, &magicAccuracy)); - - // Disambiguate conflicting extensions (if magic matching found something) - if (candidateByData.isValid() && magicAccuracy > 0) { - const QString sniffedMime = candidateByData.name(); - // If the sniffedMime matches a glob match, use it - if (candidatesByName.contains(sniffedMime)) { - *accuracyPtr = 100; - return candidateByData; - } - // If there is a glob match that is a sub class of sniffedMime, use it - for (const QString &m : std::as_const(candidatesByName)) { - if (inherits(m, sniffedMime)) { - // We have magic + pattern pointing to this, so it's a pretty good match - *accuracyPtr = 100; - return mimeTypeForName(m); - } - } - *accuracyPtr = magicAccuracy; - return candidateByData; - } - } - - if (candidatesByName.count() > 1) { - *accuracyPtr = 20; - candidatesByName.sort(); // to make it deterministic - const MimeType mime = mimeTypeForName(candidatesByName.at(0)); - if (mime.isValid()) - return mime; - } - - return mimeTypeForName(defaultMimeType()); -} - -QList MimeDatabasePrivate::allMimeTypes() -{ - return provider()->allMimeTypes(); -} - -bool MimeDatabasePrivate::inherits(const QString &mime, const QString &parent) -{ - const QString resolvedParent = provider()->resolveAlias(parent); - //Q_ASSERT(provider()->resolveAlias(mime) == mime); - QStack toCheck; - QSet seen; // avoid endless loop on bogus mime data - toCheck.push(mime); - seen.insert(mime); - while (!toCheck.isEmpty()) { - const QString current = toCheck.pop(); - if (current == resolvedParent) - return true; - const QStringList parents = provider()->parents(current); - for (const QString &par : parents) { - int seenSize = seen.size(); - seen.insert(par); - if (seen.size() != seenSize) // haven't seen before, so add - toCheck.push(par); - } - } - return false; -} - -/*! - \class MimeDatabase - \inmodule QtCore - \brief The MimeDatabase class maintains a database of MIME types. - - \since 5.0 - - The MIME type database is provided by the freedesktop.org shared-mime-info - project. If the MIME type database cannot be found on the system, as is the case - on most Windows and Mac OS X systems, Qt will use its own copy of it. - - Applications which want to define custom MIME types need to install an - XML file into the locations searched for MIME definitions. - These locations can be queried with - \code - QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, QLatin1String("mime/packages"), - QStandardPaths::LocateDirectory); - \endcode - On a typical Unix system, this will be /usr/share/mime/packages/, but it is also - possible to extend the list of directories by setting the environment variable - \c XDG_DATA_DIRS. For instance adding /opt/myapp/share to \c XDG_DATA_DIRS will result - in /opt/myapp/share/mime/packages/ being searched for MIME definitions. - - Here is an example of MIME XML: - \code - - - - Qt qmake Profile - - - - \endcode - - For more details about the syntax of XML MIME definitions, including defining - "magic" in order to detect MIME types based on data as well, read the - Shared Mime Info specification at - http://standards.freedesktop.org/shared-mime-info-spec/shared-mime-info-spec-latest.html - - On Unix systems, a binary cache is used for more performance. This cache is generated - by the command "update-mime-database path", where path would be /opt/myapp/share/mime - in the above example. Make sure to run this command when installing the MIME type - definition file. - - \threadsafe - - \snippet code/src_corelib_mimetype_qmimedatabase.cpp 0 - - \sa MimeType - */ - -/*! - \fn MimeDatabase::MimeDatabase(); - Constructs a MimeDatabase object. - - It is perfectly OK to create an instance of MimeDatabase every time you need to - perform a lookup. - The parsing of mimetypes is done on demand (when shared-mime-info is installed) - or when the very first instance is constructed (when parsing XML files directly). - */ -MimeDatabase::MimeDatabase() : - d(staticMimeDatabase()) -{ -} - -/*! - \fn MimeDatabase::~MimeDatabase(); - Destroys the MimeDatabase object. - */ -MimeDatabase::~MimeDatabase() -{ - d = nullptr; -} - -/*! - \fn MimeType MimeDatabase::mimeTypeForName(const QString &nameOrAlias) const; - Returns a MIME type for \a nameOrAlias or an invalid one if none found. - */ -MimeType MimeDatabase::mimeTypeForName(const QString &nameOrAlias) const -{ - QMutexLocker locker(&d->mutex); - - if (d->m_startupPhase <= MimeDatabase::PluginsInitializing) - qWarning("Accessing MimeDatabase for %s before plugins are initialized", qPrintable(nameOrAlias)); - - return d->mimeTypeForName(nameOrAlias); -} - -/*! - Returns a MIME type for \a fileInfo. - - A valid MIME type is always returned. - - The default matching algorithm looks at both the file name and the file - contents, if necessary. The file extension has priority over the contents, - but the contents will be used if the file extension is unknown, or - matches multiple MIME types. - If \a fileInfo is a Unix symbolic link, the file that it refers to - will be used instead. - If the file doesn't match any known pattern or data, the default MIME type - (application/octet-stream) is returned. - - When \a mode is set to MatchExtension, only the file name is used, not - the file contents. The file doesn't even have to exist. If the file name - doesn't match any known pattern, the default MIME type (application/octet-stream) - is returned. - If multiple MIME types match this file, the first one (alphabetically) is returned. - - When \a mode is set to MatchContent, and the file is readable, only the - file contents are used to determine the MIME type. This is equivalent to - calling mimeTypeForData with a QFile as input device. - - \a fileInfo may refer to an absolute or relative path. - - \sa MimeType::isDefault(), mimeTypeForData() -*/ -MimeType MimeDatabase::mimeTypeForFile(const QFileInfo &fileInfo, MatchMode mode) const -{ - QMutexLocker locker(&d->mutex); - - if (fileInfo.isDir()) - return d->mimeTypeForName(QLatin1String("inode/directory")); - - QFile file(fileInfo.absoluteFilePath()); - -#ifdef Q_OS_UNIX - // Cannot access statBuf.st_mode from the filesystem engine, so we have to stat again. - const QByteArray nativeFilePath = QFile::encodeName(file.fileName()); - QT_STATBUF statBuffer; - if (QT_LSTAT(nativeFilePath.constData(), &statBuffer) == 0) { - if (S_ISCHR(statBuffer.st_mode)) - return d->mimeTypeForName(QLatin1String("inode/chardevice")); - if (S_ISBLK(statBuffer.st_mode)) - return d->mimeTypeForName(QLatin1String("inode/blockdevice")); - if (S_ISFIFO(statBuffer.st_mode)) - return d->mimeTypeForName(QLatin1String("inode/fifo")); - if (S_ISSOCK(statBuffer.st_mode)) - return d->mimeTypeForName(QLatin1String("inode/socket")); - } -#endif - - int priority = 0; - switch (mode) { - case MatchDefault: - return d->mimeTypeForFileNameAndData(fileInfo.absoluteFilePath(), &file, &priority); - case MatchExtension: - locker.unlock(); - return mimeTypeForFile(fileInfo.absoluteFilePath(), mode); - case MatchContent: - if (file.open(QIODevice::ReadOnly)) { - locker.unlock(); - return mimeTypeForData(&file); - } else { - return d->mimeTypeForName(d->defaultMimeType()); - } - default: - Q_ASSERT(false); - } - return d->mimeTypeForName(d->defaultMimeType()); -} - -/*! - Returns a MIME type for the file named \a fileName using \a mode. - - \overload -*/ -MimeType MimeDatabase::mimeTypeForFile(const QString &fileName, MatchMode mode) const -{ - if (mode == MatchExtension) { - QMutexLocker locker(&d->mutex); - QStringList matches = d->mimeTypeForFileName(fileName); - const int matchCount = matches.count(); - if (matchCount == 0) { - return d->mimeTypeForName(d->defaultMimeType()); - } else if (matchCount == 1) { - return d->mimeTypeForName(matches.first()); - } else { - // We have to pick one. - matches.sort(); // Make it deterministic - return d->mimeTypeForName(matches.first()); - } - } else { - // Implemented as a wrapper around mimeTypeForFile(QFileInfo), so no mutex. - QFileInfo fileInfo(fileName); - return mimeTypeForFile(fileInfo, mode); - } -} - -/*! - Returns the MIME types for the file name \a fileName. - - If the file name doesn't match any known pattern, an empty list is returned. - If multiple MIME types match this file, they are all returned. - - This function does not try to open the file. To also use the content - when determining the MIME type, use mimeTypeForFile() or - mimeTypeForFileNameAndData() instead. - - \sa mimeTypeForFile() -*/ -QList MimeDatabase::mimeTypesForFileName(const QString &fileName) const -{ - QMutexLocker locker(&d->mutex); - - QStringList matches = d->mimeTypeForFileName(fileName); - QList mimes; - matches.sort(); // Make it deterministic - for (const QString &mime : std::as_const(matches)) - mimes.append(d->mimeTypeForName(mime)); - return mimes; -} -/*! - Returns the suffix for the file \a fileName, as known by the MIME database. - - This allows to pre-select "tar.bz2" for foo.tar.bz2, but still only - "txt" for my.file.with.dots.txt. -*/ -QString MimeDatabase::suffixForFileName(const QString &fileName) const -{ - QMutexLocker locker(&d->mutex); - QString foundSuffix; - d->mimeTypeForFileName(fileName, &foundSuffix); - return foundSuffix; -} - -/*! - Returns a MIME type for \a data. - - A valid MIME type is always returned. If \a data doesn't match any - known MIME type data, the default MIME type (application/octet-stream) - is returned. -*/ -MimeType MimeDatabase::mimeTypeForData(const QByteArray &data) const -{ - QMutexLocker locker(&d->mutex); - - int accuracy = 0; - return d->findByData(data, &accuracy); -} - -/*! - Returns a MIME type for the data in \a device. - - A valid MIME type is always returned. If the data in \a device doesn't match any - known MIME type data, the default MIME type (application/octet-stream) - is returned. -*/ -MimeType MimeDatabase::mimeTypeForData(QIODevice *device) const -{ - QMutexLocker locker(&d->mutex); - - int accuracy = 0; - const bool openedByUs = !device->isOpen() && device->open(QIODevice::ReadOnly); - if (device->isOpen()) { - // Read 16K in one go (QIODEVICE_BUFFERSIZE in qiodevice_p.h). - // This is much faster than seeking back and forth into QIODevice. - const QByteArray data = device->peek(16384); - const MimeType result = d->findByData(data, &accuracy); - if (openedByUs) - device->close(); - return result; - } - return d->mimeTypeForName(d->defaultMimeType()); -} - -/*! - Returns a MIME type for \a url. - - If the URL is a local file, this calls mimeTypeForFile. - - Otherwise the matching is done based on the file name only, - except for schemes where file names don't mean much, like HTTP. - This method always returns the default mimetype for HTTP URLs, - use QNetworkAccessManager to handle HTTP URLs properly. - - A valid MIME type is always returned. If \a url doesn't match any - known MIME type data, the default MIME type (application/octet-stream) - is returned. -*/ -MimeType MimeDatabase::mimeTypeForUrl(const QUrl &url) const -{ - if (url.isLocalFile()) - return mimeTypeForFile(url.toLocalFile()); - - const QString scheme = url.scheme(); - if (scheme.startsWith(QLatin1String("http"))) - return mimeTypeForName(d->defaultMimeType()); - - return mimeTypeForFile(url.path()); -} - -/*! - Returns a MIME type for the given \a fileName and \a device data. - - This overload can be useful when the file is remote, and we started to - download some of its data in a device. This allows to do full MIME type - matching for remote files as well. - - If the device is not open, it will be opened by this function, and closed - after the MIME type detection is completed. - - A valid MIME type is always returned. If \a device data doesn't match any - known MIME type data, the default MIME type (application/octet-stream) - is returned. - - This method looks at both the file name and the file contents, - if necessary. The file extension has priority over the contents, - but the contents will be used if the file extension is unknown, or - matches multiple MIME types. -*/ -MimeType MimeDatabase::mimeTypeForFileNameAndData(const QString &fileName, QIODevice *device) const -{ - int accuracy = 0; - const MimeType result = d->mimeTypeForFileNameAndData(fileName, device, &accuracy); - return result; -} - -/*! - Returns a MIME type for the given \a fileName and device \a data. - - This overload can be useful when the file is remote, and we started to - download some of its data. This allows to do full MIME type matching for - remote files as well. - - A valid MIME type is always returned. If \a data doesn't match any - known MIME type data, the default MIME type (application/octet-stream) - is returned. - - This method looks at both the file name and the file contents, - if necessary. The file extension has priority over the contents, - but the contents will be used if the file extension is unknown, or - matches multiple MIME types. -*/ -MimeType MimeDatabase::mimeTypeForFileNameAndData(const QString &fileName, const QByteArray &data) const -{ - QBuffer buffer(const_cast(&data)); - buffer.open(QIODevice::ReadOnly); - int accuracy = 0; - return d->mimeTypeForFileNameAndData(fileName, &buffer, &accuracy); -} - -/*! - Returns the list of all available MIME types. - - This can be useful for showing all MIME types to the user, for instance - in a MIME type editor. Do not use unless really necessary in other cases - though, prefer using the \l {mimeTypeForData()}{mimeTypeForXxx()} methods for performance reasons. -*/ -QList MimeDatabase::allMimeTypes() const -{ - QMutexLocker locker(&d->mutex); - - return d->allMimeTypes(); -} - -/*! - \enum MimeDatabase::MatchMode - - This enum specifies how matching a file to a MIME type is performed. - - \value MatchDefault Both the file name and content are used to look for a match - - \value MatchExtension Only the file name is used to look for a match - - \value MatchContent The file content is used to look for a match -*/ diff --git a/src/libs/utils/mimetypes/mimedatabase.h b/src/libs/utils/mimetypes/mimedatabase.h deleted file mode 100644 index 771bf5b72ed..00000000000 --- a/src/libs/utils/mimetypes/mimedatabase.h +++ /dev/null @@ -1,57 +0,0 @@ -// Copyright (C) 2016 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR LGPL-3.0 - -#pragma once - -#include "mimetype.h" - -QT_BEGIN_NAMESPACE -class QFileInfo; -class QIODevice; -class QUrl; -QT_END_NAMESPACE - -namespace Utils { - -class MimeDatabase -{ - Q_DISABLE_COPY(MimeDatabase) - -public: - MimeDatabase(); - ~MimeDatabase(); - - MimeType mimeTypeForName(const QString &nameOrAlias) const; - - enum MatchMode { MatchDefault = 0x0, MatchExtension = 0x1, MatchContent = 0x2 }; - - MimeType mimeTypeForFile(const QString &fileName, MatchMode mode = MatchDefault) const; - MimeType mimeTypeForFile(const QFileInfo &fileInfo, MatchMode mode = MatchDefault) const; - QList mimeTypesForFileName(const QString &fileName) const; - - MimeType mimeTypeForData(const QByteArray &data) const; - MimeType mimeTypeForData(QIODevice *device) const; - - MimeType mimeTypeForUrl(const QUrl &url) const; - MimeType mimeTypeForFileNameAndData(const QString &fileName, QIODevice *device) const; - MimeType mimeTypeForFileNameAndData(const QString &fileName, const QByteArray &data) const; - - QString suffixForFileName(const QString &fileName) const; - - QList allMimeTypes() const; - - // For debugging purposes. - enum StartupPhase { - BeforeInitialize, - PluginsLoading, - PluginsInitializing, // Register up to here. - PluginsDelayedInitializing, // Use from here on. - UpAndRunning - }; - static void setStartupPhase(StartupPhase); - -private: - Internal::MimeDatabasePrivate *d; -}; - -} // Utils diff --git a/src/libs/utils/mimetypes/mimedatabase_p.h b/src/libs/utils/mimetypes/mimedatabase_p.h deleted file mode 100644 index e5d8afe69ab..00000000000 --- a/src/libs/utils/mimetypes/mimedatabase_p.h +++ /dev/null @@ -1,74 +0,0 @@ -// Copyright (C) 2016 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR LGPL-3.0 - -#pragma once - -// -// W A R N I N G -// ------------- -// -// This file is mostly copied from Qt code and should not be touched -// unless really needed. -// - - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include -#include -QT_BEGIN_NAMESPACE -class QIODevice; -QT_END_NAMESPACE - -#include "mimetype.h" -#include "mimetype_p.h" -#include "mimeglobpattern_p.h" - -namespace Utils { -namespace Internal { - -class MimeProviderBase; - -class MimeDatabasePrivate -{ -public: - Q_DISABLE_COPY(MimeDatabasePrivate) - - MimeDatabasePrivate(); - ~MimeDatabasePrivate(); - - static MimeDatabasePrivate *instance(); - - MimeProviderBase *provider(); - void setProvider(MimeProviderBase *theProvider); - - inline QString defaultMimeType() const { return m_defaultMimeType; } - - bool inherits(const QString &mime, const QString &parent); - - QList allMimeTypes(); - - - MimeType mimeTypeForName(const QString &nameOrAlias); - MimeType mimeTypeForFileNameAndData(const QString &fileName, QIODevice *device, int *priorityPtr); - MimeType findByData(const QByteArray &data, int *priorityPtr); - QStringList mimeTypeForFileName(const QString &fileName, QString *foundSuffix = nullptr); - - mutable MimeProviderBase *m_provider; - const QString m_defaultMimeType; - QMutex mutex; - - int m_startupPhase = 0; -}; - -} // Internal -} // Utils diff --git a/src/libs/utils/mimetypes/mimeglobpattern.cpp b/src/libs/utils/mimetypes/mimeglobpattern.cpp deleted file mode 100644 index fca8b740913..00000000000 --- a/src/libs/utils/mimetypes/mimeglobpattern.cpp +++ /dev/null @@ -1,241 +0,0 @@ -// Copyright (C) 2016 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR LGPL-3.0 - -#include "mimeglobpattern_p.h" - -#include -#include -#include - -using namespace Utils; -using namespace Utils::Internal; - -/*! - \internal - \class MimeGlobMatchResult - \inmodule QtCore - \brief The MimeGlobMatchResult class accumulates results from glob matching. - - Handles glob weights, and preferring longer matches over shorter matches. -*/ - -void MimeGlobMatchResult::addMatch(const QString &mimeType, int weight, const QString &pattern) -{ - // Is this a lower-weight pattern than the last match? Skip this match then. - if (weight < m_weight) - return; - bool replace = weight > m_weight; - if (!replace) { - // Compare the length of the match - if (pattern.length() < m_matchingPatternLength) - return; // too short, ignore - else if (pattern.length() > m_matchingPatternLength) { - // longer: clear any previous match (like *.bz2, when pattern is *.tar.bz2) - replace = true; - } - } - if (replace) { - m_matchingMimeTypes.clear(); - // remember the new "longer" length - m_matchingPatternLength = pattern.length(); - m_weight = weight; - } - if (!m_matchingMimeTypes.contains(mimeType)) { - m_matchingMimeTypes.append(mimeType); - if (pattern.startsWith(QLatin1String("*."))) - m_foundSuffix = pattern.mid(2); - } -} - -MimeGlobPattern::PatternType MimeGlobPattern::detectPatternType(const QString &pattern) const -{ - const int patternLength = pattern.length(); - if (!patternLength) - return OtherPattern; - - const bool starCount = pattern.count(QLatin1Char('*')) == 1; - const bool hasSquareBracket = pattern.indexOf(QLatin1Char('[')) != -1; - const bool hasQuestionMark = pattern.indexOf(QLatin1Char('?')) != -1; - - if (!hasSquareBracket && !hasQuestionMark) { - if (starCount == 1) { - // Patterns like "*~", "*.extension" - if (pattern.at(0) == QLatin1Char('*')) - return SuffixPattern; - // Patterns like "README*" (well this is currently the only one like that...) - if (pattern.at(patternLength - 1) == QLatin1Char('*')) - return PrefixPattern; - } - // Names without any wildcards like "README" - if (starCount == 0) - return LiteralPattern; - } - - if (pattern == QLatin1String("[0-9][0-9][0-9].vdr")) - return VdrPattern; - - if (pattern == QLatin1String("*.anim[1-9j]")) - return AnimPattern; - - return OtherPattern; -} - -/*! - \internal - \class MimeGlobPattern - \inmodule QtCore - \brief The MimeGlobPattern class contains the glob pattern for file names for MIME type matching. - - \sa MimeType, MimeDatabase, MimeMagicRuleMatcher, MimeMagicRule -*/ - -bool MimeGlobPattern::matchFileName(const QString &inputFileName) const -{ - // "Applications MUST match globs case-insensitively, except when the case-sensitive - // attribute is set to true." - // The constructor takes care of putting case-insensitive patterns in lowercase. - const QString fileName = m_caseSensitivity == Qt::CaseInsensitive - ? inputFileName.toLower() : inputFileName; - - const int patternLength = m_pattern.length(); - if (!patternLength) - return false; - const int fileNameLength = fileName.length(); - - switch (m_patternType) { - case SuffixPattern: { - if (fileNameLength + 1 < patternLength) - return false; - - const QChar *c1 = m_pattern.unicode() + patternLength - 1; - const QChar *c2 = fileName.unicode() + fileNameLength - 1; - int cnt = 1; - while (cnt < patternLength && *c1-- == *c2--) - ++cnt; - return cnt == patternLength; - } - case PrefixPattern: { - if (fileNameLength + 1 < patternLength) - return false; - - const QChar *c1 = m_pattern.unicode(); - const QChar *c2 = fileName.unicode(); - int cnt = 1; - while (cnt < patternLength && *c1++ == *c2++) - ++cnt; - return cnt == patternLength; - } - case LiteralPattern: - return (m_pattern == fileName); - case VdrPattern: // "[0-9][0-9][0-9].vdr" case - return fileNameLength == 7 - && fileName.at(0).isDigit() && fileName.at(1).isDigit() && fileName.at(2).isDigit() - && QStringView{fileName}.mid(3, 4) == QLatin1String(".vdr"); - case AnimPattern: { // "*.anim[1-9j]" case - if (fileNameLength < 6) - return false; - const QChar lastChar = fileName.at(fileNameLength - 1); - const bool lastCharOK = (lastChar.isDigit() && lastChar != QLatin1Char('0')) - || lastChar == QLatin1Char('j'); - return lastCharOK && QStringView{fileName}.mid(fileNameLength - 6, 5) == QLatin1String(".anim"); - } - case OtherPattern: - // Other fallback patterns: slow but correct method - const QRegularExpression rx(QRegularExpression::anchoredPattern( - QRegularExpression::wildcardToRegularExpression(m_pattern))); - return rx.match(fileName).hasMatch(); - } - return false; -} - -static bool isFastPattern(const QString &pattern) -{ - // starts with "*.", has no other '*' and no other '.' - return pattern.lastIndexOf(QLatin1Char('*')) == 0 - && pattern.lastIndexOf(QLatin1Char('.')) == 1 - // and contains no other special character - && !pattern.contains(QLatin1Char('?')) - && !pattern.contains(QLatin1Char('[')) - ; -} - -void MimeAllGlobPatterns::addGlob(const MimeGlobPattern &glob) -{ - const QString &pattern = glob.pattern(); - Q_ASSERT(!pattern.isEmpty()); - - // Store each patterns into either m_fastPatternDict (*.txt, *.html etc. with default weight 50) - // or for the rest, like core.*, *.tar.bz2, *~, into highWeightPatternOffset (>50) - // or lowWeightPatternOffset (<=50) - - if (glob.weight() == 50 && isFastPattern(pattern) && !glob.isCaseSensitive()) { - // The bulk of the patterns is *.foo with weight 50 --> those go into the fast patterns hash. - const QString extension = pattern.mid(2).toLower(); - QStringList &patterns = m_fastPatterns[extension]; // find or create - if (!patterns.contains(glob.mimeType())) - patterns.append(glob.mimeType()); - } else { - if (glob.weight() > 50) { - if (!m_highWeightGlobs.hasPattern(glob.mimeType(), glob.pattern())) - m_highWeightGlobs.append(glob); - } else { - if (!m_lowWeightGlobs.hasPattern(glob.mimeType(), glob.pattern())) - m_lowWeightGlobs.append(glob); - } - } -} - -void MimeAllGlobPatterns::removeMimeType(const QString &mimeType) -{ - for (QStringList &x : m_fastPatterns) - x.removeAll(mimeType); - - m_highWeightGlobs.removeMimeType(mimeType); - m_lowWeightGlobs.removeMimeType(mimeType); -} - -void MimeGlobPatternList::match(MimeGlobMatchResult &result, - const QString &fileName) const -{ - for (const MimeGlobPattern &glob : *this) { - if (glob.matchFileName(fileName)) - result.addMatch(glob.mimeType(), glob.weight(), glob.pattern()); - } -} - -QStringList MimeAllGlobPatterns::matchingGlobs(const QString &fileName, QString *foundSuffix) const -{ - // First try the high weight matches (>50), if any. - MimeGlobMatchResult result; - m_highWeightGlobs.match(result, fileName); - if (result.m_matchingMimeTypes.isEmpty()) { - - // Now use the "fast patterns" dict, for simple *.foo patterns with weight 50 - // (which is most of them, so this optimization is definitely worth it) - const int lastDot = fileName.lastIndexOf(QLatin1Char('.')); - if (lastDot != -1) { // if no '.', skip the extension lookup - const int ext_len = fileName.length() - lastDot - 1; - const QString simpleExtension = fileName.right(ext_len).toLower(); - // (toLower because fast patterns are always case-insensitive and saved as lowercase) - - const QStringList matchingMimeTypes = m_fastPatterns.value(simpleExtension); - for (const QString &mime : matchingMimeTypes) - result.addMatch(mime, 50, QLatin1String("*.") + simpleExtension); - // Can't return yet; *.tar.bz2 has to win over *.bz2, so we need the low-weight mimetypes anyway, - // at least those with weight 50. - } - - // Finally, try the low weight matches (<=50) - m_lowWeightGlobs.match(result, fileName); - } - if (foundSuffix) - *foundSuffix = result.m_foundSuffix; - return result.m_matchingMimeTypes; -} - -void MimeAllGlobPatterns::clear() -{ - m_fastPatterns.clear(); - m_highWeightGlobs.clear(); - m_lowWeightGlobs.clear(); -} diff --git a/src/libs/utils/mimetypes/mimeglobpattern_p.h b/src/libs/utils/mimetypes/mimeglobpattern_p.h deleted file mode 100644 index c8eb2753f7a..00000000000 --- a/src/libs/utils/mimetypes/mimeglobpattern_p.h +++ /dev/null @@ -1,135 +0,0 @@ -// Copyright (C) 2016 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR LGPL-3.0 - -#pragma once - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include -#include - -namespace Utils { -namespace Internal { - -struct MimeGlobMatchResult -{ - void addMatch(const QString &mimeType, int weight, const QString &pattern); - - QStringList m_matchingMimeTypes; - int m_weight = 0; - int m_matchingPatternLength = 0; - QString m_foundSuffix; -}; - -class MimeGlobPattern -{ -public: - static const unsigned MaxWeight = 100; - static const unsigned DefaultWeight = 50; - static const unsigned MinWeight = 1; - - explicit MimeGlobPattern(const QString &thePattern, const QString &theMimeType, - unsigned theWeight = DefaultWeight, - Qt::CaseSensitivity s = Qt::CaseInsensitive) : - m_pattern(s == Qt::CaseInsensitive ? thePattern.toLower() : thePattern), - m_mimeType(theMimeType), - m_weight(theWeight), - m_caseSensitivity(s), - m_patternType(detectPatternType(m_pattern)) - { - } - - void swap(MimeGlobPattern &other) noexcept - { - qSwap(m_pattern, other.m_pattern); - qSwap(m_mimeType, other.m_mimeType); - qSwap(m_weight, other.m_weight); - qSwap(m_caseSensitivity, other.m_caseSensitivity); - qSwap(m_patternType, other.m_patternType); - } - - bool matchFileName(const QString &inputFileName) const; - - inline const QString &pattern() const { return m_pattern; } - inline unsigned weight() const { return m_weight; } - inline const QString &mimeType() const { return m_mimeType; } - inline bool isCaseSensitive() const { return m_caseSensitivity == Qt::CaseSensitive; } - -private: - enum PatternType { - SuffixPattern, - PrefixPattern, - LiteralPattern, - VdrPattern, // special handling for "[0-9][0-9][0-9].vdr" pattern - AnimPattern, // special handling for "*.anim[1-9j]" pattern - OtherPattern - }; - PatternType detectPatternType(const QString &pattern) const; - - QString m_pattern; - QString m_mimeType; - int m_weight; - Qt::CaseSensitivity m_caseSensitivity; - PatternType m_patternType; -}; - -class MimeGlobPatternList : public QList -{ -public: - bool hasPattern(const QString &mimeType, const QString &pattern) const - { - const_iterator it = begin(); - const const_iterator myend = end(); - for (; it != myend; ++it) - if ((*it).pattern() == pattern && (*it).mimeType() == mimeType) - return true; - return false; - } - - /*! - "noglobs" is very rare occurrence, so it's ok if it's slow - */ - void removeMimeType(const QString &mimeType) - { - auto isMimeTypeEqual = [&mimeType](const MimeGlobPattern &pattern) { - return pattern.mimeType() == mimeType; - }; - erase(std::remove_if(begin(), end(), isMimeTypeEqual), end()); - } - - void match(MimeGlobMatchResult &result, const QString &fileName) const; -}; - -/*! - Result of the globs parsing, as data structures ready for efficient MIME type matching. - This contains: - 1) a map of fast regular patterns (e.g. *.txt is stored as "txt" in a qhash's key) - 2) a linear list of high-weight globs - 3) a linear list of low-weight globs - */ -class MimeAllGlobPatterns -{ -public: - typedef QHash PatternsMap; // MIME type -> patterns - - void addGlob(const MimeGlobPattern &glob); - void removeMimeType(const QString &mimeType); - QStringList matchingGlobs(const QString &fileName, QString *foundSuffix) const; - void clear(); - - PatternsMap m_fastPatterns; // example: "doc" -> "application/msword", "text/plain" - MimeGlobPatternList m_highWeightGlobs; - MimeGlobPatternList m_lowWeightGlobs; // <= 50, including the non-fast 50 patterns -}; - -} // Internal -} // Utils diff --git a/src/libs/utils/mimetypes/mimemagicrule.cpp b/src/libs/utils/mimetypes/mimemagicrule.cpp deleted file mode 100644 index 8c7d94e6d92..00000000000 --- a/src/libs/utils/mimetypes/mimemagicrule.cpp +++ /dev/null @@ -1,403 +0,0 @@ -// Copyright (C) 2016 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR LGPL-3.0 - -#include "mimemagicrule_p.h" - -#include -#include -#include -#include - -using namespace Utils; -using namespace Utils::Internal; - -// in the same order as Type! -static const char magicRuleTypes_string[] = - "invalid\0" - "string\0" - "regexp\0" - "host16\0" - "host32\0" - "big16\0" - "big32\0" - "little16\0" - "little32\0" - "byte\0" - "\0"; - -static const int magicRuleTypes_indices[] = { - 0, 8, 15, 22, 29, 36, 42, 48, 57, 66, 71, 0 -}; - -MimeMagicRule::Type MimeMagicRule::type(const QByteArray &theTypeName) -{ - for (int i = String; i <= Byte; ++i) { - if (theTypeName == magicRuleTypes_string + magicRuleTypes_indices[i]) - return Type(i); - } - return Invalid; -} - -QByteArray MimeMagicRule::typeName(MimeMagicRule::Type theType) -{ - return magicRuleTypes_string + magicRuleTypes_indices[theType]; -} - -namespace Utils { -namespace Internal { - -class MimeMagicRulePrivate -{ -public: - bool operator==(const MimeMagicRulePrivate &other) const; - - MimeMagicRule::Type type; - QByteArray value; - int startPos; - int endPos; - QByteArray mask; - - QRegularExpression regexp; - QByteArray pattern; - quint32 number; - quint32 numberMask; - - using MatchFunction = bool (*)(const MimeMagicRulePrivate*, const QByteArray&); - MatchFunction matchFunction; -}; - -bool MimeMagicRulePrivate::operator==(const MimeMagicRulePrivate &other) const -{ - return type == other.type && - value == other.value && - startPos == other.startPos && - endPos == other.endPos && - mask == other.mask && - pattern == other.pattern && - number == other.number && - numberMask == other.numberMask && - matchFunction == other.matchFunction; -} - -} // Internal -} // Utils - -// Used by both providers -bool MimeMagicRule::matchSubstring(const char *dataPtr, int dataSize, int rangeStart, int rangeLength, - int valueLength, const char *valueData, const char *mask) -{ - // Size of searched data. - // Example: value="ABC", rangeLength=3 -> we need 3+3-1=5 bytes (ABCxx,xABCx,xxABC would match) - const int dataNeeded = qMin(rangeLength + valueLength - 1, dataSize - rangeStart); - - if (!mask) { - // callgrind says QByteArray::indexOf is much slower, since our strings are typically too - // short for be worth Boyer-Moore matching (1 to 71 bytes, 11 bytes on average). - bool found = false; - for (int i = rangeStart; i < rangeStart + rangeLength; ++i) { - if (i + valueLength > dataSize) - break; - - if (memcmp(valueData, dataPtr + i, valueLength) == 0) { - found = true; - break; - } - } - if (!found) - return false; - } else { - bool found = false; - const char *readDataBase = dataPtr + rangeStart; - // Example (continued from above): - // deviceSize is 4, so dataNeeded was max'ed to 4. - // maxStartPos = 4 - 3 + 1 = 2, and indeed - // we need to check for a match a positions 0 and 1 (ABCx and xABC). - const int maxStartPos = dataNeeded - valueLength + 1; - for (int i = 0; i < maxStartPos; ++i) { - const char *d = readDataBase + i; - bool valid = true; - for (int idx = 0; idx < valueLength; ++idx) { - if (((*d++) & mask[idx]) != (valueData[idx] & mask[idx])) { - valid = false; - break; - } - } - if (valid) - found = true; - } - if (!found) - return false; - } - //qDebug() << "Found" << value << "in" << searchedData; - return true; -} - -static bool matchString(const MimeMagicRulePrivate *d, const QByteArray &data) -{ - const int rangeLength = d->endPos - d->startPos + 1; - return MimeMagicRule::matchSubstring(data.constData(), data.size(), d->startPos, rangeLength, d->pattern.size(), d->pattern.constData(), d->mask.constData()); -} - -static bool matchRegExp(const MimeMagicRulePrivate *d, const QByteArray &data) -{ - const QString str = QString::fromUtf8(data); - int length = d->endPos; - if (length == d->startPos) - length = -1; // from startPos to end of string - const QString subStr = str.left(length); - return d->regexp.match(subStr, d->startPos).hasMatch(); -} - -template -static bool matchNumber(const MimeMagicRulePrivate *d, const QByteArray &data) -{ - const T value(d->number); - const T mask(d->numberMask); - - //qDebug() << "matchNumber" << "0x" << QString::number(d->number, 16) << "size" << sizeof(T); - //qDebug() << "mask" << QString::number(d->numberMask, 16); - - const char *p = data.constData() + d->startPos; - const char *e = data.constData() + qMin(data.size() - int(sizeof(T)), d->endPos + 1); - for ( ; p <= e; ++p) { - if ((*reinterpret_cast(p) & mask) == (value & mask)) - return true; - } - - return false; -} - -static inline QByteArray makePattern(const QByteArray &value) -{ - QByteArray pattern(value.size(), Qt::Uninitialized); - char *data = pattern.data(); - - const char *p = value.constData(); - const char *e = p + value.size(); - for ( ; p < e; ++p) { - if (*p == '\\' && ++p < e) { - if (*p == 'x') { // hex (\\xff) - char c = 0; - for (int i = 0; i < 2 && p + 1 < e; ++i) { - ++p; - if (*p >= '0' && *p <= '9') - c = (c << 4) + *p - '0'; - else if (*p >= 'a' && *p <= 'f') - c = (c << 4) + *p - 'a' + 10; - else if (*p >= 'A' && *p <= 'F') - c = (c << 4) + *p - 'A' + 10; - else - continue; - } - *data++ = c; - } else if (*p >= '0' && *p <= '7') { // oct (\\7, or \\77, or \\377) - char c = *p - '0'; - if (p + 1 < e && p[1] >= '0' && p[1] <= '7') { - c = (c << 3) + *(++p) - '0'; - if (p + 1 < e && p[1] >= '0' && p[1] <= '7' && p[-1] <= '3') - c = (c << 3) + *(++p) - '0'; - } - *data++ = c; - } else if (*p == 'n') { - *data++ = '\n'; - } else if (*p == 'r') { - *data++ = '\r'; - } else { // escaped - *data++ = *p; - } - } else { - *data++ = *p; - } - } - pattern.truncate(data - pattern.data()); - - return pattern; -} - -MimeMagicRule::MimeMagicRule(MimeMagicRule::Type theType, - const QByteArray &theValue, - int theStartPos, - int theEndPos, - const QByteArray &theMask, - QString *errorString) : - d(new MimeMagicRulePrivate) -{ - d->type = theType; - d->value = theValue; - d->startPos = theStartPos; - d->endPos = theEndPos; - d->mask = theMask; - d->matchFunction = nullptr; - - if (d->value.isEmpty()) { - d->type = Invalid; - if (errorString) - *errorString = QLatin1String("Invalid empty magic rule value"); - return; - } - - if (d->type >= Host16 && d->type <= Byte) { - bool ok; - d->number = d->value.toUInt(&ok, 0); // autodetect - if (!ok) { - d->type = Invalid; - if (errorString) - *errorString = QString::fromLatin1("Invalid magic rule value \"%1\"").arg( - QString::fromLatin1(d->value)); - return; - } - d->numberMask = !d->mask.isEmpty() ? d->mask.toUInt(&ok, 0) : 0; // autodetect - } - - switch (d->type) { - case String: - d->pattern = makePattern(d->value); - d->pattern.squeeze(); - if (!d->mask.isEmpty()) { - if (d->mask.size() < 4 || !d->mask.startsWith("0x")) { - d->type = Invalid; - if (errorString) - *errorString = QString::fromLatin1("Invalid magic rule mask \"%1\"").arg( - QString::fromLatin1(d->mask)); - return; - } - const QByteArray &tempMask = QByteArray::fromHex(QByteArray::fromRawData( - d->mask.constData() + 2, d->mask.size() - 2)); - if (tempMask.size() != d->pattern.size()) { - d->type = Invalid; - if (errorString) - *errorString = QString::fromLatin1("Invalid magic rule mask size \"%1\"").arg( - QString::fromLatin1(d->mask)); - return; - } - d->mask = tempMask; - } else { - d->mask.fill(char(-1), d->pattern.size()); - } - d->mask.squeeze(); - d->matchFunction = matchString; - break; - case RegExp: - d->regexp.setPatternOptions(QRegularExpression::MultilineOption - | QRegularExpression::DotMatchesEverythingOption - ); - d->regexp.setPattern(QString::fromUtf8(d->value)); - if (!d->regexp.isValid()) { - d->type = Invalid; - if (errorString) - *errorString = QString::fromLatin1("Invalid magic rule regexp value \"%1\"").arg( - QString::fromLatin1(d->value)); - return; - } - d->matchFunction = matchRegExp; - break; - case Byte: - if (d->number <= quint8(-1)) { - if (d->numberMask == 0) - d->numberMask = quint8(-1); - d->matchFunction = matchNumber; - } - break; - case Big16: - case Host16: - case Little16: - if (d->number <= quint16(-1)) { - d->number = d->type == Little16 ? qFromLittleEndian(d->number) : qFromBigEndian(d->number); - if (d->numberMask == 0) - d->numberMask = quint16(-1); - d->matchFunction = matchNumber; - } - break; - case Big32: - case Host32: - case Little32: - if (d->number <= quint32(-1)) { - d->number = d->type == Little32 ? qFromLittleEndian(d->number) : qFromBigEndian(d->number); - if (d->numberMask == 0) - d->numberMask = quint32(-1); - d->matchFunction = matchNumber; - } - break; - default: - break; - } -} - -MimeMagicRule::MimeMagicRule(const MimeMagicRule &other) - : m_subMatches(other.m_subMatches) - , d(new MimeMagicRulePrivate(*other.d)) -{ -} - -MimeMagicRule::~MimeMagicRule() = default; - -MimeMagicRule &MimeMagicRule::operator=(const MimeMagicRule &other) -{ - *d = *other.d; - m_subMatches = other.m_subMatches; - return *this; -} - -bool MimeMagicRule::operator==(const MimeMagicRule &other) const -{ - return (d == other.d || *d == *other.d) && m_subMatches == other.m_subMatches; -} - -MimeMagicRule::Type MimeMagicRule::type() const -{ - return d->type; -} - -QByteArray MimeMagicRule::value() const -{ - return d->value; -} - -int MimeMagicRule::startPos() const -{ - return d->startPos; -} - -int MimeMagicRule::endPos() const -{ - return d->endPos; -} - -QByteArray MimeMagicRule::mask() const -{ - QByteArray result = d->mask; - if (d->type == String) { - // restore '0x' - result = "0x" + result.toHex(); - } - return result; -} - -bool MimeMagicRule::isValid() const -{ - return d->matchFunction; -} - -bool MimeMagicRule::matches(const QByteArray &data) const -{ - const bool ok = d->matchFunction && d->matchFunction(d.data(), data); - if (!ok) - return false; - - // No submatch? Then we are done. - if (m_subMatches.isEmpty()) - return true; - - //qDebug() << "Checking" << m_subMatches.count() << "sub-rules"; - // Check that one of the submatches matches too - for ( QList::const_iterator it = m_subMatches.begin(), end = m_subMatches.end() ; - it != end ; ++it ) { - if ((*it).matches(data)) { - // One of the hierarchies matched -> mimetype recognized. - return true; - } - } - return false; - - -} diff --git a/src/libs/utils/mimetypes/mimemagicrule_p.h b/src/libs/utils/mimetypes/mimemagicrule_p.h deleted file mode 100644 index 142d6a40c23..00000000000 --- a/src/libs/utils/mimetypes/mimemagicrule_p.h +++ /dev/null @@ -1,71 +0,0 @@ -// Copyright (C) 2016 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR LGPL-3.0 - -#pragma once - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include - -#include -#include -#include -#include - -namespace Utils { - -class MimeType; - -namespace Internal { -class MimeMagicRulePrivate; -} - -class QTCREATOR_UTILS_EXPORT MimeMagicRule -{ -public: - enum Type { Invalid = 0, String, RegExp, Host16, Host32, Big16, Big32, Little16, Little32, Byte }; - - MimeMagicRule(Type type, const QByteArray &value, int startPos, int endPos, - const QByteArray &mask = QByteArray(), QString *errorString = nullptr); - MimeMagicRule(const MimeMagicRule &other); - ~MimeMagicRule(); - - MimeMagicRule &operator=(const MimeMagicRule &other); - - bool operator==(const MimeMagicRule &other) const; - - Type type() const; - QByteArray value() const; - int startPos() const; - int endPos() const; - QByteArray mask() const; - - bool isValid() const; - - bool matches(const QByteArray &data) const; - - QList m_subMatches; - - static Type type(const QByteArray &type); - static QByteArray typeName(Type type); - - static bool matchSubstring(const char *dataPtr, int dataSize, int rangeStart, int rangeLength, int valueLength, const char *valueData, const char *mask); - -private: - const QScopedPointer d; -}; - -} // Utils - -QT_BEGIN_NAMESPACE -Q_DECLARE_TYPEINFO(Utils::MimeMagicRule, Q_MOVABLE_TYPE); -QT_END_NAMESPACE diff --git a/src/libs/utils/mimetypes/mimemagicrulematcher.cpp b/src/libs/utils/mimetypes/mimemagicrulematcher.cpp deleted file mode 100644 index 5f7161019c6..00000000000 --- a/src/libs/utils/mimetypes/mimemagicrulematcher.cpp +++ /dev/null @@ -1,67 +0,0 @@ -// Copyright (C) 2016 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR LGPL-3.0 - -#include "mimemagicrulematcher_p.h" - -#include "mimetype_p.h" - -using namespace Utils; -using namespace Utils::Internal; - -/*! - \internal - \class MimeMagicRuleMatcher - \inmodule QtCore - - \brief The MimeMagicRuleMatcher class checks a number of rules based on operator "or". - - It is used for rules parsed from XML files. - - \sa MimeType, MimeDatabase, MagicRule, MagicStringRule, MagicByteRule, GlobPattern - \sa MimeTypeParserBase, MimeTypeParser -*/ - -MimeMagicRuleMatcher::MimeMagicRuleMatcher(const QString &mime, unsigned thePriority) : - m_list(), - m_priority(thePriority), - m_mimetype(mime) -{ -} - -bool MimeMagicRuleMatcher::operator==(const MimeMagicRuleMatcher &other) const -{ - return m_list == other.m_list && - m_priority == other.m_priority; -} - -void MimeMagicRuleMatcher::addRule(const MimeMagicRule &rule) -{ - m_list.append(rule); -} - -void MimeMagicRuleMatcher::addRules(const QList &rules) -{ - m_list.append(rules); -} - -QList MimeMagicRuleMatcher::magicRules() const -{ - return m_list; -} - -// Check for a match on contents of a file -bool MimeMagicRuleMatcher::matches(const QByteArray &data) const -{ - for (const MimeMagicRule &magicRule : m_list) { - if (magicRule.matches(data)) - return true; - } - - return false; -} - -// Return a priority value from 1..100 -unsigned MimeMagicRuleMatcher::priority() const -{ - return m_priority; -} diff --git a/src/libs/utils/mimetypes/mimemagicrulematcher_p.h b/src/libs/utils/mimetypes/mimemagicrulematcher_p.h deleted file mode 100644 index a33a1d849ab..00000000000 --- a/src/libs/utils/mimetypes/mimemagicrulematcher_p.h +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright (C) 2016 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR LGPL-3.0 - -#pragma once - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include "mimemagicrule_p.h" - -#include -#include -#include - - -namespace Utils { -namespace Internal { - -class MimeMagicRuleMatcher -{ -public: - explicit MimeMagicRuleMatcher(const QString &mime, unsigned priority = 65535); - - bool operator==(const MimeMagicRuleMatcher &other) const; - - void addRule(const MimeMagicRule &rule); - void addRules(const QList &rules); - QList magicRules() const; - - bool matches(const QByteArray &data) const; - - unsigned priority() const; - - QString mimetype() const { return m_mimetype; } - -private: - QList m_list; - unsigned m_priority; - QString m_mimetype; -}; - -} // Internal -} // Utils diff --git a/src/libs/utils/mimetypes/mimeprovider.cpp b/src/libs/utils/mimetypes/mimeprovider.cpp deleted file mode 100644 index 03574a157f4..00000000000 --- a/src/libs/utils/mimetypes/mimeprovider.cpp +++ /dev/null @@ -1,871 +0,0 @@ -// Copyright (C) 2016 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR LGPL-3.0 - -#include "mimeprovider_p.h" - -#include "mimetypeparser_p.h" -#include -#include "mimemagicrulematcher_p.h" - -#include -#include -#include -#include -#include -#include -#include -#include - -using namespace Utils; -using namespace Utils::Internal; - -static QString fallbackParent(const QString &mimeTypeName) -{ - const QString myGroup = mimeTypeName.left(mimeTypeName.indexOf(QLatin1Char('/'))); - // All text/* types are subclasses of text/plain. - if (myGroup == QLatin1String("text") && mimeTypeName != QLatin1String("text/plain")) - return QLatin1String("text/plain"); - // All real-file mimetypes implicitly derive from application/octet-stream - if (myGroup != QLatin1String("inode") && - // ignore non-file extensions - myGroup != QLatin1String("all") && myGroup != QLatin1String("fonts") && myGroup != QLatin1String("print") && myGroup != QLatin1String("uri") - && mimeTypeName != QLatin1String("application/octet-stream")) { - return QLatin1String("application/octet-stream"); - } - return QString(); -} - -MimeProviderBase::MimeProviderBase(MimeDatabasePrivate *db) - : m_db(db) -{ -} - -static int mime_secondsBetweenChecks = 5; - -bool MimeProviderBase::shouldCheck() -{ - const QDateTime now = QDateTime::currentDateTime(); - if (m_lastCheck.isValid() && m_lastCheck.secsTo(now) < mime_secondsBetweenChecks) - return false; - m_lastCheck = now; - return true; -} - -//MimeBinaryProvider::MimeBinaryProvider(MimeDatabasePrivate *db) -// : MimeProviderBase(db), m_mimetypeListLoaded(false) -//{ -//} - -//#if defined(Q_OS_UNIX) && !defined(Q_OS_INTEGRITY) -//#define QT_USE_MMAP -//#endif - -//struct MimeBinaryProvider::CacheFile -//{ -// CacheFile(const QString &fileName); -// ~CacheFile(); - -// bool isValid() const { return m_valid; } -// inline quint16 getUint16(int offset) const -// { -// return qFromBigEndian(*reinterpret_cast(data + offset)); -// } -// inline quint32 getUint32(int offset) const -// { -// return qFromBigEndian(*reinterpret_cast(data + offset)); -// } -// inline const char *getCharStar(int offset) const -// { -// return reinterpret_cast(data + offset); -// } -// bool load(); -// bool reload(); - -// QFile file; -// uchar *data; -// QDateTime m_mtime; -// bool m_valid; -//}; - -//MimeBinaryProvider::CacheFile::CacheFile(const QString &fileName) -// : file(fileName), m_valid(false) -//{ -// load(); -//} - -//MimeBinaryProvider::CacheFile::~CacheFile() -//{ -//} - -//bool MimeBinaryProvider::CacheFile::load() -//{ -// if (!file.open(QIODevice::ReadOnly)) -// return false; -// data = file.map(0, file.size()); -// if (data) { -// const int major = getUint16(0); -// const int minor = getUint16(2); -// m_valid = (major == 1 && minor >= 1 && minor <= 2); -// } -// m_mtime = QFileInfo(file).lastModified(); -// return m_valid; -//} - -//bool MimeBinaryProvider::CacheFile::reload() -//{ -// //qDebug() << "reload!" << file->fileName(); -// m_valid = false; -// if (file.isOpen()) { -// file.close(); -// } -// data = 0; -// return load(); -//} - -//MimeBinaryProvider::CacheFile *MimeBinaryProvider::CacheFileList::findCacheFile(const QString &fileName) const -//{ -// for (const_iterator it = begin(); it != end(); ++it) { -// if ((*it)->file.fileName() == fileName) -// return *it; -// } -// return 0; -//} - -//MimeBinaryProvider::~MimeBinaryProvider() -//{ -// qDeleteAll(m_cacheFiles); -//} - -//// Position of the "list offsets" values, at the beginning of the mime.cache file -//enum { -// PosAliasListOffset = 4, -// PosParentListOffset = 8, -// PosLiteralListOffset = 12, -// PosReverseSuffixTreeOffset = 16, -// PosGlobListOffset = 20, -// PosMagicListOffset = 24, -// // PosNamespaceListOffset = 28, -// PosIconsListOffset = 32, -// PosGenericIconsListOffset = 36 -//}; - -//bool MimeBinaryProvider::isValid() -//{ -//#if defined(QT_USE_MMAP) -// if (!qEnvironmentVariableIsEmpty("QT_NO_MIME_CACHE")) -// return false; - -// Q_ASSERT(m_cacheFiles.isEmpty()); // this method is only ever called once -// checkCache(); - -// if (m_cacheFiles.count() > 1) -// return true; -// if (m_cacheFiles.isEmpty()) -// return false; - -// // We found exactly one file; is it the user-modified mimes, or a system file? -// const QString foundFile = m_cacheFiles.first()->file.fileName(); -// const QString localCacheFile = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QLatin1String("/mime/mime.cache"); - -// return foundFile != localCacheFile; -//#else -// return false; -//#endif -//} - -//bool MimeBinaryProvider::CacheFileList::checkCacheChanged() -//{ -// bool somethingChanged = false; -// QMutableListIterator it(*this); -// while (it.hasNext()) { -// CacheFile *cacheFile = it.next(); -// QFileInfo fileInfo(cacheFile->file); -// if (!fileInfo.exists()) { // This can't happen by just running update-mime-database. But the user could use rm -rf :-) -// delete cacheFile; -// it.remove(); -// somethingChanged = true; -// } else if (fileInfo.lastModified() > cacheFile->m_mtime) { -// if (!cacheFile->reload()) { -// delete cacheFile; -// it.remove(); -// } -// somethingChanged = true; -// } -// } -// return somethingChanged; -//} - -//void MimeBinaryProvider::checkCache() -//{ -// if (!shouldCheck()) -// return; - -// // First iterate over existing known cache files and check for uptodate -// if (m_cacheFiles.checkCacheChanged()) -// m_mimetypeListLoaded = false; - -// // Then check if new cache files appeared -// const QStringList cacheFileNames = QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, QLatin1String("mime/mime.cache")); -// if (cacheFileNames != m_cacheFileNames) { -// for (const QString &cacheFileName : cacheFileNames) { -// CacheFile *cacheFile = m_cacheFiles.findCacheFile(cacheFileName); -// if (!cacheFile) { -// //qDebug() << "new file:" << cacheFileName; -// cacheFile = new CacheFile(cacheFileName); -// if (cacheFile->isValid()) // verify version -// m_cacheFiles.append(cacheFile); -// else -// delete cacheFile; -// } -// } -// m_cacheFileNames = cacheFileNames; -// m_mimetypeListLoaded = false; -// } -//} - -//static MimeType mimeTypeForNameUnchecked(const QString &name) -//{ -// MimeTypePrivate data; -// data.name = name; -// // The rest is retrieved on demand. -// // comment and globPatterns: in loadMimeTypePrivate -// // iconName: in loadIcon -// // genericIconName: in loadGenericIcon -// return MimeType(data); -//} - -//MimeType MimeBinaryProvider::mimeTypeForName(const QString &name) -//{ -// checkCache(); -// if (!m_mimetypeListLoaded) -// loadMimeTypeList(); -// if (!m_mimetypeNames.contains(name)) -// return MimeType(); // unknown mimetype -// return mimeTypeForNameUnchecked(name); -//} - -//QStringList MimeBinaryProvider::findByFileName(const QString &fileName, QString *foundSuffix) -//{ -// checkCache(); -// if (fileName.isEmpty()) -// return QStringList(); -// const QString lowerFileName = fileName.toLower(); -// MimeGlobMatchResult result; -// // TODO this parses in the order (local, global). Check that it handles "NOGLOBS" correctly. -// for (CacheFile *cacheFile : std::as_const(m_cacheFiles)) { -// matchGlobList(result, cacheFile, cacheFile->getUint32(PosLiteralListOffset), fileName); -// matchGlobList(result, cacheFile, cacheFile->getUint32(PosGlobListOffset), fileName); -// const int reverseSuffixTreeOffset = cacheFile->getUint32(PosReverseSuffixTreeOffset); -// const int numRoots = cacheFile->getUint32(reverseSuffixTreeOffset); -// const int firstRootOffset = cacheFile->getUint32(reverseSuffixTreeOffset + 4); -// matchSuffixTree(result, cacheFile, numRoots, firstRootOffset, lowerFileName, fileName.length() - 1, false); -// if (result.m_matchingMimeTypes.isEmpty()) -// matchSuffixTree(result, cacheFile, numRoots, firstRootOffset, fileName, fileName.length() - 1, true); -// } -// if (foundSuffix) -// *foundSuffix = result.m_foundSuffix; -// return result.m_matchingMimeTypes; -//} - -//void MimeBinaryProvider::matchGlobList(MimeGlobMatchResult &result, CacheFile *cacheFile, int off, const QString &fileName) -//{ -// const int numGlobs = cacheFile->getUint32(off); -// //qDebug() << "Loading" << numGlobs << "globs from" << cacheFile->file.fileName() << "at offset" << cacheFile->globListOffset; -// for (int i = 0; i < numGlobs; ++i) { -// const int globOffset = cacheFile->getUint32(off + 4 + 12 * i); -// const int mimeTypeOffset = cacheFile->getUint32(off + 4 + 12 * i + 4); -// const int flagsAndWeight = cacheFile->getUint32(off + 4 + 12 * i + 8); -// const int weight = flagsAndWeight & 0xff; -// const bool caseSensitive = flagsAndWeight & 0x100; -// const Qt::CaseSensitivity qtCaseSensitive = caseSensitive ? Qt::CaseSensitive : Qt::CaseInsensitive; -// const QString pattern = QLatin1String(cacheFile->getCharStar(globOffset)); - -// const char *mimeType = cacheFile->getCharStar(mimeTypeOffset); -// //qDebug() << pattern << mimeType << weight << caseSensitive; -// MimeGlobPattern glob(pattern, QString() /*unused*/, weight, qtCaseSensitive); - -// // TODO: this could be done faster for literals where a simple == would do. -// if (glob.matchFileName(fileName)) -// result.addMatch(QLatin1String(mimeType), weight, pattern); -// } -//} - -//bool MimeBinaryProvider::matchSuffixTree(MimeGlobMatchResult &result, MimeBinaryProvider::CacheFile *cacheFile, int numEntries, int firstOffset, const QString &fileName, int charPos, bool caseSensitiveCheck) -//{ -// QChar fileChar = fileName[charPos]; -// int min = 0; -// int max = numEntries - 1; -// while (min <= max) { -// const int mid = (min + max) / 2; -// const int off = firstOffset + 12 * mid; -// const QChar ch = cacheFile->getUint32(off); -// if (ch < fileChar) -// min = mid + 1; -// else if (ch > fileChar) -// max = mid - 1; -// else { -// --charPos; -// int numChildren = cacheFile->getUint32(off + 4); -// int childrenOffset = cacheFile->getUint32(off + 8); -// bool success = false; -// if (charPos > 0) -// success = matchSuffixTree(result, cacheFile, numChildren, childrenOffset, fileName, charPos, caseSensitiveCheck); -// if (!success) { -// for (int i = 0; i < numChildren; ++i) { -// const int childOff = childrenOffset + 12 * i; -// const int mch = cacheFile->getUint32(childOff); -// if (mch != 0) -// break; -// const int mimeTypeOffset = cacheFile->getUint32(childOff + 4); -// const char *mimeType = cacheFile->getCharStar(mimeTypeOffset); -// const int flagsAndWeight = cacheFile->getUint32(childOff + 8); -// const int weight = flagsAndWeight & 0xff; -// const bool caseSensitive = flagsAndWeight & 0x100; -// if (caseSensitiveCheck || !caseSensitive) { -// result.addMatch(QLatin1String(mimeType), weight, QLatin1Char('*') + fileName.mid(charPos+1)); -// success = true; -// } -// } -// } -// return success; -// } -// } -// return false; -//} - -//bool MimeBinaryProvider::matchMagicRule(MimeBinaryProvider::CacheFile *cacheFile, int numMatchlets, int firstOffset, const QByteArray &data) -//{ -// const char *dataPtr = data.constData(); -// const int dataSize = data.size(); -// for (int matchlet = 0; matchlet < numMatchlets; ++matchlet) { -// const int off = firstOffset + matchlet * 32; -// const int rangeStart = cacheFile->getUint32(off); -// const int rangeLength = cacheFile->getUint32(off + 4); -// //const int wordSize = cacheFile->getUint32(off + 8); -// const int valueLength = cacheFile->getUint32(off + 12); -// const int valueOffset = cacheFile->getUint32(off + 16); -// const int maskOffset = cacheFile->getUint32(off + 20); -// const char *mask = maskOffset ? cacheFile->getCharStar(maskOffset) : NULL; - -// if (!MimeMagicRule::matchSubstring(dataPtr, dataSize, rangeStart, rangeLength, valueLength, cacheFile->getCharStar(valueOffset), mask)) -// continue; - -// const int numChildren = cacheFile->getUint32(off + 24); -// const int firstChildOffset = cacheFile->getUint32(off + 28); -// if (numChildren == 0) // No submatch? Then we are done. -// return true; -// // Check that one of the submatches matches too -// if (matchMagicRule(cacheFile, numChildren, firstChildOffset, data)) -// return true; -// } -// return false; -//} - -//MimeType MimeBinaryProvider::findByMagic(const QByteArray &data, int *accuracyPtr) -//{ -// checkCache(); -// for (CacheFile *cacheFile : std::as_const(m_cacheFiles)) { -// const int magicListOffset = cacheFile->getUint32(PosMagicListOffset); -// const int numMatches = cacheFile->getUint32(magicListOffset); -// //const int maxExtent = cacheFile->getUint32(magicListOffset + 4); -// const int firstMatchOffset = cacheFile->getUint32(magicListOffset + 8); - -// for (int i = 0; i < numMatches; ++i) { -// const int off = firstMatchOffset + i * 16; -// const int numMatchlets = cacheFile->getUint32(off + 8); -// const int firstMatchletOffset = cacheFile->getUint32(off + 12); -// if (matchMagicRule(cacheFile, numMatchlets, firstMatchletOffset, data)) { -// const int mimeTypeOffset = cacheFile->getUint32(off + 4); -// const char *mimeType = cacheFile->getCharStar(mimeTypeOffset); -// *accuracyPtr = cacheFile->getUint32(off); -// // Return the first match. We have no rules for conflicting magic data... -// // (mime.cache itself is sorted, but what about local overrides with a lower prio?) -// return mimeTypeForNameUnchecked(QLatin1String(mimeType)); -// } -// } -// } -// return MimeType(); -//} - -//QStringList MimeBinaryProvider::parents(const QString &mime) -//{ -// checkCache(); -// const QByteArray mimeStr = mime.toLatin1(); -// QStringList result; -// for (CacheFile *cacheFile : std::as_const(m_cacheFiles)) { -// const int parentListOffset = cacheFile->getUint32(PosParentListOffset); -// const int numEntries = cacheFile->getUint32(parentListOffset); - -// int begin = 0; -// int end = numEntries - 1; -// while (begin <= end) { -// const int medium = (begin + end) / 2; -// const int off = parentListOffset + 4 + 8 * medium; -// const int mimeOffset = cacheFile->getUint32(off); -// const char *aMime = cacheFile->getCharStar(mimeOffset); -// const int cmp = qstrcmp(aMime, mimeStr); -// if (cmp < 0) { -// begin = medium + 1; -// } else if (cmp > 0) { -// end = medium - 1; -// } else { -// const int parentsOffset = cacheFile->getUint32(off + 4); -// const int numParents = cacheFile->getUint32(parentsOffset); -// for (int i = 0; i < numParents; ++i) { -// const int parentOffset = cacheFile->getUint32(parentsOffset + 4 + 4 * i); -// const char *aParent = cacheFile->getCharStar(parentOffset); -// result.append(QString::fromLatin1(aParent)); -// } -// break; -// } -// } -// } -// if (result.isEmpty()) { -// const QString parent = fallbackParent(mime); -// if (!parent.isEmpty()) -// result.append(parent); -// } -// return result; -//} - -//QString MimeBinaryProvider::resolveAlias(const QString &name) -//{ -// checkCache(); -// const QByteArray input = name.toLatin1(); -// for (CacheFile *cacheFile : std::as_const(m_cacheFiles)) { -// const int aliasListOffset = cacheFile->getUint32(PosAliasListOffset); -// const int numEntries = cacheFile->getUint32(aliasListOffset); -// int begin = 0; -// int end = numEntries - 1; -// while (begin <= end) { -// const int medium = (begin + end) / 2; -// const int off = aliasListOffset + 4 + 8 * medium; -// const int aliasOffset = cacheFile->getUint32(off); -// const char *alias = cacheFile->getCharStar(aliasOffset); -// const int cmp = qstrcmp(alias, input); -// if (cmp < 0) { -// begin = medium + 1; -// } else if (cmp > 0) { -// end = medium - 1; -// } else { -// const int mimeOffset = cacheFile->getUint32(off + 4); -// const char *mimeType = cacheFile->getCharStar(mimeOffset); -// return QLatin1String(mimeType); -// } -// } -// } - -// return name; -//} - -//QStringList MimeBinaryProvider::listAliases(const QString &name) -//{ -// checkCache(); -// QStringList result; -// const QByteArray input = name.toLatin1(); -// for (CacheFile *cacheFile : std::as_const(m_cacheFiles)) { -// const int aliasListOffset = cacheFile->getUint32(PosAliasListOffset); -// const int numEntries = cacheFile->getUint32(aliasListOffset); -// for (int pos = 0; pos < numEntries; ++pos) { -// const int off = aliasListOffset + 4 + 8 * pos; -// const int mimeOffset = cacheFile->getUint32(off + 4); -// const char *mimeType = cacheFile->getCharStar(mimeOffset); - -// if (input == mimeType) { -// const int aliasOffset = cacheFile->getUint32(off); -// const char *alias = cacheFile->getCharStar(aliasOffset); -// result.append(QString::fromLatin1(alias)); -// } -// } -// } -// return result; -//} - -//void MimeBinaryProvider::loadMimeTypeList() -//{ -// if (!m_mimetypeListLoaded) { -// m_mimetypeListLoaded = true; -// m_mimetypeNames.clear(); -// // Unfortunately mime.cache doesn't have a full list of all mimetypes. -// // So we have to parse the plain-text files called "types". -// const QStringList typesFilenames = QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, QLatin1String("mime/types")); -// for (const QString &typeFilename : typesFilenames) { -// QFile file(typeFilename); -// if (file.open(QIODevice::ReadOnly)) { -// while (!file.atEnd()) { -// QByteArray line = file.readLine(); -// line.chop(1); -// m_mimetypeNames.insert(QString::fromLatin1(line.constData(), line.size())); -// } -// } -// } -// } -//} - -//QList MimeBinaryProvider::allMimeTypes() -//{ -// QList result; -// loadMimeTypeList(); - -// for (QSet::const_iterator it = m_mimetypeNames.constBegin(); -// it != m_mimetypeNames.constEnd(); ++it) -// result.append(mimeTypeForNameUnchecked(*it)); - -// return result; -//} - -//void MimeBinaryProvider::loadMimeTypePrivate(MimeTypePrivate &data) -//{ -//#ifdef QT_NO_XMLSTREAMREADER -// qWarning() << "Cannot load mime type since QXmlStreamReader is not available."; -// return; -//#else -// if (data.loaded) -// return; -// data.loaded = true; -// // load comment and globPatterns - -// const QString file = data.name + QLatin1String(".xml"); -// const QStringList mimeFiles = QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, QString::fromLatin1("mime/") + file); -// if (mimeFiles.isEmpty()) { -// // TODO: ask Thiago about this -// qWarning() << "No file found for" << file << ", even though the file appeared in a directory listing."; -// qWarning() << "Either it was just removed, or the directory doesn't have executable permission..."; -// qWarning() << QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, QLatin1String("mime"), QStandardPaths::LocateDirectory); -// return; -// } - -// QString comment; -// QString mainPattern; -// const QString preferredLanguage = QLocale::system().name(); - -// QListIterator mimeFilesIter(mimeFiles); -// mimeFilesIter.toBack(); -// while (mimeFilesIter.hasPrevious()) { // global first, then local. -// const QString fullPath = mimeFilesIter.previous(); -// QFile qfile(fullPath); -// if (!qfile.open(QFile::ReadOnly)) -// continue; - -// QXmlStreamReader xml(&qfile); -// if (xml.readNextStartElement()) { -// if (xml.name() != QLatin1String("mime-type")) { -// continue; -// } -// const QString name = xml.attributes().value(QLatin1String("type")).toString(); -// if (name.isEmpty()) -// continue; -// if (name != data.name) { -// qWarning() << "Got name" << name << "in file" << file << "expected" << data.name; -// } - -// while (xml.readNextStartElement()) { -// const QStringRef tag = xml.name(); -// if (tag == QLatin1String("comment")) { -// QString lang = xml.attributes().value(QLatin1String("xml:lang")).toString(); -// const QString text = xml.readElementText(); -// if (lang.isEmpty()) { -// lang = QLatin1String("en_US"); -// } -// data.localeComments.insert(lang, text); -// continue; // we called readElementText, so we're at the EndElement already. -// } else if (tag == QLatin1String("icon")) { // as written out by shared-mime-info >= 0.40 -// data.iconName = xml.attributes().value(QLatin1String("name")).toString(); -// } else if (tag == QLatin1String("glob-deleteall")) { // as written out by shared-mime-info >= 0.70 -// data.globPatterns.clear(); -// } else if (tag == QLatin1String("glob")) { // as written out by shared-mime-info >= 0.70 -// const QString pattern = xml.attributes().value(QLatin1String("pattern")).toString(); -// if (mainPattern.isEmpty() && pattern.startsWith(QLatin1Char('*'))) { -// mainPattern = pattern; -// } -// if (!data.globPatterns.contains(pattern)) -// data.globPatterns.append(pattern); -// } -// xml.skipCurrentElement(); -// } -// Q_ASSERT(xml.name() == QLatin1String("mime-type")); -// } -// } - -// // Let's assume that shared-mime-info is at least version 0.70 -// // Otherwise we would need 1) a version check, and 2) code for parsing patterns from the globs file. -//#if 1 -// if (!mainPattern.isEmpty() && data.globPatterns.first() != mainPattern) { -// // ensure it's first in the list of patterns -// data.globPatterns.removeAll(mainPattern); -// data.globPatterns.prepend(mainPattern); -// } -//#else -// const bool globsInXml = sharedMimeInfoVersion() >= QT_VERSION_CHECK(0, 70, 0); -// if (globsInXml) { -// if (!mainPattern.isEmpty() && data.globPatterns.first() != mainPattern) { -// // ensure it's first in the list of patterns -// data.globPatterns.removeAll(mainPattern); -// data.globPatterns.prepend(mainPattern); -// } -// } else { -// // Fallback: get the patterns from the globs file -// // TODO: This would be the only way to support shared-mime-info < 0.70 -// // But is this really worth the effort? -// } -//#endif -//#endif //QT_NO_XMLSTREAMREADER -//} - -//// Binary search in the icons or generic-icons list -//QString MimeBinaryProvider::iconForMime(CacheFile *cacheFile, int posListOffset, const QByteArray &inputMime) -//{ -// const int iconsListOffset = cacheFile->getUint32(posListOffset); -// const int numIcons = cacheFile->getUint32(iconsListOffset); -// int begin = 0; -// int end = numIcons - 1; -// while (begin <= end) { -// const int medium = (begin + end) / 2; -// const int off = iconsListOffset + 4 + 8 * medium; -// const int mimeOffset = cacheFile->getUint32(off); -// const char *mime = cacheFile->getCharStar(mimeOffset); -// const int cmp = qstrcmp(mime, inputMime); -// if (cmp < 0) -// begin = medium + 1; -// else if (cmp > 0) -// end = medium - 1; -// else { -// const int iconOffset = cacheFile->getUint32(off + 4); -// return QLatin1String(cacheFile->getCharStar(iconOffset)); -// } -// } -// return QString(); -//} - -//void MimeBinaryProvider::loadIcon(MimeTypePrivate &data) -//{ -// checkCache(); -// const QByteArray inputMime = data.name.toLatin1(); -// for (CacheFile *cacheFile : std::as_const(m_cacheFiles)) { -// const QString icon = iconForMime(cacheFile, PosIconsListOffset, inputMime); -// if (!icon.isEmpty()) { -// data.iconName = icon; -// return; -// } -// } -//} - -//void MimeBinaryProvider::loadGenericIcon(MimeTypePrivate &data) -//{ -// checkCache(); -// const QByteArray inputMime = data.name.toLatin1(); -// for (CacheFile *cacheFile : std::as_const(m_cacheFiles)) { -// const QString icon = iconForMime(cacheFile, PosGenericIconsListOffset, inputMime); -// if (!icon.isEmpty()) { -// data.genericIconName = icon; -// return; -// } -// } -//} - -//// - -MimeXMLProvider::MimeXMLProvider(MimeDatabasePrivate *db) - : MimeProviderBase(db), m_loaded(false) -{ -} - -bool MimeXMLProvider::isValid() -{ - return true; -} - -MimeType MimeXMLProvider::mimeTypeForName(const QString &name) -{ - ensureLoaded(); - - return m_nameMimeTypeMap.value(name); -} - -QStringList MimeXMLProvider::findByFileName(const QString &fileName, QString *foundSuffix) -{ - ensureLoaded(); - - const QStringList matchingMimeTypes = m_mimeTypeGlobs.matchingGlobs(fileName, foundSuffix); - return matchingMimeTypes; -} - -MimeType MimeXMLProvider::findByMagic(const QByteArray &data, int *accuracyPtr) -{ - ensureLoaded(); - - QString candidate; - - for (const MimeMagicRuleMatcher &matcher : std::as_const(m_magicMatchers)) { - if (matcher.matches(data)) { - const int priority = matcher.priority(); - if (priority > *accuracyPtr) { - *accuracyPtr = priority; - candidate = matcher.mimetype(); - } - } - } - return mimeTypeForName(candidate); -} - -QMap > MimeXMLProvider::magicRulesForMimeType(const MimeType &mimeType) -{ - QMap > result; - for (const MimeMagicRuleMatcher &matcher : std::as_const(m_magicMatchers)) { - if (mimeType.matchesName(matcher.mimetype())) - result[matcher.priority()].append(matcher.magicRules()); - } - return result; -} - -void MimeXMLProvider::setGlobPatternsForMimeType(const MimeType &mimeType, const QStringList &patterns) -{ - // remove all previous globs - m_mimeTypeGlobs.removeMimeType(mimeType.name()); - // add new patterns as case-insensitive default-weight patterns - for (const QString &pattern : patterns) - addGlobPattern(MimeGlobPattern(pattern, mimeType.name())); - mimeType.d->globPatterns = patterns; -} - -void MimeXMLProvider::setMagicRulesForMimeType(const MimeType &mimeType, const QMap > &rules) -{ - // remove all previous rules - for (int i = 0; i < m_magicMatchers.size(); ++i) { - if (m_magicMatchers.at(i).mimetype() == mimeType.name()) - m_magicMatchers.removeAt(i--); - } - // add new rules - for (auto it = rules.cbegin(); it != rules.cend(); ++it) { - MimeMagicRuleMatcher matcher(mimeType.name(), it.key()/*priority*/); - matcher.addRules(it.value()); - addMagicMatcher(matcher); - } -} - -void MimeXMLProvider::ensureLoaded() -{ - if (!m_loaded /*|| shouldCheck()*/) { - m_loaded = true; - QStringList allFiles = QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, - QStringLiteral("mime/packages/freedesktop.org.xml"), - QStandardPaths::LocateFile); - - if (allFiles.isEmpty()) { - // System freedsktop.org.xml file not found, use our bundled copy - const char freedesktopOrgXml[] = ":/utils/mimetypes/freedesktop.org.xml"; - allFiles.prepend(QLatin1String(freedesktopOrgXml)); - } - - m_nameMimeTypeMap.clear(); - m_aliases.clear(); - m_parents.clear(); - m_mimeTypeGlobs.clear(); - m_magicMatchers.clear(); - - //qDebug() << "Loading" << m_allFiles; - - // add custom mime types first, which override any default from freedesktop.org.xml - MimeTypeParser parser(*this); - for (auto it = m_additionalData.constBegin(), end = m_additionalData.constEnd(); it != end; ++it) { - QString errorMessage; - if (!parser.parse(it.value(), it.key(), &errorMessage)) { - qWarning("MimeDatabase: Error loading %s\n%s", qPrintable(it.key()), - qPrintable(errorMessage)); - } - } - - for (const QString &file : std::as_const(allFiles)) - load(file); - } -} - -void MimeXMLProvider::load(const QString &fileName) -{ - QString errorMessage; - if (!load(fileName, &errorMessage)) - qWarning("MimeDatabase: Error loading %s\n%s", qPrintable(fileName), qPrintable(errorMessage)); -} - -bool MimeXMLProvider::load(const QString &fileName, QString *errorMessage) -{ - m_loaded = true; - - QFile file(fileName); - if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { - if (errorMessage) - *errorMessage = QString::fromLatin1("Cannot open %1: %2").arg(fileName, file.errorString()); - return false; - } - - if (errorMessage) - errorMessage->clear(); - - const QByteArray content = file.readAll(); - MimeTypeParser parser(*this); - return parser.parse(content, fileName, errorMessage); -} - -void MimeXMLProvider::addGlobPattern(const MimeGlobPattern &glob) -{ - m_mimeTypeGlobs.addGlob(glob); -} - -void MimeXMLProvider::addMimeType(const MimeType &mt) -{ - m_nameMimeTypeMap.insert(mt.name(), mt); -} - -QStringList MimeXMLProvider::parents(const QString &mime) -{ - ensureLoaded(); - QStringList result = m_parents.value(mime); - if (result.isEmpty()) { - const QString parent = fallbackParent(mime); - if (!parent.isEmpty()) - result.append(parent); - } - return result; -} - -void MimeXMLProvider::addParent(const QString &child, const QString &parent) -{ - m_parents[child].append(parent); -} - -QStringList MimeXMLProvider::listAliases(const QString &name) -{ - ensureLoaded(); - // Iterate through the whole hash. This method is rarely used. - return m_aliases.keys(name); -} - -QString MimeXMLProvider::resolveAlias(const QString &name) -{ - ensureLoaded(); - return m_aliases.value(name, name); -} - -void MimeXMLProvider::addAlias(const QString &alias, const QString &name) -{ - m_aliases.insert(alias, name); -} - -QList MimeXMLProvider::allMimeTypes() -{ - ensureLoaded(); - return m_nameMimeTypeMap.values(); -} - -void MimeXMLProvider::addMagicMatcher(const MimeMagicRuleMatcher &matcher) -{ - m_magicMatchers.append(matcher); -} - -void MimeXMLProvider::addData(const QString &id, const QByteArray &data) -{ - if (m_additionalData.contains(id)) - qWarning("Overwriting data in mime database, id '%s'", qPrintable(id)); - m_additionalData.insert(id, data); - m_loaded = false; // force reload to ensure correct load order for overridden mime types -} diff --git a/src/libs/utils/mimetypes/mimeprovider_p.h b/src/libs/utils/mimetypes/mimeprovider_p.h deleted file mode 100644 index b2f1ef15757..00000000000 --- a/src/libs/utils/mimetypes/mimeprovider_p.h +++ /dev/null @@ -1,155 +0,0 @@ -// Copyright (C) 2016 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR LGPL-3.0 - -#pragma once - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include "mimedatabase_p.h" -#include "mimemagicrule_p.h" - -#include -#include - -namespace Utils { -namespace Internal { - -class MimeMagicRuleMatcher; - -class MimeProviderBase -{ -public: - MimeProviderBase(MimeDatabasePrivate *db); - virtual ~MimeProviderBase() {} - - virtual bool isValid() = 0; - virtual MimeType mimeTypeForName(const QString &name) = 0; - virtual QStringList findByFileName(const QString &fileName, QString *foundSuffix) = 0; - virtual QStringList parents(const QString &mime) = 0; - virtual QString resolveAlias(const QString &name) = 0; - virtual QStringList listAliases(const QString &name) = 0; - virtual MimeType findByMagic(const QByteArray &data, int *accuracyPtr) = 0; - virtual QList allMimeTypes() = 0; - virtual void loadMimeTypePrivate(MimeTypePrivate &) {} - virtual void loadIcon(MimeTypePrivate &) {} - virtual void loadGenericIcon(MimeTypePrivate &) {} - - // Qt Creator additions - virtual QMap > magicRulesForMimeType(const MimeType &mimeType) = 0; - virtual void setGlobPatternsForMimeType(const MimeType &mimeType, const QStringList &patterns) = 0; - virtual void setMagicRulesForMimeType(const MimeType &mimeType, const QMap > &rules) = 0; - - MimeDatabasePrivate *m_db; -protected: - bool shouldCheck(); - QDateTime m_lastCheck; -}; - -///* -// Parses the files 'mime.cache' and 'types' on demand -// */ -//class MimeBinaryProvider : public MimeProviderBase -//{ -//public: -// MimeBinaryProvider(MimeDatabasePrivate *db); -// virtual ~MimeBinaryProvider(); - -// virtual bool isValid(); -// virtual MimeType mimeTypeForName(const QString &name); -// virtual QStringList findByFileName(const QString &fileName, QString *foundSuffix); -// virtual QStringList parents(const QString &mime); -// virtual QString resolveAlias(const QString &name); -// virtual QStringList listAliases(const QString &name); -// virtual MimeType findByMagic(const QByteArray &data, int *accuracyPtr); -// virtual QList allMimeTypes(); -// virtual void loadMimeTypePrivate(MimeTypePrivate &); -// virtual void loadIcon(MimeTypePrivate &); -// virtual void loadGenericIcon(MimeTypePrivate &); - -//private: -// struct CacheFile; - -// void matchGlobList(MimeGlobMatchResult &result, CacheFile *cacheFile, int offset, const QString &fileName); -// bool matchSuffixTree(MimeGlobMatchResult &result, CacheFile *cacheFile, int numEntries, int firstOffset, const QString &fileName, int charPos, bool caseSensitiveCheck); -// bool matchMagicRule(CacheFile *cacheFile, int numMatchlets, int firstOffset, const QByteArray &data); -// QString iconForMime(CacheFile *cacheFile, int posListOffset, const QByteArray &inputMime); -// void loadMimeTypeList(); -// void checkCache(); - -// class CacheFileList : public QList -// { -// public: -// CacheFile *findCacheFile(const QString &fileName) const; -// bool checkCacheChanged(); -// }; -// CacheFileList m_cacheFiles; -// QStringList m_cacheFileNames; -// QSet m_mimetypeNames; -// bool m_mimetypeListLoaded; -//}; - -/* - Parses the raw XML files (slower) - */ -class MimeXMLProvider : public MimeProviderBase -{ -public: - MimeXMLProvider(MimeDatabasePrivate *db); - - bool isValid() override; - MimeType mimeTypeForName(const QString &name) override; - QStringList findByFileName(const QString &fileName, QString *foundSuffix) override; - QStringList parents(const QString &mime) override; - QString resolveAlias(const QString &name) override; - QStringList listAliases(const QString &name) override; - MimeType findByMagic(const QByteArray &data, int *accuracyPtr) override; - QList allMimeTypes() override; - - bool load(const QString &fileName, QString *errorMessage); - - // Called by the mimetype xml parser - void addMimeType(const MimeType &mt); - void addGlobPattern(const MimeGlobPattern &glob); - void addParent(const QString &child, const QString &parent); - void addAlias(const QString &alias, const QString &name); - void addMagicMatcher(const MimeMagicRuleMatcher &matcher); - - // Qt Creator additions - void addData(const QString &id, const QByteArray &data); - QMap > magicRulesForMimeType(const MimeType &mimeType) override; - void setGlobPatternsForMimeType(const MimeType &mimeType, const QStringList &patterns) override; - void setMagicRulesForMimeType(const MimeType &mimeType, const QMap > &rules) override; - -private: - void ensureLoaded(); - void load(const QString &fileName); - - bool m_loaded; - - typedef QHash NameMimeTypeMap; - NameMimeTypeMap m_nameMimeTypeMap; - - typedef QHash AliasHash; - AliasHash m_aliases; - - typedef QHash ParentsHash; - ParentsHash m_parents; - MimeAllGlobPatterns m_mimeTypeGlobs; - - QList m_magicMatchers; - - // Qt Creator additions - QHash m_additionalData; // id -> data -}; - -} // Internal -} // Utils diff --git a/src/libs/utils/mimetypes/mimetype.cpp b/src/libs/utils/mimetypes/mimetype.cpp deleted file mode 100644 index 3786d37a791..00000000000 --- a/src/libs/utils/mimetypes/mimetype.cpp +++ /dev/null @@ -1,423 +0,0 @@ -// Copyright (C) 2016 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR LGPL-3.0 - -#include "mimetype.h" - -#include "mimetype_p.h" -#include "mimedatabase_p.h" -#include "mimeprovider_p.h" - -#include "mimeglobpattern_p.h" - -#include -#include - -#include - -using namespace Utils; -using namespace Utils::Internal; - -static QString suffixFromPattern(const QString &pattern) -{ - // Not a simple suffix if it looks like: README or *. or *.* or *.JP*G or *.JP? - if (pattern.startsWith(QLatin1String("*.")) && - pattern.length() > 2 && - pattern.indexOf(QLatin1Char('*'), 2) < 0 && pattern.indexOf(QLatin1Char('?'), 2) < 0) { - return pattern.mid(2); - } - return QString(); -} - -MimeTypePrivate::MimeTypePrivate() - : loaded(false) -{} - -MimeTypePrivate::MimeTypePrivate(const MimeType &other) - : name(other.d->name), - localeComments(other.d->localeComments), - genericIconName(other.d->genericIconName), - iconName(other.d->iconName), - globPatterns(other.d->globPatterns), - loaded(other.d->loaded) -{} - -void MimeTypePrivate::clear() -{ - name.clear(); - localeComments.clear(); - genericIconName.clear(); - iconName.clear(); - globPatterns.clear(); - loaded = false; -} - -void MimeTypePrivate::addGlobPattern(const QString &pattern) -{ - globPatterns.append(pattern); -} - -/*! - \class MimeType - \inmodule QtCreator - \ingroup shared - \brief The MimeType class describes types of file or data, represented by a MIME type string. - - \since 5.0 - - For instance, a file named \c readme.txt has the MIME type \c text/plain. - The MIME type can be determined from the file name, or from the file - contents, or from both. MIME type determination can also be done on - buffers of data not coming from files. - - Determining the MIME type of a file can be useful to make sure your - application supports it. It is also useful in file-manager-like applications - or widgets, in order to display an appropriate \l {MimeType::iconName}{icon} for the file, or even - the descriptive \l {MimeType::comment()}{comment} in detailed views. - - To check if a file has the expected MIME type, you should use inherits() - rather than a simple string comparison based on the name(). This is because - MIME types can inherit from each other: for instance a C source file is - a specific type of plain text file, so \c text/x-csrc inherits \c text/plain. - */ - -/*! - Constructs this MimeType object initialized with default property values that indicate an invalid MIME type. - */ -MimeType::MimeType() : - d(new MimeTypePrivate()) -{ -} - -/*! - Constructs this MimeType object as a copy of \a other. - */ -MimeType::MimeType(const MimeType &other) = default; - -/*! - Assigns the data of \a other to this MimeType object, and returns a reference to this object. - */ -MimeType &MimeType::operator=(const MimeType &other) -{ - if (d != other.d) - d = other.d; - return *this; -} - -/*! - \fn MimeType::MimeType(const Internal::MimeTypePrivate &dd) - \internal - */ -MimeType::MimeType(const MimeTypePrivate &dd) : - d(new MimeTypePrivate(dd)) -{ -} - -/*! - Destroys the MimeType object, and releases the d pointer. - */ -MimeType::~MimeType() = default; - -/*! - Returns \c true if \a other equals this MimeType object, otherwise returns \c false. - The name is the unique identifier for a MIME type, so two MIME types with - the same name are equal. - */ -bool MimeType::operator==(const MimeType &other) const -{ - return d == other.d || d->name == other.d->name; -} - -/*! - \fn bool MimeType::operator!=(const MimeType &other) const; - Returns \c true if \a other does not equal this MimeType object, otherwise returns \c false. - */ - -/*! - \fn inline uint Utils::qHash(const MimeType &mime) - \internal -*/ - -/*! - Returns \c true if the MimeType object contains valid data, otherwise returns \c false. - A valid MIME type has a non-empty name(). - The invalid MIME type is the default-constructed MimeType. - */ -bool MimeType::isValid() const -{ - return !d->name.isEmpty(); -} - -/*! - Returns \c true if this MIME type is the default MIME type which - applies to all files: \c application/octet-stream. - */ -bool MimeType::isDefault() const -{ - return d->name == MimeDatabasePrivate::instance()->defaultMimeType(); -} - -/*! - Returns the name of the MIME type. - */ -QString MimeType::name() const -{ - return d->name; -} - -/*! - Returns the description of the MIME type to be displayed on user interfaces. - - The system language (QLocale::system().name()) is used to select the appropriate translation. - */ -QString MimeType::comment() const -{ - MimeDatabasePrivate::instance()->provider()->loadMimeTypePrivate(*d); - - QStringList languageList; - languageList << QLocale::system().name(); - languageList << QLocale::system().uiLanguages(); - for (const QString &language : std::as_const(languageList)) { - const QString lang = language == QLatin1String("C") ? QLatin1String("en_US") : language; - const QString comm = d->localeComments.value(lang); - if (!comm.isEmpty()) - return comm; - const int pos = lang.indexOf(QLatin1Char('_')); - if (pos != -1) { - // "pt_BR" not found? try just "pt" - const QString shortLang = lang.left(pos); - const QString commShort = d->localeComments.value(shortLang); - if (!commShort.isEmpty()) - return commShort; - } - } - - // Use the mimetype name as fallback - return d->name; -} - -/*! - Returns the file name of a generic icon that represents the MIME type. - - This should be used if the icon returned by iconName() cannot be found on - the system. It is used for categories of similar types (like spreadsheets - or archives) that can use a common icon. - The freedesktop.org Icon Naming Specification lists a set of such icon names. - - The icon name can be given to QIcon::fromTheme() in order to load the icon. - */ -QString MimeType::genericIconName() const -{ - MimeDatabasePrivate::instance()->provider()->loadGenericIcon(*d); - if (d->genericIconName.isEmpty()) { - // From the spec: - // If the generic icon name is empty (not specified by the mimetype definition) - // then the mimetype is used to generate the generic icon by using the top-level - // media type (e.g. "video" in "video/ogg") and appending "-x-generic" - // (i.e. "video-x-generic" in the previous example). - QString group = name(); - const int slashindex = group.indexOf(QLatin1Char('/')); - if (slashindex != -1) - group = group.left(slashindex); - return group + QLatin1String("-x-generic"); - } - return d->genericIconName; -} - -/*! - Returns the file name of an icon image that represents the MIME type. - - The icon name can be given to QIcon::fromTheme() in order to load the icon. - */ -QString MimeType::iconName() const -{ - MimeDatabasePrivate::instance()->provider()->loadIcon(*d); - if (d->iconName.isEmpty()) { - // Make default icon name from the mimetype name - d->iconName = name(); - const int slashindex = d->iconName.indexOf(QLatin1Char('/')); - if (slashindex != -1) - d->iconName[slashindex] = QLatin1Char('-'); - } - return d->iconName; -} - -/*! - Returns the list of glob matching patterns. - */ -QStringList MimeType::globPatterns() const -{ - MimeDatabasePrivate::instance()->provider()->loadMimeTypePrivate(*d); - return d->globPatterns; -} - -/*! - A type is a subclass of another type if any instance of the first type is - also an instance of the second. For example, all \c image/svg+xml files are - also \c text/xml, \c text/plain and \c application/octet-stream files. - - Subclassing is about the format, rather than the category of the data. - For example, there is no \e {generic spreadsheet} class that all - spreadsheets inherit from. - - Conversely, the parent MIME type of \c image/svg+xml is \c text/xml. - - A MIME type can have multiple parents. For instance, \c application/x-perl - has two parents: \c application/x-executable and \c text/plain. This makes - it possible to both execute perl scripts, and to open them in text editors. -*/ -QStringList MimeType::parentMimeTypes() const -{ - return MimeDatabasePrivate::instance()->provider()->parents(d->name); -} - -static void collectParentMimeTypes(const QString &mime, QStringList &allParents) -{ - const QStringList parents = MimeDatabasePrivate::instance()->provider()->parents(mime); - for (const QString &parent : parents) { - // I would use QSet, but since order matters I better not - if (!allParents.contains(parent)) - allParents.append(parent); - } - // We want a breadth-first search, so that the least-specific parent (octet-stream) is last - // This means iterating twice, unfortunately. - for (const QString &parent : parents) - collectParentMimeTypes(parent, allParents); -} - -/*! - Returns all the parent MIME types of this type, direct and indirect. - This includes grandparents, and so on. - - For instance, for \c image/svg+xml the list would be: - \c application/xml, \c text/plain, \c application/octet-stream. - - \note The \c application/octet-stream type is the ultimate parent for all types - of files (but not directories). -*/ -QStringList MimeType::allAncestors() const -{ - QStringList allParents; - collectParentMimeTypes(d->name, allParents); - return allParents; -} - -/*! - Returns the list of aliases of this MIME type. - - For instance, for \c text/csv, the returned list would be: - \c text/x-csv, \c text/x-comma-separated-values. - - \note All MimeType instances refer to proper MIME types, - never to aliases directly. - - The order of the aliases in the list is undefined. -*/ -QStringList MimeType::aliases() const -{ - return MimeDatabasePrivate::instance()->provider()->listAliases(d->name); -} - -/*! - Returns the known suffixes for the MIME type. - No leading dot is included, so for instance this would return - \c {"jpg", "jpeg"} for \c image/jpeg. - */ -QStringList MimeType::suffixes() const -{ - MimeDatabasePrivate::instance()->provider()->loadMimeTypePrivate(*d); - - QStringList result; - for (const QString &pattern : std::as_const(d->globPatterns)) { - const QString suffix = suffixFromPattern(pattern); - if (!suffix.isEmpty()) - result.append(suffix); - } - - return result; -} - -/*! - Returns the preferred suffix for the MIME type. - No leading dot is included, so for instance this would return \c "pdf" for - \c application/pdf. The return value can be empty, for MIME types which do - not have any suffixes associated. - */ -QString MimeType::preferredSuffix() const -{ - const QStringList suffixList = suffixes(); - return suffixList.isEmpty() ? QString() : suffixList.at(0); -} - -/*! - Returns a filter string usable for a file dialog. -*/ -QString MimeType::filterString() const -{ - MimeDatabasePrivate::instance()->provider()->loadMimeTypePrivate(*d); - QString filter; - - if (!d->globPatterns.empty()) { - filter += comment() + QLatin1String(" ("); - for (int i = 0; i < d->globPatterns.size(); ++i) { - if (i != 0) - filter += QLatin1Char(' '); - filter += d->globPatterns.at(i); - } - filter += QLatin1Char(')'); - } - - return filter; -} - -/*! - Returns \c true if the name or alias of the MIME type matches - \a nameOrAlias. -*/ -bool MimeType::matchesName(const QString &nameOrAlias) const -{ - if (d->name == nameOrAlias) - return true; - return MimeDatabasePrivate::instance()->provider()->resolveAlias(nameOrAlias) == d->name; -} - -/*! - Sets the preferred filename suffix for the MIME type to \a suffix. -*/ -void MimeType::setPreferredSuffix(const QString &suffix) -{ - MimeDatabasePrivate::instance()->provider()->loadMimeTypePrivate(*d); - - auto it = std::find_if(d->globPatterns.begin(), d->globPatterns.end(), - [suffix](const QString &pattern) { - return suffixFromPattern(pattern) == suffix; - }); - if (it != d->globPatterns.end()) - d->globPatterns.erase(it); - d->globPatterns.prepend(QLatin1String("*.") + suffix); -} - -/*! - Returns \c true if this MIME type is \a mimeTypeName or inherits it, - or if \a mimeTypeName is an alias for this mimetype. - - \sa parentMimeTypes() - */ -bool MimeType::inherits(const QString &mimeTypeName) const -{ - if (d->name == mimeTypeName) - return true; - return MimeDatabasePrivate::instance()->inherits(d->name, mimeTypeName); -} - -#ifndef QT_NO_DEBUG_STREAM -QDebug operator<<(QDebug debug, const MimeType &mime) -{ - QDebugStateSaver saver(debug); - if (!mime.isValid()) { - debug.nospace() << "MimeType(invalid)"; - } else { - debug.nospace() << "MimeType(" << mime.name() << ")"; - } - return debug; -} -#endif diff --git a/src/libs/utils/mimetypes/mimetype.h b/src/libs/utils/mimetypes/mimetype.h deleted file mode 100644 index 03993718d0c..00000000000 --- a/src/libs/utils/mimetypes/mimetype.h +++ /dev/null @@ -1,99 +0,0 @@ -// Copyright (C) 2016 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR LGPL-3.0 - -#pragma once - -#include - -#include -#include - -QT_BEGIN_NAMESPACE -class QFileinfo; -QT_END_NAMESPACE - -namespace Utils { - -namespace Internal { -class MimeTypeParserBase; -class MimeTypeMapEntry; -class MimeDatabasePrivate; -class MimeXMLProvider; -class MimeBinaryProvider; -class MimeTypePrivate; -} - -class QTCREATOR_UTILS_EXPORT MimeType -{ -public: - MimeType(); - MimeType(const MimeType &other); - MimeType &operator=(const MimeType &other); -//#ifdef Q_COMPILER_RVALUE_REFS -// MimeType &operator=(MimeType &&other) -// { -// qSwap(d, other.d); -// return *this; -// } -//#endif -// void swap(MimeType &other) -// { -// qSwap(d, other.d); -// } - explicit MimeType(const Internal::MimeTypePrivate &dd); - ~MimeType(); - - bool operator==(const MimeType &other) const; - - inline bool operator!=(const MimeType &other) const - { - return !operator==(other); - } - - bool isValid() const; - - bool isDefault() const; - - QString name() const; - QString comment() const; - QString genericIconName() const; - QString iconName() const; - QStringList globPatterns() const; - QStringList parentMimeTypes() const; - QStringList allAncestors() const; - QStringList aliases() const; - QStringList suffixes() const; - QString preferredSuffix() const; - - bool inherits(const QString &mimeTypeName) const; - - QString filterString() const; - - // Qt Creator additions - bool matchesName(const QString &nameOrAlias) const; - void setPreferredSuffix(const QString &suffix); - - friend auto qHash(const MimeType &mime) { return qHash(mime.name()); } - -protected: - friend class Internal::MimeTypeParserBase; - friend class Internal::MimeTypeMapEntry; - friend class Internal::MimeDatabasePrivate; - friend class Internal::MimeXMLProvider; - friend class Internal::MimeBinaryProvider; - friend class Internal::MimeTypePrivate; - - QExplicitlySharedDataPointer d; -}; - -} // Utils - -//Q_DECLARE_SHARED(Utils::MimeType) - -#ifndef QT_NO_DEBUG_STREAM -QT_BEGIN_NAMESPACE -class QDebug; -QTCREATOR_UTILS_EXPORT QDebug operator<<(QDebug debug, const Utils::MimeType &mime); -QT_END_NAMESPACE -#endif - diff --git a/src/libs/utils/mimetypes/mimetype_p.h b/src/libs/utils/mimetypes/mimetype_p.h deleted file mode 100644 index 4a215e0d1bd..00000000000 --- a/src/libs/utils/mimetypes/mimetype_p.h +++ /dev/null @@ -1,84 +0,0 @@ -// Copyright (C) 2016 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR LGPL-3.0 - -#pragma once - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include "mimetype.h" - -#include -#include - -namespace Utils { -namespace Internal { - -class MimeTypePrivate : public QSharedData -{ -public: - typedef QHash LocaleHash; - - MimeTypePrivate(); - explicit MimeTypePrivate(const MimeType &other); - - void clear(); - - void addGlobPattern(const QString &pattern); - - QString name; - LocaleHash localeComments; - QString genericIconName; - QString iconName; - QStringList globPatterns; - bool loaded; -}; - -} // Internal -} // Utils - -#define MIMETYPE_BUILDER \ - QT_BEGIN_NAMESPACE \ - static MimeType buildMimeType ( \ - const QString &name, \ - const QString &genericIconName, \ - const QString &iconName, \ - const QStringList &globPatterns \ - ) \ - { \ - MimeTypePrivate qMimeTypeData; \ - qMimeTypeData.name = name; \ - qMimeTypeData.genericIconName = genericIconName; \ - qMimeTypeData.iconName = iconName; \ - qMimeTypeData.globPatterns = globPatterns; \ - return MimeType(qMimeTypeData); \ - } \ - QT_END_NAMESPACE - -#ifdef Q_COMPILER_RVALUE_REFS -#define MIMETYPE_BUILDER_FROM_RVALUE_REFS \ - QT_BEGIN_NAMESPACE \ - static MimeType buildMimeType ( \ - QString &&name, \ - QString &&genericIconName, \ - QString &&iconName, \ - QStringList &&globPatterns \ - ) \ - { \ - MimeTypePrivate qMimeTypeData; \ - qMimeTypeData.name = std::move(name); \ - qMimeTypeData.genericIconName = std::move(genericIconName); \ - qMimeTypeData.iconName = std::move(iconName); \ - qMimeTypeData.globPatterns = std::move(globPatterns); \ - return MimeType(qMimeTypeData); \ - } \ - QT_END_NAMESPACE -#endif diff --git a/src/libs/utils/mimetypes/mimetypeparser.cpp b/src/libs/utils/mimetypes/mimetypeparser.cpp deleted file mode 100644 index 3b132299fa7..00000000000 --- a/src/libs/utils/mimetypes/mimetypeparser.cpp +++ /dev/null @@ -1,325 +0,0 @@ -// Copyright (C) 2016 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR LGPL-3.0 - -#include "mimetypeparser_p.h" - -#include "mimetype_p.h" -#include "mimemagicrulematcher_p.h" - -#include -#include -#include -#include -#include -#include -#include - -using namespace Utils; -using namespace Utils::Internal; - -// XML tags in MIME files -static const char mimeInfoTagC[] = "mime-info"; -static const char mimeTypeTagC[] = "mime-type"; -static const char mimeTypeAttributeC[] = "type"; -static const char subClassTagC[] = "sub-class-of"; -static const char commentTagC[] = "comment"; -static const char genericIconTagC[] = "generic-icon"; -static const char iconTagC[] = "icon"; -static const char nameAttributeC[] = "name"; -static const char globTagC[] = "glob"; -static const char aliasTagC[] = "alias"; -static const char patternAttributeC[] = "pattern"; -static const char weightAttributeC[] = "weight"; -static const char caseSensitiveAttributeC[] = "case-sensitive"; -static const char localeAttributeC[] = "xml:lang"; - -static const char magicTagC[] = "magic"; -static const char priorityAttributeC[] = "priority"; - -static const char matchTagC[] = "match"; -static const char matchValueAttributeC[] = "value"; -static const char matchTypeAttributeC[] = "type"; -static const char matchOffsetAttributeC[] = "offset"; -static const char matchMaskAttributeC[] = "mask"; - -/*! - \class MimeTypeParser - \inmodule QtCore - \internal - \brief The MimeTypeParser class parses MIME types, and builds a MIME database hierarchy by adding to MimeDatabasePrivate. - - Populates MimeDataBase - - \sa MimeDatabase, MimeMagicRuleMatcher, MagicRule, MagicStringRule, MagicByteRule, GlobPattern - \sa MimeTypeParser -*/ - -/*! - \class MimeTypeParserBase - \inmodule QtCore - \internal - \brief The MimeTypeParserBase class parses for a sequence of in a generic way. - - Calls abstract handler function process for MimeType it finds. - - \sa MimeDatabase, MimeMagicRuleMatcher, MagicRule, MagicStringRule, MagicByteRule, GlobPattern - \sa MimeTypeParser -*/ - -/*! - \fn virtual bool MimeTypeParserBase::process(const MimeType &t, QString *errorMessage) = 0; - Overwrite to process the sequence of parsed data -*/ - -MimeTypeParserBase::ParseState MimeTypeParserBase::nextState(ParseState currentState, - QStringView startElement) -{ - switch (currentState) { - case ParseBeginning: - if (startElement == QLatin1String(mimeInfoTagC)) - return ParseMimeInfo; - if (startElement == QLatin1String(mimeTypeTagC)) - return ParseMimeType; - return ParseError; - case ParseMimeInfo: - return startElement == QLatin1String(mimeTypeTagC) ? ParseMimeType : ParseError; - case ParseMimeType: - case ParseComment: - case ParseGenericIcon: - case ParseIcon: - case ParseGlobPattern: - case ParseSubClass: - case ParseAlias: - case ParseOtherMimeTypeSubTag: - case ParseMagicMatchRule: - if (startElement == QLatin1String(mimeTypeTagC)) // Sequence of - return ParseMimeType; - if (startElement == QLatin1String(commentTagC )) - return ParseComment; - if (startElement == QLatin1String(genericIconTagC)) - return ParseGenericIcon; - if (startElement == QLatin1String(iconTagC)) - return ParseIcon; - if (startElement == QLatin1String(globTagC)) - return ParseGlobPattern; - if (startElement == QLatin1String(subClassTagC)) - return ParseSubClass; - if (startElement == QLatin1String(aliasTagC)) - return ParseAlias; - if (startElement == QLatin1String(magicTagC)) - return ParseMagic; - if (startElement == QLatin1String(matchTagC)) - return ParseMagicMatchRule; - return ParseOtherMimeTypeSubTag; - case ParseMagic: - if (startElement == QLatin1String(matchTagC)) - return ParseMagicMatchRule; - break; - case ParseError: - break; - } - return ParseError; -} - -// Parse int number from an (attribute) string) -static bool parseNumber(const QString &n, int *target, QString *errorMessage) -{ - bool ok; - *target = n.toInt(&ok); - if (!ok) { - if (errorMessage) - *errorMessage = QString::fromLatin1("Not a number '%1'.").arg(n); - return false; - } - return true; -} - -// Evaluate a magic match rule like -// -// -#ifndef QT_NO_XMLSTREAMREADER -static bool createMagicMatchRule(const QXmlStreamAttributes &atts, - QString *errorMessage, MimeMagicRule *&rule) -{ - const QString type = atts.value(QLatin1String(matchTypeAttributeC)).toString(); - MimeMagicRule::Type magicType = MimeMagicRule::type(type.toLatin1()); - if (magicType == MimeMagicRule::Invalid) { - qWarning("%s: match type %s is not supported.", Q_FUNC_INFO, type.toUtf8().constData()); - return true; - } - const QString value = atts.value(QLatin1String(matchValueAttributeC)).toString(); - // Parse for offset as "1" or "1:10" - int startPos, endPos; - const QString offsetS = atts.value(QLatin1String(matchOffsetAttributeC)).toString(); - const int colonIndex = offsetS.indexOf(QLatin1Char(':')); - const QString startPosS = colonIndex == -1 ? offsetS : offsetS.mid(0, colonIndex); - const QString endPosS = colonIndex == -1 ? offsetS : offsetS.mid(colonIndex + 1); - if (!parseNumber(startPosS, &startPos, errorMessage) || !parseNumber(endPosS, &endPos, errorMessage)) - return false; - const QString mask = atts.value(QLatin1String(matchMaskAttributeC)).toString(); - - MimeMagicRule *tempRule = new MimeMagicRule(magicType, value.toUtf8(), startPos, endPos, - mask.toLatin1(), errorMessage); - if (!tempRule->isValid()) { - delete tempRule; - return false; - } - - rule = tempRule; - return true; -} -#endif - -bool MimeTypeParserBase::parse(const QByteArray &content, const QString &fileName, QString *errorMessage) -{ -#ifdef QT_NO_XMLSTREAMREADER - if (errorMessage) - *errorMessage = QString::fromLatin1("QXmlStreamReader is not available, cannot parse."); - return false; -#else - MimeTypePrivate data; - int priority = 50; - QStack currentRules; // stack for the nesting of rules - QList rules; // toplevel rules - QXmlStreamReader reader(content); - ParseState ps = ParseBeginning; - QXmlStreamAttributes atts; - bool ignoreCurrentMimeType = false; - while (!reader.atEnd()) { - switch (reader.readNext()) { - case QXmlStreamReader::StartElement: - if (ignoreCurrentMimeType) - continue; - ps = nextState(ps, reader.name()); - atts = reader.attributes(); - switch (ps) { - case ParseMimeType: { // start parsing a MIME type name - const QString name = atts.value(QLatin1String(mimeTypeAttributeC)).toString(); - if (name.isEmpty()) { - reader.raiseError(QString::fromLatin1("Missing '%1'-attribute").arg(QString::fromLatin1(mimeTypeAttributeC))); - } else { - if (mimeTypeExists(name)) - ignoreCurrentMimeType = true; - else - data.name = name; - } - } - break; - case ParseGenericIcon: - data.genericIconName = atts.value(QLatin1String(nameAttributeC)).toString(); - break; - case ParseIcon: - data.iconName = atts.value(QLatin1String(nameAttributeC)).toString(); - break; - case ParseGlobPattern: { - const QString pattern = atts.value(QLatin1String(patternAttributeC)).toString(); - unsigned weight = atts.value(QLatin1String(weightAttributeC)).toString().toInt(); - const bool caseSensitive = atts.value(QLatin1String(caseSensitiveAttributeC)).toString() == QLatin1String("true"); - - if (weight == 0) - weight = MimeGlobPattern::DefaultWeight; - - Q_ASSERT(!data.name.isEmpty()); - const MimeGlobPattern glob(pattern, data.name, weight, caseSensitive ? Qt::CaseSensitive : Qt::CaseInsensitive); - if (!process(glob, errorMessage)) // for actual glob matching - return false; - data.addGlobPattern(pattern); // just for MimeType::globPatterns() - } - break; - case ParseSubClass: { - const QString inheritsFrom = atts.value(QLatin1String(mimeTypeAttributeC)).toString(); - if (!inheritsFrom.isEmpty()) - processParent(data.name, inheritsFrom); - } - break; - case ParseComment: { - // comments have locale attributes. We want the default, English one - QString locale = atts.value(QLatin1String(localeAttributeC)).toString(); - const QString comment = reader.readElementText(); - if (locale.isEmpty()) - locale = QString::fromLatin1("en_US"); - data.localeComments.insert(locale, comment); - } - break; - case ParseAlias: { - const QString alias = atts.value(QLatin1String(mimeTypeAttributeC)).toString(); - if (!alias.isEmpty()) - processAlias(alias, data.name); - } - break; - case ParseMagic: { - priority = 50; - const QString priorityS = atts.value(QLatin1String(priorityAttributeC)).toString(); - if (!priorityS.isEmpty()) { - if (!parseNumber(priorityS, &priority, errorMessage)) - return false; - - } - currentRules.clear(); - //qDebug() << "MAGIC start for mimetype" << data.name; - } - break; - case ParseMagicMatchRule: { - MimeMagicRule *rule = nullptr; - if (!createMagicMatchRule(atts, errorMessage, rule)) - return false; - QList *ruleList; - if (currentRules.isEmpty()) - ruleList = &rules; - else // nest this rule into the proper parent - ruleList = ¤tRules.top()->m_subMatches; - ruleList->append(*rule); - //qDebug() << " MATCH added. Stack size was" << currentRules.size(); - currentRules.push(&ruleList->last()); - delete rule; - break; - } - case ParseError: - reader.raiseError(QString::fromLatin1("Unexpected element <%1>"). - arg(reader.name().toString())); - break; - default: - break; - } - break; - // continue switch QXmlStreamReader::Token... - case QXmlStreamReader::EndElement: // Finished element - { - const QStringView elementName = reader.name(); - if (elementName == QLatin1String(mimeTypeTagC)) { - if (!ignoreCurrentMimeType) { - if (!process(MimeType(data), errorMessage)) - return false; - } - ignoreCurrentMimeType = false; - data.clear(); - } else if (!ignoreCurrentMimeType) { - if (elementName == QLatin1String(matchTagC)) { - // Closing a tag, pop stack - currentRules.pop(); - //qDebug() << " MATCH closed. Stack size is now" << currentRules.size(); - } else if (elementName == QLatin1String(magicTagC)) { - //qDebug() << "MAGIC ended, we got" << rules.count() << "rules, with prio" << priority; - // Finished a sequence - MimeMagicRuleMatcher ruleMatcher(data.name, priority); - ruleMatcher.addRules(rules); - processMagicMatcher(ruleMatcher); - rules.clear(); - } - } - break; - } - default: - break; - } - } - - if (reader.hasError()) { - if (errorMessage) - *errorMessage = QString::fromLatin1("An error has been encountered at line %1 of %2: %3:").arg(reader.lineNumber()).arg(fileName, reader.errorString()); - return false; - } - - return true; -#endif //QT_NO_XMLSTREAMREADER -} diff --git a/src/libs/utils/mimetypes/mimetypeparser_p.h b/src/libs/utils/mimetypes/mimetypeparser_p.h deleted file mode 100644 index 5cc44e04a24..00000000000 --- a/src/libs/utils/mimetypes/mimetypeparser_p.h +++ /dev/null @@ -1,91 +0,0 @@ -// Copyright (C) 2016 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR LGPL-3.0 - -#pragma once - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include "mimedatabase_p.h" -#include "mimeprovider_p.h" - -namespace Utils { -namespace Internal { - -class MimeTypeParserBase -{ - Q_DISABLE_COPY(MimeTypeParserBase) - -public: - MimeTypeParserBase() {} - virtual ~MimeTypeParserBase() {} - - bool parse(const QByteArray &content, const QString &fileName, QString *errorMessage); - -protected: - virtual bool mimeTypeExists(const QString &mimeTypeName) = 0; - virtual bool process(const MimeType &t, QString *errorMessage) = 0; - virtual bool process(const MimeGlobPattern &t, QString *errorMessage) = 0; - virtual void processParent(const QString &child, const QString &parent) = 0; - virtual void processAlias(const QString &alias, const QString &name) = 0; - virtual void processMagicMatcher(const MimeMagicRuleMatcher &matcher) = 0; - -private: - enum ParseState { - ParseBeginning, - ParseMimeInfo, - ParseMimeType, - ParseComment, - ParseGenericIcon, - ParseIcon, - ParseGlobPattern, - ParseSubClass, - ParseAlias, - ParseMagic, - ParseMagicMatchRule, - ParseOtherMimeTypeSubTag, - ParseError - }; - - static ParseState nextState(ParseState currentState, QStringView startElement); -}; - - -class MimeTypeParser : public MimeTypeParserBase -{ -public: - explicit MimeTypeParser(MimeXMLProvider &provider) : m_provider(provider) {} - -protected: - inline bool mimeTypeExists(const QString &mimeTypeName) override - { return m_provider.mimeTypeForName(mimeTypeName).isValid(); } - - inline bool process(const MimeType &t, QString *) override - { m_provider.addMimeType(t); return true; } - - inline bool process(const MimeGlobPattern &glob, QString *) override - { m_provider.addGlobPattern(glob); return true; } - - inline void processParent(const QString &child, const QString &parent) override - { m_provider.addParent(child, parent); } - - inline void processAlias(const QString &alias, const QString &name) override - { m_provider.addAlias(alias, name); } - - inline void processMagicMatcher(const MimeMagicRuleMatcher &matcher) override - { m_provider.addMagicMatcher(matcher); } - -private: - MimeXMLProvider &m_provider; -}; - -} // Internal -} // Utils diff --git a/src/libs/utils/mimetypes/mimeutils.cpp b/src/libs/utils/mimetypes/mimeutils.cpp deleted file mode 100644 index 9e1e9824816..00000000000 --- a/src/libs/utils/mimetypes/mimeutils.cpp +++ /dev/null @@ -1,104 +0,0 @@ -// Copyright (C) 2022 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR LGPL-3.0 - -#include "mimeutils.h" - -#include "mimedatabase.h" -#include "mimedatabase_p.h" -#include "mimemagicrule_p.h" -#include "mimeprovider_p.h" - -#include "filepath.h" - -using namespace Utils; -using namespace Utils::Internal; - -void Utils::addMimeTypes(const QString &fileName, const QByteArray &data) -{ - auto d = MimeDatabasePrivate::instance(); - QMutexLocker locker(&d->mutex); - - if (d->m_startupPhase >= MimeDatabase::PluginsDelayedInitializing) - qWarning("Adding items from %s to MimeDatabase after initialization time", - qPrintable(fileName)); - - auto xmlProvider = static_cast(d->provider()); - xmlProvider->addData(fileName, data); -} - -QMap> Utils::magicRulesForMimeType(const MimeType &mimeType) -{ - auto d = MimeDatabasePrivate::instance(); - QMutexLocker locker(&d->mutex); - return d->provider()->magicRulesForMimeType(mimeType); -} - -void Utils::setGlobPatternsForMimeType(const MimeType &mimeType, const QStringList &patterns) -{ - auto d = MimeDatabasePrivate::instance(); - QMutexLocker locker(&d->mutex); - d->provider()->setGlobPatternsForMimeType(mimeType, patterns); -} - -void Utils::setMagicRulesForMimeType(const MimeType &mimeType, - const QMap> &rules) -{ - auto d = MimeDatabasePrivate::instance(); - QMutexLocker locker(&d->mutex); - d->provider()->setMagicRulesForMimeType(mimeType, rules); -} - -void Utils::setMimeStartupPhase(MimeStartupPhase phase) -{ - auto d = MimeDatabasePrivate::instance(); - QMutexLocker locker(&d->mutex); - if (int(phase) != d->m_startupPhase + 1) - qWarning("Unexpected jump in MimedDatabase lifetime from %d to %d", - d->m_startupPhase, - int(phase)); - d->m_startupPhase = int(phase); -} - -MimeType Utils::mimeTypeForName(const QString &nameOrAlias) -{ - MimeDatabase mdb; - return mdb.mimeTypeForName(nameOrAlias); -} - -MimeType Utils::mimeTypeForFile(const QString &fileName, MimeMatchMode mode) -{ - MimeDatabase mdb; - return mdb.mimeTypeForFile(fileName, MimeDatabase::MatchMode(mode)); -} - -MimeType Utils::mimeTypeForFile(const QFileInfo &fileInfo, MimeMatchMode mode) -{ - MimeDatabase mdb; - return mdb.mimeTypeForFile(fileInfo, MimeDatabase::MatchMode(mode)); -} - -MimeType Utils::mimeTypeForFile(const FilePath &filePath, MimeMatchMode mode) -{ - MimeDatabase mdb; - if (filePath.needsDevice()) - return mdb.mimeTypeForUrl(filePath.toUrl()); - return mdb.mimeTypeForFile(filePath.toString(), MimeDatabase::MatchMode(mode)); -} - -QList Utils::mimeTypesForFileName(const QString &fileName) -{ - MimeDatabase mdb; - return mdb.mimeTypesForFileName(fileName); -} - -MimeType Utils::mimeTypeForData(const QByteArray &data) -{ - MimeDatabase mdb; - return mdb.mimeTypeForData(data); -} - -QList Utils::allMimeTypes() -{ - MimeDatabase mdb; - return mdb.allMimeTypes(); -} diff --git a/src/libs/utils/utils.qbs b/src/libs/utils/utils.qbs index 5996f323e9e..d35973591dd 100644 --- a/src/libs/utils/utils.qbs +++ b/src/libs/utils/utils.qbs @@ -5,9 +5,7 @@ Project { name: "Utils" QtcLibrary { - property bool useNewMimeDatabase: true - - cpp.includePaths: base.concat((useNewMimeDatabase ? "mimetypes2" : "mimetypes"), ".") + cpp.includePaths: base.concat("mimetypes2", ".") cpp.defines: base.concat([ "UTILS_LIBRARY" ]) @@ -416,7 +414,7 @@ Project { Group { name: "MimeTypes" - prefix: useNewMimeDatabase ? "mimetypes2/" : "mimetypes/" + prefix: "mimetypes2/" files: [ "mimedatabase.cpp", "mimedatabase.h", @@ -461,8 +459,7 @@ Project { Export { Depends { name: "Qt"; submodules: ["concurrent", "widgets" ] } - cpp.includePaths: base.concat(exportingProduct.useNewMimeDatabase ? "mimetypes2" - : "mimetypes") + cpp.includePaths: base.concat("mimetypes2") } } } diff --git a/src/plugins/squish/squishplugin.cpp b/src/plugins/squish/squishplugin.cpp index f2e486770c9..b84a308396b 100644 --- a/src/plugins/squish/squishplugin.cpp +++ b/src/plugins/squish/squishplugin.cpp @@ -23,7 +23,6 @@ #include #include -#include #include #include