kio Library API Documentation

kservicefactory.cpp

00001 /*  This file is part of the KDE libraries
00002  *  Copyright (C) 1999 David Faure <faure@kde.org>
00003  *
00004  *  This library is free software; you can redistribute it and/or
00005  *  modify it under the terms of the GNU Library General Public
00006  *  License version 2 as published by the Free Software Foundation;
00007  *
00008  *  This library is distributed in the hope that it will be useful,
00009  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00010  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00011  *  Library General Public License for more details.
00012  *
00013  *  You should have received a copy of the GNU Library General Public License
00014  *  along with this library; see the file COPYING.LIB.  If not, write to
00015  *  the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
00016  *  Boston, MA 02111-1307, USA.
00017  **/
00018 
00019 #include "kservicefactory.h"
00020 #include "ksycoca.h"
00021 #include "ksycocatype.h"
00022 #include "ksycocadict.h"
00023 #include "kservice.h"
00024 
00025 #include <qstring.h>
00026 
00027 #include <klocale.h>
00028 #include <kdebug.h>
00029 #include <kglobal.h>
00030 #include <kstandarddirs.h>
00031 #include <kstaticdeleter.h>
00032 
00033 KServiceFactory::KServiceFactory()
00034  : KSycocaFactory( KST_KServiceFactory )
00035 {
00036    m_offerListOffset = 0;
00037    m_nameDictOffset = 0;
00038    m_relNameDictOffset = 0;
00039    if (m_str)
00040    {
00041       // Read Header
00042       Q_INT32 i;
00043       (*m_str) >> i;
00044       m_nameDictOffset = i;
00045       (*m_str) >> i;
00046       m_relNameDictOffset = i;
00047       (*m_str) >> i;
00048       m_offerListOffset = i;
00049       (*m_str) >> i;
00050       m_initListOffset = i;
00051 
00052       int saveOffset = m_str->device()->at();
00053       // Init index tables
00054       m_nameDict = new KSycocaDict(m_str, m_nameDictOffset);
00055       // Init index tables
00056       m_relNameDict = new KSycocaDict(m_str, m_relNameDictOffset);
00057       saveOffset = m_str->device()->at(saveOffset);
00058    }
00059    else
00060    {
00061       // Build new database
00062       m_nameDict = new KSycocaDict();
00063       m_relNameDict = new KSycocaDict();
00064    }
00065    _self = this;
00066 }
00067 
00068 KServiceFactory::~KServiceFactory()
00069 {
00070    _self = 0L;
00071    delete m_nameDict;
00072    delete m_relNameDict;
00073 }
00074 
00075 KServiceFactory * KServiceFactory::self()
00076 {
00077     if (!_self) {
00078         _self = new KServiceFactory();
00079     }
00080     return _self;
00081 }
00082 
00083 KService * KServiceFactory::findServiceByName(const QString &_name)
00084 {
00085    if (!m_sycocaDict) return 0; // Error!
00086 
00087    // Warning : this assumes we're NOT building a database
00088    // But since findServiceByName isn't called in that case...
00089    // [ see KServiceTypeFactory for how to do it if needed ]
00090 
00091    int offset = m_sycocaDict->find_string( _name );
00092    if (!offset) return 0; // Not found
00093 
00094    KService * newService = createEntry(offset);
00095 
00096    // Check whether the dictionary was right.
00097    if (newService && (newService->name() != _name))
00098    {
00099       // No it wasn't...
00100       delete newService;
00101       newService = 0; // Not found
00102    }
00103    return newService;
00104 }
00105 
00106 KService * KServiceFactory::findServiceByDesktopName(const QString &_name)
00107 {
00108    if (!m_nameDict) return 0; // Error!
00109 
00110    // Warning : this assumes we're NOT building a database
00111    // But since findServiceByName isn't called in that case...
00112    // [ see KServiceTypeFactory for how to do it if needed ]
00113 
00114    int offset = m_nameDict->find_string( _name );
00115    if (!offset) return 0; // Not found
00116 
00117    KService * newService = createEntry(offset);
00118 
00119    // Check whether the dictionary was right.
00120    if (newService && (newService->desktopEntryName() != _name))
00121    {
00122       // No it wasn't...
00123       delete newService;
00124       newService = 0; // Not found
00125    }
00126    return newService;
00127 }
00128 
00129 KService * KServiceFactory::findServiceByDesktopPath(const QString &_name)
00130 {
00131    if (!m_relNameDict) return 0; // Error!
00132 
00133    // Warning : this assumes we're NOT building a database
00134    // But since findServiceByName isn't called in that case...
00135    // [ see KServiceTypeFactory for how to do it if needed ]
00136 
00137    int offset = m_relNameDict->find_string( _name );
00138    if (!offset) return 0; // Not found
00139 
00140    KService * newService = createEntry(offset);
00141 
00142    // Check whether the dictionary was right.
00143    if (newService && (newService->desktopEntryPath() != _name))
00144    {
00145       // No it wasn't...
00146       delete newService;
00147       newService = 0; // Not found
00148    }
00149    return newService;
00150 }
00151 
00152 KService* KServiceFactory::createEntry(int offset)
00153 {
00154    KService * newEntry = 0L;
00155    KSycocaType type;
00156    QDataStream *str = KSycoca::self()->findEntry(offset, type);
00157    switch(type)
00158    {
00159      case KST_KService:
00160         newEntry = new KService(*str, offset);
00161         break;
00162 
00163      default:
00164         kdError(7011) << QString("KServiceFactory: unexpected object entry in KSycoca database (type = %1)").arg((int)type) << endl;
00165         return 0;
00166    }
00167    if (!newEntry->isValid())
00168    {
00169       kdError(7011) << "KServiceFactory: corrupt object in KSycoca database!\n" << endl;
00170       delete newEntry;
00171       newEntry = 0;
00172    }
00173    return newEntry;
00174 }
00175 
00176 KService::List KServiceFactory::allServices()
00177 {
00178    KService::List result;
00179    KSycocaEntry::List list = allEntries();
00180    for( KSycocaEntry::List::Iterator it = list.begin();
00181         it != list.end();
00182         ++it)
00183    {
00184       KService *newService = dynamic_cast<KService *>((*it).data());
00185       if (newService)
00186          result.append( KService::Ptr( newService ) );
00187    }
00188    return result;
00189 }
00190 
00191 KService::List KServiceFactory::allInitServices()
00192 {
00193    KService::List list;
00194    if (!m_str) return list;
00195 
00196    // Assume we're NOT building a database
00197 
00198    m_str->device()->at(m_initListOffset);
00199    Q_INT32 entryCount;
00200    (*m_str) >> entryCount;
00201 
00202    Q_INT32 *offsetList = new Q_INT32[entryCount];
00203    for(int i = 0; i < entryCount; i++)
00204    {
00205       (*m_str) >> offsetList[i];
00206    }
00207 
00208    for(int i = 0; i < entryCount; i++)
00209    {
00210       KService *newEntry = createEntry(offsetList[i]);
00211       if (newEntry)
00212       {
00213          list.append( KService::Ptr( newEntry ) );
00214       }
00215    }
00216    delete [] offsetList;
00217    return list;
00218 }
00219 
00220 KService::List KServiceFactory::offers( int serviceTypeOffset )
00221 {
00222    KService::List list;
00223 
00224    QDataStream *str = m_str;
00225    // Jump to the offer list
00226    str->device()->at( m_offerListOffset );
00227 
00228    Q_INT32 aServiceTypeOffset;
00229    Q_INT32 aServiceOffset;
00230    // We might want to do a binary search instead of a linear search
00231    // since servicetype offsets are sorted. Bah.
00232    while (true)
00233    {
00234       (*str) >> aServiceTypeOffset;
00235       if ( aServiceTypeOffset )
00236       {
00237          (*str) >> aServiceOffset;
00238          if ( aServiceTypeOffset == serviceTypeOffset )
00239          {
00240             // Save stream position !
00241             int savedPos = str->device()->at();
00242             // Create Service
00243             KService * serv = createEntry( aServiceOffset );
00244             if (serv)
00245                 list.append( KService::Ptr( serv ) );
00246             // Restore position
00247             str->device()->at( savedPos );
00248          } else if ( aServiceTypeOffset > (Q_INT32)serviceTypeOffset )
00249             break; // too far
00250       }
00251       else
00252          break; // 0 => end of list
00253    }
00254    return list;
00255 }
00256 
00257 KServiceFactory *KServiceFactory::_self = 0;
00258 
00259 void KServiceFactory::virtual_hook( int id, void* data )
00260 { KSycocaFactory::virtual_hook( id, data ); }
00261 
KDE Logo
This file is part of the documentation for kdelibs Version 3.1.5.
Documentation copyright © 1996-2002 the KDE developers.
Generated on Wed Jan 28 13:14:18 2004 by doxygen 1.3.4 written by Dimitri van Heesch, © 1997-2001