# kio Library API Documentation

Overview | Class Hierarchy | Classes | Classes (annotated) | Members | Namespaces | Source Files

# 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          if ( !matchingOffset || !(*it).endsWith( "*" ) ) // *.html wins over Makefile.*
    00196          {
    00197              matchingOffset = *it_offset;
    00198              if (match)
    00199                 *match = *it;
    00200              break;
    00201          }
    00202       }
    00203    }
    00204
    00205    if ( matchingOffset ) {
    00206       KServiceType *newServiceType = createEntry( matchingOffset );
    00207       assert (newServiceType && newServiceType->isType( KST_KMimeType ));
    00208       return (KMimeType *) newServiceType;
    00209    }
    00210    else
    00211       return 0;
    00212 }
    00213
    00214 KMimeType::List KServiceTypeFactory::allMimeTypes()
    00215 {
    00216    KMimeType::List result;
    00217    KSycocaEntry::List list = allEntries();
    00218    for( KSycocaEntry::List::Iterator it = list.begin();
    00219         it != list.end();
    00220         ++it)
    00221    {
    00222       KMimeType *newMimeType = dynamic_cast<KMimeType *>((*it).data());
    00223       if (newMimeType)
    00224          result.append( KMimeType::Ptr( newMimeType ) );
    00225    }
    00226    return result;
    00227 }
    00228
    00229 KServiceType::List KServiceTypeFactory::allServiceTypes()
    00230 {
    00231    KServiceType::List result;
    00232    KSycocaEntry::List list = allEntries();
    00233    for( KSycocaEntry::List::Iterator it = list.begin();
    00234         it != list.end();
    00235         ++it)
    00236    {
    00237 #ifndef Q_WS_QWS
    00238       KServiceType *newServiceType = dynamic_cast<KServiceType *>((*it).data());
    00239 #else //FIXME
    00240       KServiceType *newServiceType = (KServiceType*)(*it).data();
    00241 #endif
    00242       if (newServiceType)
    00243          result.append( KServiceType::Ptr( newServiceType ) );
    00244    }
    00245    return result;
    00246 }
    00247
    00248 bool KServiceTypeFactory::checkMimeTypes()
    00249 {
    00250    QDataStream *str = KSycoca::self()->findFactory( factoryId() );
    00251    if (!str) return false;
    00252
    00253    // check if there are mimetypes/servicetypes
    00254    return (m_beginEntryOffset != m_endEntryOffset);
    00255 }
    00256
    00257 KServiceType * KServiceTypeFactory::createEntry(int offset)
    00258 {
    00259    KServiceType *newEntry = 0;
    00260    KSycocaType type;
    00261    QDataStream *str = KSycoca::self()->findEntry(offset, type);
    00262    if (!str) return 0;
    00263
    00264    switch(type)
    00265    {
    00266      case KST_KServiceType:
    00267         newEntry = new KServiceType(*str, offset);
    00268         break;
    00269      case KST_KMimeType:
    00270         newEntry = new KMimeType(*str, offset);
    00271         break;
    00272      case KST_KFolderType:
    00273         newEntry = new KFolderType(*str, offset);
    00274         break;
    00275      case KST_KDEDesktopMimeType:
    00276         newEntry = new KDEDesktopMimeType(*str, offset);
    00277         break;
    00278      case KST_KExecMimeType:
    00279         newEntry = new KExecMimeType(*str, offset);
    00280         break;
    00281
    00282      default:
    00283         kdError(7011) << QString("KServiceTypeFactory: unexpected object entry in KSycoca database (type = %1)").arg((int)type) << endl;
    00284         break;
    00285    }
    00286    if (!newEntry->isValid())
    00287    {
    00288       kdError(7011) << "KServiceTypeFactory: corrupt object in KSycoca database!\n" << endl;
    00289       delete newEntry;
    00290       newEntry = 0;
    00291    }
    00292    return newEntry;
    00293 }
    00294
    00295 KServiceTypeFactory *KServiceTypeFactory::_self = 0;
    00296
    00297 void KServiceTypeFactory::virtual_hook( int id, void* data )
    00298 { KSycocaFactory::virtual_hook( id, data ); }
    00299
    00300 // vim: ts=3 sw=3 et

This file is part of the documentation for kio Library Version 3.4.1.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Sat Jun 11 20:24:03 2005 by doxygen 1.4.1 written by Dimitri van Heesch, © 1997-2003