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 "ksycoca.h" 00020 #include "ksycocatype.h" 00021 #include "ksycocafactory.h" 00022 #include "ksycocaentry.h" 00023 #include "ksycocadict.h" 00024 #include <qstringlist.h> 00025 #include <qdict.h> 00026 #include <kdebug.h> 00027 00028 template class QDict<KSycocaEntry>; 00029 template class QDict<KSharedPtr<KSycocaEntry> >; 00030 00031 KSycocaFactory::KSycocaFactory(KSycocaFactoryId factory_id) 00032 : m_resourceList(0), m_entryDict(0), m_sycocaDict(0) 00033 { 00034 if (!KSycoca::self()->isBuilding()) // read-only database ? 00035 { 00036 m_str = KSycoca::self()->findFactory( factory_id ); 00037 // can't call factoryId() here since the constructor can't call inherited methods 00038 if (m_str) // Can be 0 in case of errors 00039 { 00040 // Read position of index tables.... 00041 Q_INT32 i; 00042 (*m_str) >> i; 00043 m_sycocaDictOffset = i; 00044 (*m_str) >> i; 00045 m_beginEntryOffset = i; 00046 (*m_str) >> i; 00047 m_endEntryOffset = i; 00048 00049 int saveOffset = m_str->device()->at(); 00050 // Init index tables 00051 m_sycocaDict = new KSycocaDict(m_str, m_sycocaDictOffset); 00052 saveOffset = m_str->device()->at(saveOffset); 00053 } 00054 } 00055 else 00056 { 00057 // Build new database! 00058 m_str = 0; 00059 m_resourceList = 0; 00060 m_entryDict = new KSycocaEntryDict(977); 00061 m_entryDict->setAutoDelete(true); 00062 m_sycocaDict = new KSycocaDict(); 00063 m_beginEntryOffset = 0; 00064 m_endEntryOffset = 0; 00065 00066 // m_resourceList will be filled in by inherited constructors 00067 } 00068 KSycoca::self()->addFactory(this); 00069 } 00070 00071 KSycocaFactory::~KSycocaFactory() 00072 { 00073 delete m_entryDict; 00074 delete m_sycocaDict; 00075 } 00076 00077 void 00078 KSycocaFactory::saveHeader(QDataStream &str) 00079 { 00080 // Write header 00081 str.device()->at(mOffset); 00082 str << (Q_INT32) m_sycocaDictOffset; 00083 str << (Q_INT32) m_beginEntryOffset; 00084 str << (Q_INT32) m_endEntryOffset; 00085 } 00086 00087 void 00088 KSycocaFactory::save(QDataStream &str) 00089 { 00090 if (!m_entryDict) return; // Error! Function should only be called when 00091 // building database 00092 if (!m_sycocaDict) return; // Error! 00093 00094 mOffset = str.device()->at(); // store position in member variable 00095 m_sycocaDictOffset = 0; 00096 00097 // Write header (pass #1) 00098 saveHeader(str); 00099 00100 m_beginEntryOffset = str.device()->at(); 00101 00102 // Write all entries. 00103 int entryCount = 0; 00104 for(QDictIterator<KSycocaEntry::Ptr> it ( *m_entryDict ); 00105 it.current(); 00106 ++it) 00107 { 00108 KSycocaEntry *entry = (*it.current()); 00109 entry->save(str); 00110 entryCount++; 00111 } 00112 00113 m_endEntryOffset = str.device()->at(); 00114 00115 // Write indices... 00116 // Linear index 00117 str << (Q_INT32) entryCount; 00118 for(QDictIterator<KSycocaEntry::Ptr> it ( *m_entryDict ); 00119 it.current(); 00120 ++it) 00121 { 00122 KSycocaEntry *entry = (*it.current()); 00123 str << (Q_INT32) entry->offset(); 00124 } 00125 00126 // Dictionary index 00127 m_sycocaDictOffset = str.device()->at(); 00128 m_sycocaDict->save(str); 00129 00130 int endOfFactoryData = str.device()->at(); 00131 00132 // Update header (pass #2) 00133 saveHeader(str); 00134 00135 // Seek to end. 00136 str.device()->at(endOfFactoryData); 00137 } 00138 00139 void 00140 KSycocaFactory::addEntry(KSycocaEntry *newEntry, const char *) 00141 { 00142 if (!m_entryDict) return; // Error! Function should only be called when 00143 // building database 00144 00145 if (!m_sycocaDict) return; // Error! 00146 00147 QString name = newEntry->name(); 00148 m_entryDict->insert( name, new KSycocaEntry::Ptr(newEntry) ); 00149 m_sycocaDict->add( name, newEntry ); 00150 } 00151 00152 void 00153 KSycocaFactory::removeEntry(KSycocaEntry *newEntry) 00154 { 00155 if (!m_entryDict) return; // Error! Function should only be called when 00156 // building database 00157 00158 if (!m_sycocaDict) return; // Error! 00159 00160 QString name = newEntry->name(); 00161 m_entryDict->remove( name ); 00162 m_sycocaDict->remove( name ); 00163 } 00164 00165 KSycocaEntry::List KSycocaFactory::allEntries() 00166 { 00167 KSycocaEntry::List list; 00168 if (!m_str) return list; 00169 00170 // Assume we're NOT building a database 00171 00172 m_str->device()->at(m_endEntryOffset); 00173 Q_INT32 entryCount; 00174 (*m_str) >> entryCount; 00175 00176 if (entryCount > 8192) 00177 { 00178 KSycoca::flagError(); 00179 return list; 00180 } 00181 00182 Q_INT32 *offsetList = new Q_INT32[entryCount]; 00183 for(int i = 0; i < entryCount; i++) 00184 { 00185 (*m_str) >> offsetList[i]; 00186 } 00187 00188 for(int i = 0; i < entryCount; i++) 00189 { 00190 KSycocaEntry *newEntry = createEntry(offsetList[i]); 00191 if (newEntry) 00192 { 00193 list.append( KSycocaEntry::Ptr( newEntry ) ); 00194 } 00195 } 00196 delete [] offsetList; 00197 return list; 00198 } 00199 00200 void KSycocaFactory::virtual_hook( int /*id*/, void* /*data*/) 00201 { /*BASE::virtual_hook( id, data );*/ } 00202