• Skip to content
  • Skip to link menu
KDE 4.3 API Reference
  • KDE API Reference
  • kdelibs
  • Sitemap
  • Contact Us
 

KDECore

ksycocafactory.cpp

Go to the documentation of this file.
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., 51 Franklin Street, Fifth Floor,
00016  *  Boston, MA 02110-1301, USA.
00017  */
00018 
00019 #include "ksycocafactory.h"
00020 #include "ksycoca.h"
00021 #include "ksycocatype.h"
00022 #include "ksycocaentry.h"
00023 #include "ksycocadict.h"
00024 
00025 #include <config.h>
00026 #include <kdebug.h>
00027 
00028 #include <QThread>
00029 #include <QtCore/QHash>
00030 
00031 class KSycocaFactory::Private
00032 {
00033 public:
00034     Private() {}
00035     ~Private()
00036     {
00037         delete m_sycocaDict;
00038     }
00039 
00040     int mOffset;
00041     int m_sycocaDictOffset;
00042     int m_beginEntryOffset;
00043     int m_endEntryOffset;
00044     KSycocaDict *m_sycocaDict;
00045 };
00046 
00047 KSycocaFactory::KSycocaFactory(KSycocaFactoryId factory_id)
00048     : m_resourceList(0), m_entryDict(0), m_str(0), d(new Private)
00049 {
00050     if (!KSycoca::self()->isBuilding() && (m_str = KSycoca::self()->findFactory(factory_id))) {
00051         // Read position of index tables....
00052         qint32 i;
00053         (*m_str) >> i;
00054         d->m_sycocaDictOffset = i;
00055         (*m_str) >> i;
00056         d->m_beginEntryOffset = i;
00057         (*m_str) >> i;
00058         d->m_endEntryOffset = i;
00059 
00060         QDataStream* str = stream();
00061         int saveOffset = str->device()->pos();
00062         // Init index tables
00063         d->m_sycocaDict = new KSycocaDict(str, d->m_sycocaDictOffset);
00064         saveOffset = str->device()->seek(saveOffset);
00065     } else {
00066         // We are in kbuildsycoca4 -- build new database!
00067         m_entryDict = new KSycocaEntryDict;
00068         d->m_sycocaDict = new KSycocaDict;
00069         d->m_beginEntryOffset = 0;
00070         d->m_endEntryOffset = 0;
00071 
00072         // m_resourceList will be filled in by inherited constructors
00073     }
00074     KSycoca::self()->addFactory(this);
00075 }
00076 
00077 KSycocaFactory::~KSycocaFactory()
00078 {
00079     delete m_entryDict;
00080     delete d;
00081 }
00082 
00083 void
00084 KSycocaFactory::saveHeader(QDataStream &str)
00085 {
00086     // Write header
00087     str.device()->seek(d->mOffset);
00088     str << (qint32) d->m_sycocaDictOffset;
00089     str << (qint32) d->m_beginEntryOffset;
00090     str << (qint32) d->m_endEntryOffset;
00091 }
00092 
00093 void
00094 KSycocaFactory::save(QDataStream &str)
00095 {
00096     if (!m_entryDict) return; // Error! Function should only be called when
00097     // building database
00098     if (!d->m_sycocaDict) return; // Error!
00099 
00100     d->mOffset = str.device()->pos(); // store position in member variable
00101     d->m_sycocaDictOffset = 0;
00102 
00103     // Write header (pass #1)
00104     saveHeader(str);
00105 
00106     d->m_beginEntryOffset = str.device()->pos();
00107 
00108     // Write all entries.
00109     int entryCount = 0;
00110     for(KSycocaEntryDict::Iterator it = m_entryDict->begin();
00111         it != m_entryDict->end(); ++it)
00112     {
00113         KSycocaEntry::Ptr entry = *it;
00114         entry->save(str);
00115         entryCount++;
00116     }
00117 
00118     d->m_endEntryOffset = str.device()->pos();
00119 
00120     // Write indices...
00121     // Linear index
00122     str << (qint32) entryCount;
00123     for(KSycocaEntryDict::Iterator it = m_entryDict->begin();
00124         it != m_entryDict->end(); ++it)
00125     {
00126         str << qint32(it->data()->offset());
00127     }
00128 
00129     // Dictionary index
00130     d->m_sycocaDictOffset = str.device()->pos();
00131     d->m_sycocaDict->save(str);
00132 
00133     int endOfFactoryData = str.device()->pos();
00134 
00135     // Update header (pass #2)
00136     saveHeader(str);
00137 
00138     // Seek to end.
00139     str.device()->seek(endOfFactoryData);
00140 }
00141 
00142 void
00143 KSycocaFactory::addEntry(const KSycocaEntry::Ptr& newEntry)
00144 {
00145     if (!m_entryDict) return; // Error! Function should only be called when
00146     // building database
00147 
00148     if (!d->m_sycocaDict) return; // Error!
00149 
00150     KSycocaEntry::Ptr oldEntry = m_entryDict->value(newEntry->storageId());
00151     if (oldEntry) {
00152         // Already exists -> replace
00153         // We found a more-local override, e.g. ~/.local/share/applications/kde4/foo.desktop
00154         // So forget about the more global file.
00155         //
00156         // This can also happen with two .protocol files using the same protocol= entry.
00157         // If we didn't remove one here, we would end up asserting because save()
00158         // wasn't called on one of the entries.
00159         //kDebug(7021) << "removing" << oldEntry.data() << oldEntry->entryPath() << "because of" << newEntry->entryPath() << "they have the same storageId" << newEntry->storageId();
00160         removeEntry(newEntry->storageId());
00161     }
00162 
00163     const QString name = newEntry->storageId();
00164     m_entryDict->insert( name, newEntry );
00165     d->m_sycocaDict->add( name, newEntry );
00166 }
00167 
00168 void
00169 KSycocaFactory::removeEntry(const QString& entryName)
00170 {
00171     if (!m_entryDict) return; // Error! Function should only be called when
00172     // building database
00173 
00174     if (!d->m_sycocaDict) return; // Error!
00175 
00176     m_entryDict->remove( entryName );
00177     d->m_sycocaDict->remove( entryName ); // O(N)
00178 }
00179 
00180 KSycocaEntry::List KSycocaFactory::allEntries() const
00181 {
00182     KSycocaEntry::List list;
00183 
00184     // Assume we're NOT building a database
00185 
00186     QDataStream* str = stream();
00187     if (!str) return list;
00188     str->device()->seek(d->m_endEntryOffset);
00189     qint32 entryCount;
00190     (*str) >> entryCount;
00191 
00192     if (entryCount > 8192)
00193     {
00194         kDebug(7021) << QThread::currentThread() << "error detected in factory" << this;
00195         KSycoca::flagError();
00196         return list;
00197     }
00198 
00199     // offsetList is needed because createEntry() modifies the stream position
00200     qint32 *offsetList = new qint32[entryCount];
00201     for(int i = 0; i < entryCount; i++)
00202     {
00203         (*str) >> offsetList[i];
00204     }
00205 
00206     for(int i = 0; i < entryCount; i++)
00207     {
00208         KSycocaEntry *newEntry = createEntry(offsetList[i]);
00209         if (newEntry)
00210         {
00211             list.append( KSycocaEntry::Ptr( newEntry ) );
00212         }
00213     }
00214     delete [] offsetList;
00215     return list;
00216 }
00217 
00218 int KSycocaFactory::offset() const
00219 {
00220     return d->mOffset;
00221 }
00222 
00223 const KSycocaResourceList * KSycocaFactory::resourceList() const
00224 {
00225     return m_resourceList;
00226 }
00227 
00228 const KSycocaDict * KSycocaFactory::sycocaDict() const
00229 {
00230     return d->m_sycocaDict;
00231 }
00232 
00233 bool KSycocaFactory::isEmpty() const
00234 {
00235     return d->m_beginEntryOffset == d->m_endEntryOffset;
00236 }
00237 
00238 QDataStream* KSycocaFactory::stream() const
00239 {
00240     return m_str;
00241 }
00242 
00243 void KSycocaFactory::virtual_hook( int /*id*/, void* /*data*/)
00244 { /*BASE::virtual_hook( id, data );*/ }
00245 

KDECore

Skip menu "KDECore"
  • Main Page
  • Modules
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

kdelibs

Skip menu "kdelibs"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • Kate
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs by doxygen 1.6.1
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal