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"
21 #include "ksycocatype.h"
22 #include "ksycocaentry.h"
23 #include "ksycocadict.h"
28 #include <QtCore/QMutableStringListIterator>
29 #include <QtCore/QHash>
31 class KSycocaFactory::Private
41 int m_sycocaDictOffset
;
42 int m_beginEntryOffset
;
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....
55 d
->m_sycocaDictOffset
= i
;
57 d
->m_beginEntryOffset
= i
;
59 d
->m_endEntryOffset
= i
;
61 int saveOffset
= m_str
->device()->pos();
63 d
->m_sycocaDict
= new KSycocaDict(m_str
, d
->m_sycocaDictOffset
);
64 saveOffset
= m_str
->device()->seek(saveOffset
);
68 // Build new database!
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()
87 KSycocaFactory::saveHeader(QDataStream
&str
)
90 str
.device()->seek(d
->mOffset
);
91 str
<< (qint32
) d
->m_sycocaDictOffset
;
92 str
<< (qint32
) d
->m_beginEntryOffset
;
93 str
<< (qint32
) d
->m_endEntryOffset
;
97 KSycocaFactory::save(QDataStream
&str
)
99 if (!m_entryDict
) return; // Error! Function should only be called when
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)
109 d
->m_beginEntryOffset
= str
.device()->pos();
111 // Write all entries.
113 for(KSycocaEntryDict::Iterator it
= m_entryDict
->begin();
114 it
!= m_entryDict
->end(); ++it
)
116 KSycocaEntry::Ptr entry
= *it
;
121 d
->m_endEntryOffset
= str
.device()->pos();
125 str
<< (qint32
) entryCount
;
126 for(KSycocaEntryDict::Iterator it
= m_entryDict
->begin();
127 it
!= m_entryDict
->end(); ++it
)
129 str
<< qint32(it
->data()->offset());
133 d
->m_sycocaDictOffset
= str
.device()->pos();
134 d
->m_sycocaDict
->save(str
);
136 int endOfFactoryData
= str
.device()->pos();
138 // Update header (pass #2)
142 str
.device()->seek(endOfFactoryData
);
146 KSycocaFactory::addEntry(const KSycocaEntry::Ptr
& newEntry
)
148 if (!m_entryDict
) return; // Error! Function should only be called when
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
);
159 KSycocaFactory::removeEntry(const QString
& entryName
)
161 if (!m_entryDict
) return; // Error! Function should only be called when
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
);
179 (*m_str
) >> entryCount
;
181 if (entryCount
> 8192)
183 KSycoca::flagError();
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
]);
199 list
.append( KSycocaEntry::Ptr( newEntry
) );
202 delete [] offsetList
;
206 int KSycocaFactory::offset() const
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 );*/ }