File indexing completed on 2024-04-21 15:03:08

0001 /*
0002     This file is part of the KDE libraries
0003     SPDX-FileCopyrightText: 1999 Waldo Bastian <bastian@kde.org>
0004     SPDX-FileCopyrightText: 2006-2009 David Faure <faure@kde.org>
0005 
0006     SPDX-License-Identifier: LGPL-2.0-or-later
0007 */
0008 
0009 #include "kmimetypefactory_p.h"
0010 #include "servicesdebug.h"
0011 #include <QDataStream>
0012 #include <ksycoca.h>
0013 #include <ksycocadict_p.h>
0014 
0015 extern int servicesDebugArea();
0016 
0017 KMimeTypeFactory::KMimeTypeFactory(KSycoca *db)
0018     : KSycocaFactory(KST_KMimeTypeFactory, db)
0019 {
0020 }
0021 
0022 KMimeTypeFactory::~KMimeTypeFactory()
0023 {
0024 }
0025 
0026 int KMimeTypeFactory::entryOffset(const QString &mimeTypeName)
0027 {
0028     if (!sycocaDict()) {
0029         return -1; // Error!
0030     }
0031     assert(!sycoca()->isBuilding());
0032     const int offset = sycocaDict()->find_string(mimeTypeName.toLower());
0033     return offset;
0034 }
0035 
0036 int KMimeTypeFactory::serviceOffersOffset(const QString &mimeTypeName)
0037 {
0038     const int offset = entryOffset(mimeTypeName.toLower());
0039     if (!offset) {
0040         return -1; // Not found
0041     }
0042 
0043     MimeTypeEntry::Ptr newMimeType(createEntry(offset));
0044     if (!newMimeType) {
0045         return -1;
0046     }
0047     // Check whether the dictionary was right.
0048     if (newMimeType->name() != mimeTypeName.toLower()) {
0049         // No it wasn't...
0050         return -1;
0051     }
0052     return newMimeType->serviceOffersOffset();
0053 }
0054 
0055 KMimeTypeFactory::MimeTypeEntry *KMimeTypeFactory::createEntry(int offset) const
0056 {
0057     KSycocaType type;
0058     QDataStream *str = sycoca()->findEntry(offset, type);
0059     if (!str) {
0060         return nullptr;
0061     }
0062 
0063     if (type != KST_KMimeTypeEntry) {
0064         qCWarning(SERVICES) << "KMimeTypeFactory: unexpected object entry in KSycoca database (type=" << int(type) << ")";
0065         return nullptr;
0066     }
0067     MimeTypeEntry *newEntry = new MimeTypeEntry(*str, offset);
0068     if (newEntry && !newEntry->isValid()) {
0069         qCWarning(SERVICES) << "KMimeTypeFactory: corrupt object in KSycoca database!\n";
0070         delete newEntry;
0071         newEntry = nullptr;
0072     }
0073     return newEntry;
0074 }
0075 
0076 QStringList KMimeTypeFactory::allMimeTypes()
0077 {
0078     // TODO: reimplement in terms of "listing xdgdata-mime", to avoid ksycoca dependency,
0079     // then move to KMimeTypeRepository
0080     const KSycocaEntry::List list = allEntries();
0081     QStringList result;
0082     result.reserve(list.size());
0083 
0084     std::transform(list.cbegin(), list.cend(), std::back_inserter(result), [](const KSycocaEntry::Ptr &entry) {
0085         Q_ASSERT(entry->isType(KST_KMimeTypeEntry));
0086 
0087         MimeTypeEntry::Ptr mimeType(static_cast<MimeTypeEntry *>(entry.data()));
0088         return mimeType->name();
0089     });
0090 
0091     return result;
0092 }
0093 
0094 KMimeTypeFactory::MimeTypeEntry::Ptr KMimeTypeFactory::findMimeTypeEntryByName(const QString &name)
0095 {
0096     Q_ASSERT(sycoca()->isBuilding());
0097     // We're building a database - the MIME type entry must be in memory
0098     KSycocaEntry::Ptr servType = m_entryDict->value(name.toLower());
0099     return MimeTypeEntry::Ptr(static_cast<MimeTypeEntry *>(servType.data()));
0100 }
0101 
0102 QStringList KMimeTypeFactory::resourceDirs()
0103 {
0104     return KSycocaFactory::allDirectories(QStringLiteral("mime"));
0105 }
0106 
0107 ////
0108 
0109 class KMimeTypeFactory::MimeTypeEntryPrivate : public KSycocaEntryPrivate
0110 {
0111 public:
0112     K_SYCOCATYPE(KST_KMimeTypeEntry, KSycocaEntryPrivate)
0113     MimeTypeEntryPrivate(const QString &file, const QString &name)
0114         : KSycocaEntryPrivate(file)
0115         , m_name(name)
0116         , m_serviceOffersOffset(-1)
0117     {
0118     }
0119     MimeTypeEntryPrivate(QDataStream &s, int offset)
0120         : KSycocaEntryPrivate(s, offset)
0121         , m_serviceOffersOffset(-1)
0122     {
0123         s >> m_name >> m_serviceOffersOffset;
0124     }
0125     QString name() const override
0126     {
0127         return m_name;
0128     }
0129     void save(QDataStream &s) override;
0130 
0131     QString m_name;
0132     int m_serviceOffersOffset;
0133 };
0134 
0135 void KMimeTypeFactory::MimeTypeEntryPrivate::save(QDataStream &s)
0136 {
0137     KSycocaEntryPrivate::save(s);
0138     s << m_name << m_serviceOffersOffset;
0139 }
0140 
0141 ////
0142 
0143 KMimeTypeFactory::MimeTypeEntry::MimeTypeEntry(const QString &file, const QString &name)
0144     : KSycocaEntry(*new MimeTypeEntryPrivate(file, name.toLower()))
0145 {
0146 }
0147 
0148 KMimeTypeFactory::MimeTypeEntry::MimeTypeEntry(QDataStream &s, int offset)
0149     : KSycocaEntry(*new MimeTypeEntryPrivate(s, offset))
0150 {
0151 }
0152 
0153 KMimeTypeFactory::MimeTypeEntry::~MimeTypeEntry()
0154 {
0155 }
0156 
0157 int KMimeTypeFactory::MimeTypeEntry::serviceOffersOffset() const
0158 {
0159     Q_D(const MimeTypeEntry);
0160     return d->m_serviceOffersOffset;
0161 }
0162 
0163 void KMimeTypeFactory::MimeTypeEntry::setServiceOffersOffset(int off)
0164 {
0165     Q_D(MimeTypeEntry);
0166     d->m_serviceOffersOffset = off;
0167 }