KDECore
ksycocafactory.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
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
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
00066 d->m_sycocaDict = new KSycocaDict(str, d->m_sycocaDictOffset);
00067 saveOffset = str->device()->seek(saveOffset);
00068 } else {
00069
00070 m_entryDict = new KSycocaEntryDict;
00071 d->m_sycocaDict = new KSycocaDict;
00072 d->m_beginEntryOffset = 0;
00073 d->m_endEntryOffset = 0;
00074
00075
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
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;
00100
00101 if (!d->m_sycocaDict) return;
00102
00103 d->mOffset = str.device()->pos();
00104 d->m_sycocaDictOffset = 0;
00105
00106
00107 saveHeader(str);
00108
00109 d->m_beginEntryOffset = str.device()->pos();
00110
00111
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
00124
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
00133 d->m_sycocaDictOffset = str.device()->pos();
00134 d->m_sycocaDict->save(str);
00135
00136 int endOfFactoryData = str.device()->pos();
00137
00138
00139 saveHeader(str);
00140
00141
00142 str.device()->seek(endOfFactoryData);
00143 }
00144
00145 void
00146 KSycocaFactory::addEntry(const KSycocaEntry::Ptr& newEntry)
00147 {
00148 if (!m_entryDict) return;
00149
00150
00151 if (!d->m_sycocaDict) return;
00152
00153 KSycocaEntry::Ptr oldEntry = m_entryDict->value(newEntry->storageId());
00154 if (oldEntry) {
00155
00156
00157
00158
00159
00160
00161
00162
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;
00175
00176
00177 if (!d->m_sycocaDict) return;
00178
00179 m_entryDict->remove( entryName );
00180 d->m_sycocaDict->remove( entryName );
00181 }
00182
00183 KSycocaEntry::List KSycocaFactory::allEntries() const
00184 {
00185 KSycocaEntry::List list;
00186
00187
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
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 , void* )
00247 { }
00248