fix logic
[personal-kdelibs.git] / kdecore / sycoca / ksycocafactory.cpp
blob155a827eb78d5e85fd938970e92b97fffeb4ceae
1 /* This file is part of the KDE libraries
2 * Copyright (C) 1999 David Faure <faure@kde.org>
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License version 2 as published by the Free Software Foundation;
8 * This library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * Library General Public License for more details.
13 * You should have received a copy of the GNU Library General Public License
14 * along with this library; see the file COPYING.LIB. If not, write to
15 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
16 * Boston, MA 02110-1301, USA.
19 #include "ksycocafactory.h"
20 #include "ksycoca.h"
21 #include "ksycocatype.h"
22 #include "ksycocaentry.h"
23 #include "ksycocadict.h"
25 #include <config.h>
26 #include <kdebug.h>
28 #include <QtCore/QMutableStringListIterator>
29 #include <QtCore/QHash>
31 class KSycocaFactory::Private
33 public:
34 Private() {}
35 ~Private()
37 delete m_sycocaDict;
40 int mOffset;
41 int m_sycocaDictOffset;
42 int m_beginEntryOffset;
43 int m_endEntryOffset;
44 KSycocaDict *m_sycocaDict;
47 KSycocaFactory::KSycocaFactory(KSycocaFactoryId factory_id)
48 : m_resourceList(0), m_entryDict(0), d(new Private)
50 if (!KSycoca::self()->isBuilding() && (m_str = KSycoca::self()->findFactory( factory_id )))
52 // Read position of index tables....
53 qint32 i;
54 (*m_str) >> i;
55 d->m_sycocaDictOffset = i;
56 (*m_str) >> i;
57 d->m_beginEntryOffset = i;
58 (*m_str) >> i;
59 d->m_endEntryOffset = i;
61 int saveOffset = m_str->device()->pos();
62 // Init index tables
63 d->m_sycocaDict = new KSycocaDict(m_str, d->m_sycocaDictOffset);
64 saveOffset = m_str->device()->seek(saveOffset);
66 else
68 // Build new database!
69 m_str = 0;
70 m_entryDict = new KSycocaEntryDict;
71 d->m_sycocaDict = new KSycocaDict;
72 d->m_beginEntryOffset = 0;
73 d->m_endEntryOffset = 0;
75 // m_resourceList will be filled in by inherited constructors
77 KSycoca::self()->addFactory(this);
80 KSycocaFactory::~KSycocaFactory()
82 delete m_entryDict;
83 delete d;
86 void
87 KSycocaFactory::saveHeader(QDataStream &str)
89 // Write header
90 str.device()->seek(d->mOffset);
91 str << (qint32) d->m_sycocaDictOffset;
92 str << (qint32) d->m_beginEntryOffset;
93 str << (qint32) d->m_endEntryOffset;
96 void
97 KSycocaFactory::save(QDataStream &str)
99 if (!m_entryDict) return; // Error! Function should only be called when
100 // building database
101 if (!d->m_sycocaDict) return; // Error!
103 d->mOffset = str.device()->pos(); // store position in member variable
104 d->m_sycocaDictOffset = 0;
106 // Write header (pass #1)
107 saveHeader(str);
109 d->m_beginEntryOffset = str.device()->pos();
111 // Write all entries.
112 int entryCount = 0;
113 for(KSycocaEntryDict::Iterator it = m_entryDict->begin();
114 it != m_entryDict->end(); ++it)
116 KSycocaEntry::Ptr entry = *it;
117 entry->save(str);
118 entryCount++;
121 d->m_endEntryOffset = str.device()->pos();
123 // Write indices...
124 // Linear index
125 str << (qint32) entryCount;
126 for(KSycocaEntryDict::Iterator it = m_entryDict->begin();
127 it != m_entryDict->end(); ++it)
129 str << qint32(it->data()->offset());
132 // Dictionary index
133 d->m_sycocaDictOffset = str.device()->pos();
134 d->m_sycocaDict->save(str);
136 int endOfFactoryData = str.device()->pos();
138 // Update header (pass #2)
139 saveHeader(str);
141 // Seek to end.
142 str.device()->seek(endOfFactoryData);
145 void
146 KSycocaFactory::addEntry(const KSycocaEntry::Ptr& newEntry)
148 if (!m_entryDict) return; // Error! Function should only be called when
149 // building database
151 if (!d->m_sycocaDict) return; // Error!
153 const QString name = newEntry->storageId();
154 m_entryDict->insert( name, newEntry );
155 d->m_sycocaDict->add( name, newEntry );
158 void
159 KSycocaFactory::removeEntry(const QString& entryName)
161 if (!m_entryDict) return; // Error! Function should only be called when
162 // building database
164 if (!d->m_sycocaDict) return; // Error!
166 m_entryDict->remove( entryName );
167 d->m_sycocaDict->remove( entryName ); // O(N)
170 KSycocaEntry::List KSycocaFactory::allEntries() const
172 KSycocaEntry::List list;
173 if (!m_str) return list;
175 // Assume we're NOT building a database
177 m_str->device()->seek(d->m_endEntryOffset);
178 qint32 entryCount;
179 (*m_str) >> entryCount;
181 if (entryCount > 8192)
183 KSycoca::flagError();
184 return list;
187 // offsetList is needed because createEntry() modifies the stream position
188 qint32 *offsetList = new qint32[entryCount];
189 for(int i = 0; i < entryCount; i++)
191 (*m_str) >> offsetList[i];
194 for(int i = 0; i < entryCount; i++)
196 KSycocaEntry *newEntry = createEntry(offsetList[i]);
197 if (newEntry)
199 list.append( KSycocaEntry::Ptr( newEntry ) );
202 delete [] offsetList;
203 return list;
206 int KSycocaFactory::offset() const
208 return d->mOffset;
211 const KSycocaResourceList * KSycocaFactory::resourceList() const
213 return m_resourceList;
216 const KSycocaDict * KSycocaFactory::sycocaDict() const
218 return d->m_sycocaDict;
221 bool KSycocaFactory::isEmpty() const
223 return d->m_beginEntryOffset == d->m_endEntryOffset;
226 void KSycocaFactory::virtual_hook( int /*id*/, void* /*data*/)
227 { /*BASE::virtual_hook( id, data );*/ }