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() {}
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
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
00063 d->m_sycocaDict = new KSycocaDict(str, d->m_sycocaDictOffset);
00064 saveOffset = str->device()->seek(saveOffset);
00065 } else {
00066
00067 m_entryDict = new KSycocaEntryDict;
00068 d->m_sycocaDict = new KSycocaDict;
00069 d->m_beginEntryOffset = 0;
00070 d->m_endEntryOffset = 0;
00071
00072
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
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;
00097
00098 if (!d->m_sycocaDict) return;
00099
00100 d->mOffset = str.device()->pos();
00101 d->m_sycocaDictOffset = 0;
00102
00103
00104 saveHeader(str);
00105
00106 d->m_beginEntryOffset = str.device()->pos();
00107
00108
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
00121
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
00130 d->m_sycocaDictOffset = str.device()->pos();
00131 d->m_sycocaDict->save(str);
00132
00133 int endOfFactoryData = str.device()->pos();
00134
00135
00136 saveHeader(str);
00137
00138
00139 str.device()->seek(endOfFactoryData);
00140 }
00141
00142 void
00143 KSycocaFactory::addEntry(const KSycocaEntry::Ptr& newEntry)
00144 {
00145 if (!m_entryDict) return;
00146
00147
00148 if (!d->m_sycocaDict) return;
00149
00150 KSycocaEntry::Ptr oldEntry = m_entryDict->value(newEntry->storageId());
00151 if (oldEntry) {
00152
00153
00154
00155
00156
00157
00158
00159
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;
00172
00173
00174 if (!d->m_sycocaDict) return;
00175
00176 m_entryDict->remove( entryName );
00177 d->m_sycocaDict->remove( entryName );
00178 }
00179
00180 KSycocaEntry::List KSycocaFactory::allEntries() const
00181 {
00182 KSycocaEntry::List list;
00183
00184
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
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 , void* )
00244 { }
00245