kio Library API Documentation

kservicetypefactory.cpp

00001 /* This file is part of the KDE libraries 00002 * Copyright (C) 1999 Waldo Bastian <bastian@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., 59 Temple Place - Suite 330, 00016 * Boston, MA 02111-1307, USA. 00017 **/ 00018 00019 #include "kservicetypefactory.h" 00020 #include "ksycoca.h" 00021 #include "ksycocatype.h" 00022 #include "ksycocadict.h" 00023 #include "kservicetype.h" 00024 #include "kmimetype.h" 00025 #include "kuserprofile.h" 00026 00027 #include <kapplication.h> 00028 #include <kdebug.h> 00029 #include <assert.h> 00030 #include <kstringhandler.h> 00031 #include <qfile.h> 00032 00033 KServiceTypeFactory::KServiceTypeFactory() 00034 : KSycocaFactory( KST_KServiceTypeFactory ) 00035 { 00036 _self = this; 00037 m_fastPatternOffset = 0; 00038 m_otherPatternOffset = 0; 00039 if (m_str) 00040 { 00041 // Read Header 00042 Q_INT32 i,n; 00043 (*m_str) >> i; 00044 m_fastPatternOffset = i; 00045 (*m_str) >> i; 00046 m_otherPatternOffset = i; 00047 (*m_str) >> n; 00048 00049 if (n > 1024) 00050 { 00051 KSycoca::flagError(); 00052 } 00053 else 00054 { 00055 QString str; 00056 for(;n;n--) 00057 { 00058 KSycocaEntry::read(*m_str, str); 00059 (*m_str) >> i; 00060 m_propertyTypeDict.insert(str, i); 00061 } 00062 } 00063 } 00064 } 00065 00066 00067 KServiceTypeFactory::~KServiceTypeFactory() 00068 { 00069 _self = 0L; 00070 KServiceTypeProfile::clear(); 00071 } 00072 00073 KServiceTypeFactory * KServiceTypeFactory::self() 00074 { 00075 if (!_self) 00076 _self = new KServiceTypeFactory(); 00077 return _self; 00078 } 00079 00080 KServiceType * KServiceTypeFactory::findServiceTypeByName(const QString &_name) 00081 { 00082 if (!m_sycocaDict) return 0L; // Error! 00083 assert (!KSycoca::self()->isBuilding()); 00084 int offset = m_sycocaDict->find_string( _name ); 00085 if (!offset) return 0; // Not found 00086 KServiceType * newServiceType = createEntry(offset); 00087 00088 // Check whether the dictionary was right. 00089 if (newServiceType && (newServiceType->name() != _name)) 00090 { 00091 // No it wasn't... 00092 delete newServiceType; 00093 newServiceType = 0; // Not found 00094 } 00095 return newServiceType; 00096 } 00097 00098 QVariant::Type KServiceTypeFactory::findPropertyTypeByName(const QString &_name) 00099 { 00100 if (!m_sycocaDict) 00101 return QVariant::Invalid; // Error! 00102 00103 assert (!KSycoca::self()->isBuilding()); 00104 00105 QMapConstIterator<QString,int> it = m_propertyTypeDict.find(_name); 00106 if (it != m_propertyTypeDict.end()) { 00107 return (QVariant::Type)it.data(); 00108 } 00109 00110 return QVariant::Invalid; 00111 } 00112 00113 KMimeType * KServiceTypeFactory::findFromPattern(const QString &_filename, QString *match) 00114 { 00115 // Assume we're NOT building a database 00116 if (!m_str) return 0; 00117 00118 // Get stream to the header 00119 QDataStream *str = m_str; 00120 00121 str->device()->at( m_fastPatternOffset ); 00122 00123 Q_INT32 nrOfEntries; 00124 (*str) >> nrOfEntries; 00125 Q_INT32 entrySize; 00126 (*str) >> entrySize; 00127 00128 Q_INT32 fastOffset = str->device()->at( ); 00129 00130 Q_INT32 matchingOffset = 0; 00131 00132 // Let's go for a binary search in the "fast" pattern index 00133 Q_INT32 left = 0; 00134 Q_INT32 right = nrOfEntries - 1; 00135 Q_INT32 middle; 00136 // Extract extension 00137 int lastDot = _filename.findRev('.'); 00138 int ext_len = _filename.length() - lastDot - 1; 00139 if (lastDot != -1 && ext_len <= 4) // if no '.', skip the extension lookup 00140 { 00141 QString extension = _filename.right( ext_len ); 00142 extension = extension.leftJustify(4); 00143 00144 QString pattern; 00145 while (left <= right) { 00146 middle = (left + right) / 2; 00147 // read pattern at position "middle" 00148 str->device()->at( middle * entrySize + fastOffset ); 00149 KSycocaEntry::read(*str, pattern); 00150 int cmp = pattern.compare( extension ); 00151 if (cmp < 0) 00152 left = middle + 1; 00153 else if (cmp == 0) // found 00154 { 00155 (*str) >> matchingOffset; 00156 // don't return newServiceType - there may be an "other" pattern that 00157 // matches best this file, like *.tar.bz 00158 if (match) 00159 *match = "*."+pattern; 00160 break; // but get out of the fast patterns 00161 } 00162 else 00163 right = middle - 1; 00164 } 00165 } 00166 00167 // Now try the "other" Pattern table 00168 if ( m_patterns.isEmpty() ) { 00169 str->device()->at( m_otherPatternOffset ); 00170 00171 QString pattern; 00172 Q_INT32 mimetypeOffset; 00173 00174 while (true) 00175 { 00176 KSycocaEntry::read(*str, pattern); 00177 if (pattern.isEmpty()) // end of list 00178 break; 00179 (*str) >> mimetypeOffset; 00180 m_patterns.push_back( pattern ); 00181 m_pattern_offsets.push_back( mimetypeOffset ); 00182 } 00183 } 00184 00185 assert( m_patterns.size() == m_pattern_offsets.size() ); 00186 00187 QStringList::const_iterator it = m_patterns.begin(); 00188 QStringList::const_iterator end = m_patterns.end(); 00189 QValueVector<Q_INT32>::const_iterator it_offset = m_pattern_offsets.begin(); 00190 00191 for ( ; it != end; ++it, ++it_offset ) 00192 { 00193 if ( KStringHandler::matchFileName( _filename, *it ) ) 00194 { 00195 matchingOffset = *it_offset; 00196 if (match) 00197 *match = *it; 00198 break; 00199 } 00200 } 00201 00202 if ( matchingOffset ) { 00203 KServiceType *newServiceType = createEntry( matchingOffset ); 00204 assert (newServiceType && newServiceType->isType( KST_KMimeType )); 00205 return (KMimeType *) newServiceType; 00206 } 00207 else 00208 return 0; 00209 } 00210 00211 KMimeType::List KServiceTypeFactory::allMimeTypes() 00212 { 00213 KMimeType::List result; 00214 KSycocaEntry::List list = allEntries(); 00215 for( KSycocaEntry::List::Iterator it = list.begin(); 00216 it != list.end(); 00217 ++it) 00218 { 00219 KMimeType *newMimeType = dynamic_cast<KMimeType *>((*it).data()); 00220 if (newMimeType) 00221 result.append( KMimeType::Ptr( newMimeType ) ); 00222 } 00223 return result; 00224 } 00225 00226 KServiceType::List KServiceTypeFactory::allServiceTypes() 00227 { 00228 KServiceType::List result; 00229 KSycocaEntry::List list = allEntries(); 00230 for( KSycocaEntry::List::Iterator it = list.begin(); 00231 it != list.end(); 00232 ++it) 00233 { 00234 #ifndef Q_WS_QWS 00235 KServiceType *newServiceType = dynamic_cast<KServiceType *>((*it).data()); 00236 #else //FIXME 00237 KServiceType *newServiceType = (KServiceType*)(*it).data(); 00238 #endif 00239 if (newServiceType) 00240 result.append( KServiceType::Ptr( newServiceType ) ); 00241 } 00242 return result; 00243 } 00244 00245 bool KServiceTypeFactory::checkMimeTypes() 00246 { 00247 QDataStream *str = KSycoca::self()->findFactory( factoryId() ); 00248 if (!str) return false; 00249 00250 // check if there are mimetypes/servicetypes 00251 return (m_beginEntryOffset != m_endEntryOffset); 00252 } 00253 00254 KServiceType * KServiceTypeFactory::createEntry(int offset) 00255 { 00256 KServiceType *newEntry = 0; 00257 KSycocaType type; 00258 QDataStream *str = KSycoca::self()->findEntry(offset, type); 00259 if (!str) return 0; 00260 00261 switch(type) 00262 { 00263 case KST_KServiceType: 00264 newEntry = new KServiceType(*str, offset); 00265 break; 00266 case KST_KMimeType: 00267 newEntry = new KMimeType(*str, offset); 00268 break; 00269 case KST_KFolderType: 00270 newEntry = new KFolderType(*str, offset); 00271 break; 00272 case KST_KDEDesktopMimeType: 00273 newEntry = new KDEDesktopMimeType(*str, offset); 00274 break; 00275 case KST_KExecMimeType: 00276 newEntry = new KExecMimeType(*str, offset); 00277 break; 00278 00279 default: 00280 kdError(7011) << QString("KServiceTypeFactory: unexpected object entry in KSycoca database (type = %1)").arg((int)type) << endl; 00281 break; 00282 } 00283 if (!newEntry->isValid()) 00284 { 00285 kdError(7011) << "KServiceTypeFactory: corrupt object in KSycoca database!\n" << endl; 00286 delete newEntry; 00287 newEntry = 0; 00288 } 00289 return newEntry; 00290 } 00291 00292 KServiceTypeFactory *KServiceTypeFactory::_self = 0; 00293 00294 void KServiceTypeFactory::virtual_hook( int id, void* data ) 00295 { KSycocaFactory::virtual_hook( id, data ); } 00296 00297 // vim: ts=3 sw=3 et
KDE Logo
This file is part of the documentation for kio Library Version 3.2.3.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Wed Mar 16 17:22:31 2005 by doxygen 1.3.7 written by Dimitri van Heesch, © 1997-2003