File indexing completed on 2024-04-21 07:43:50

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