File indexing completed on 2024-12-01 03:42:11

0001 /*
0002     This file is part of the KDE libraries
0003     SPDX-FileCopyrightText: 2000 Waldo Bastian <bastian@kde.org>
0004 
0005     SPDX-License-Identifier: LGPL-2.0-or-later
0006 */
0007 
0008 #include "kservice.h"
0009 #include "kservicegroupfactory_p.h"
0010 #include "ksycoca.h"
0011 #include "ksycocadict_p.h"
0012 #include "ksycocatype.h"
0013 
0014 #include "servicesdebug.h"
0015 
0016 #include <QIODevice>
0017 
0018 KServiceGroupFactory::KServiceGroupFactory(KSycoca *db)
0019     : KSycocaFactory(KST_KServiceGroupFactory, db)
0020     , m_baseGroupDict(nullptr)
0021     , m_baseGroupDictOffset(0)
0022 {
0023     if (!sycoca()->isBuilding()) {
0024         QDataStream *str = stream();
0025         if (!str) {
0026             return;
0027         }
0028         // Read Header
0029         qint32 i;
0030         (*str) >> i;
0031         m_baseGroupDictOffset = i;
0032 
0033         const qint64 saveOffset = str->device()->pos();
0034         // Init index tables
0035         m_baseGroupDict = new KSycocaDict(str, m_baseGroupDictOffset);
0036         str->device()->seek(saveOffset);
0037     }
0038 }
0039 
0040 KServiceGroupFactory::~KServiceGroupFactory()
0041 {
0042     delete m_baseGroupDict;
0043 }
0044 
0045 KServiceGroup::Ptr KServiceGroupFactory::findGroupByDesktopPath(const QString &_name, bool deep)
0046 {
0047     if (!sycocaDict()) {
0048         return KServiceGroup::Ptr(); // Error!
0049     }
0050     int offset = sycocaDict()->find_string(_name);
0051     if (!offset) {
0052         return KServiceGroup::Ptr(); // Not found
0053     }
0054 
0055     KServiceGroup::Ptr newGroup(createGroup(offset, deep));
0056 
0057     // Check whether the dictionary was right.
0058     if (newGroup && (newGroup->relPath() != _name)) {
0059         // No it wasn't...
0060         newGroup = nullptr; // Not found
0061     }
0062     return newGroup;
0063 }
0064 
0065 KServiceGroup::Ptr KServiceGroupFactory::findBaseGroup(const QString &_baseGroupName, bool deep)
0066 {
0067     if (!m_baseGroupDict) {
0068         return KServiceGroup::Ptr(); // Error!
0069     }
0070 
0071     // Warning : this assumes we're NOT building a database
0072     // But since findBaseGroup isn't called in that case...
0073     // [ see KServiceTypeFactory for how to do it if needed ]
0074 
0075     int offset = m_baseGroupDict->find_string(_baseGroupName);
0076     if (!offset) {
0077         return KServiceGroup::Ptr(); // Not found
0078     }
0079 
0080     KServiceGroup::Ptr newGroup(createGroup(offset, deep));
0081 
0082     // Check whether the dictionary was right.
0083     if (newGroup && (newGroup->baseGroupName() != _baseGroupName)) {
0084         // No it wasn't...
0085         newGroup = nullptr; // Not found
0086     }
0087     return newGroup;
0088 }
0089 
0090 KServiceGroup *KServiceGroupFactory::createGroup(int offset, bool deep) const
0091 {
0092     KSycocaType type;
0093     QDataStream *str = sycoca()->findEntry(offset, type);
0094     if (type != KST_KServiceGroup) {
0095         qCWarning(SERVICES) << "KServiceGroupFactory: unexpected object entry in KSycoca database (type = " << int(type) << ")";
0096         return nullptr;
0097     }
0098 
0099     KServiceGroup *newEntry = new KServiceGroup(*str, offset, deep);
0100     if (!newEntry->isValid()) {
0101         qCWarning(SERVICES) << "KServiceGroupFactory: corrupt object in KSycoca database!";
0102         delete newEntry;
0103         newEntry = nullptr;
0104     }
0105     return newEntry;
0106 }
0107 
0108 KServiceGroup *KServiceGroupFactory::createEntry(int offset) const
0109 {
0110     return createGroup(offset, true);
0111 }
0112 
0113 void KServiceGroupFactory::virtual_hook(int id, void *data)
0114 {
0115     KSycocaFactory::virtual_hook(id, data);
0116 }