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

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