• Skip to content
  • Skip to link menu
KDE 4.7 API Reference
  • KDE API Reference
  • kdelibs
  • KDE Home
  • Contact Us
 

KIO

kfilemetainfo.cpp
Go to the documentation of this file.
00001 /* This file is part of the KDE libraries
00002 
00003    Copyright (c) 2001,2002 Carsten Pfeiffer <pfeiffer@kde.org>
00004                  2007 Jos van den Oever <jos@vandenoever.info>
00005                  2010 Sebastian Trueg <trueg@kde.org>
00006 
00007    This library is free software; you can redistribute it and/or
00008    modify it under the terms of the GNU Library General Public
00009    License (LGPL) as published by the Free Software Foundation; either
00010    version 2 of the License, or (at your option) any later version.
00011 
00012    This library is distributed in the hope that it will be useful,
00013    but WITHOUT ANY WARRANTY; without even the implied warranty of
00014    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015    Library General Public License for more details.
00016 
00017    You should have received a copy of the GNU Library General Public License
00018    along with this library; see the file COPYING.LIB.  If not, write to
00019    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00020    Boston, MA 02110-1301, USA.
00021 */
00022 
00023 #include "kfilemetainfo.h"
00024 #include "kfilemetainfoitem.h"
00025 #include "kfilemetainfoitem_p.h"
00026 #include "kfilewriteplugin.h"
00027 #include "kfilewriteplugin_p.h"
00028 
00029 #ifndef KIO_NO_STRIGI
00030 #include <strigi/bufferedstream.h>
00031 #include <strigi/analyzerconfiguration.h>
00032 #include <strigi/indexwriter.h>
00033 #include <strigi/analysisresult.h>
00034 #include <strigi/fieldtypes.h>
00035 #endif
00036 
00037 #include <kurl.h>
00038 #include <kdebug.h>
00039 
00040 #include <QFileInfo>
00041 #include <QDateTime>
00042 #include <QStringList>
00043 
00044 class KFileMetaInfoGroupPrivate : public QSharedData {
00045 public:
00046     QString name;
00047 };
00048 
00049 KFileMetaInfoGroup::~KFileMetaInfoGroup()
00050 {
00051 }
00052 
00053 KFileMetaInfoGroup::KFileMetaInfoGroup ( KFileMetaInfoGroup const& g )
00054 {
00055     d = g.d;
00056 }
00057 
00058 QDataStream& operator >> ( QDataStream& s, KFileMetaInfo& )
00059 {
00060     return s;
00061 }
00062 
00063 QDataStream& operator << ( QDataStream& s, const KFileMetaInfo& )
00064 {
00065     return s;
00066 }
00067 #ifndef KIO_NO_STRIGI
00068 
00071 class QIODeviceInputStream : public Strigi::BufferedInputStream {
00072 private:
00073     QIODevice& in;
00074     const qint64 m_maxRead;
00075     qint64 m_read;
00076     int32_t fillBuffer ( char* start, int32_t space );
00077 public:
00078     QIODeviceInputStream ( QIODevice& i, qint64 max );
00079 };
00080 
00081 int32_t
00082 QIODeviceInputStream::fillBuffer ( char* start, int32_t space )
00083 {
00084     if ( !in.isOpen() || !in.isReadable() )
00085         return -1;
00086 
00087     // we force a max stream read length according to the config since some Strigi
00088     // plugins simply ignore the value which will lead to frozen client apps
00089     qint64 max = m_maxRead;
00090     if(max < 0)
00091         max = space;
00092     else
00093         max = qMin(qint64(space), qMax(max-m_read,qint64(0)));
00094 
00095     // read into the buffer
00096     int32_t nwritten = in.read ( start, max );
00097 
00098     // check the file stream status
00099     if ( nwritten < 0 ) {
00100         m_error = "Could not read from QIODevice.";
00101         in.close();
00102         return -1;
00103     }
00104     if ( nwritten == 0 || in.atEnd() ) {
00105         in.close();
00106     }
00107     m_read += nwritten;
00108     return nwritten;
00109 }
00110 
00111 QIODeviceInputStream::QIODeviceInputStream ( QIODevice& i, qint64 max )
00112     : in ( i ),
00113       m_maxRead(max),
00114       m_read(0)
00115 {
00116     // determine if we have a character device, which will likely never eof and thereby
00117     // potentially cause an infinite loop.
00118     if ( i.isSequential() ) {
00119         in.close(); // cause fillBuffer to return -1
00120     }
00121 }
00122 
00127 class KMetaInfoWriter : public Strigi::IndexWriter {
00128 public:
00129     // irrelevant for KFileMetaInfo
00130     void startAnalysis(const Strigi::AnalysisResult*) {
00131     }
00132 
00133     // irrelevant for KFileMetaInfo
00134     // we do not store text as metainfo
00135     void addText(const Strigi::AnalysisResult*, const char* /*s*/, int32_t /*n*/) {
00136     }
00137     void addValue(const Strigi::AnalysisResult* idx, const Strigi::RegisteredField* field,
00138             const std::string& value) {
00139         if (idx->writerData()) {
00140             QString val = QString::fromUtf8(value.c_str(), value.size());
00141             if( !val.startsWith(':') )
00142                 addValue(idx, field, val);
00143         }
00144     }
00145     void addValue(const Strigi::AnalysisResult* idx, const Strigi::RegisteredField* field,
00146         const unsigned char* data, uint32_t size) {
00147         if (idx->writerData()) {
00148             QByteArray d((const char*)data, size);
00149             addValue(idx, field, QVariant(d));
00150         }
00151     }
00152     void addValue(const Strigi::AnalysisResult* idx, const Strigi::RegisteredField* field,
00153             uint32_t value) {
00154         if (idx->writerData()) {
00155             addValue(idx, field, QVariant((quint32)value));
00156         }
00157     }
00158     void addValue(const Strigi::AnalysisResult* idx, const Strigi::RegisteredField* field,
00159             int32_t value) {
00160         if (idx->writerData()) {
00161             addValue(idx, field, QVariant((qint32)value));
00162         }
00163     }
00164     void addValue(const Strigi::AnalysisResult* idx, const Strigi::RegisteredField* field,
00165             double value) {
00166         if (idx->writerData()) {
00167             addValue(idx, field, QVariant(value));
00168         }
00169     }
00170     void addValue(const Strigi::AnalysisResult* idx,
00171                   const Strigi::RegisteredField* field, const QVariant& value) {
00172         QHash<QString, KFileMetaInfoItem>* info
00173             = static_cast<QHash<QString, KFileMetaInfoItem>*>(
00174             idx->writerData());
00175         if (info) {
00176             std::string name(field->key());
00177             QString key = QString::fromUtf8(name.c_str(), name.size());
00178             QHash<QString, KFileMetaInfoItem>::iterator i = info->find(key);
00179             if (i == info->end()) {
00180                 info->insert(key, KFileMetaInfoItem(key, value, 0, true));
00181             } else {
00182                 i.value().addValue(value);
00183             }
00184         }
00185     }
00186     void addValue(const Strigi::AnalysisResult* ar,
00187                   const Strigi::RegisteredField* field, const std::string& name,
00188             const std::string& value) {
00189         if (ar->writerData()) {
00190             QVariantMap m;
00191             m.insert ( name.c_str(), value.c_str() );
00192             addValue ( ar, field, m );
00193         }
00194     }
00195 
00196     /* irrelevant for KFileMetaInfo: These triples does not convey information
00197      * about this file, so we ignore it
00198      */
00199     void addTriplet ( const std::string& /*subject*/,
00200                       const std::string& /*predicate*/, const std::string& /*object*/ ) {
00201     }
00202 
00203     // irrelevant for KFileMetaInfo
00204     void finishAnalysis(const Strigi::AnalysisResult*) {}
00205     // irrelevant for KFileMetaInfo
00206     void deleteEntries(const std::vector<std::string>&) {}
00207     // irrelevant for KFileMetaInfo
00208     void deleteAllEntries() {}
00209 };
00210 
00211 
00212 class KFileMetaInfoPrivate : public QSharedData
00213 {
00214 public:
00215     QHash<QString, KFileMetaInfoItem> items;
00216     KUrl m_url;
00217 
00218     void init ( QIODevice& stream, const KUrl& url, time_t mtime, KFileMetaInfo::WhatFlags w = KFileMetaInfo::Everything );
00219     void initWriters ( const KUrl& /*file*/ );
00220     void operator= ( const KFileMetaInfoPrivate& k ) {
00221         items = k.items;
00222     }
00223 };
00224 static const KFileMetaInfoItem nullitem;
00225 
00226 class KFileMetaInfoAnalysisConfiguration : public Strigi::AnalyzerConfiguration
00227 {
00228 public:
00229     KFileMetaInfoAnalysisConfiguration( KFileMetaInfo::WhatFlags indexDetail )
00230     : m_indexDetail(indexDetail) {
00231     }
00232 
00233     int64_t maximalStreamReadLength ( const Strigi::AnalysisResult& ar ) {
00234         if(ar.depth() > 0)
00235             return 0; // ignore all data that has a depth > 0, i.e. files in archives
00236         else if(m_indexDetail == KFileMetaInfo::Everything)
00237             return -1;
00238         else
00239             return 65536; // do not read the whole file - this is used for on-the-fly analysis
00240     }
00241 
00242 private:
00243     KFileMetaInfo::WhatFlags m_indexDetail;
00244 };
00245 
00246 void KFileMetaInfoPrivate::init ( QIODevice& stream, const KUrl& url, time_t mtime, KFileMetaInfo::WhatFlags w )
00247 {
00248     m_url = url;
00249 
00250     // get data from Strigi
00251     KFileMetaInfoAnalysisConfiguration c( w );
00252     Strigi::StreamAnalyzer indexer ( c );
00253     KMetaInfoWriter writer;
00254     kDebug ( 7033 ) << url;
00255     Strigi::AnalysisResult idx ( url.toLocalFile().toUtf8().constData(), mtime, writer, indexer );
00256     idx.setWriterData ( &items );
00257 
00258     QIODeviceInputStream strigiStream ( stream, c.maximalStreamReadLength(idx) );
00259     indexer.analyze ( idx, &strigiStream );
00260 
00261     // TODO: get data from Nepomuk
00262 }
00263 
00264 void KFileMetaInfoPrivate::initWriters ( const KUrl& file )
00265 {
00266     QStringList mimetypes;
00267     QHash<QString, KFileMetaInfoItem>::iterator i;
00268     for ( i = items.begin(); i != items.end(); ++i ) {
00269         KFileWritePlugin *w =
00270             KFileWriterProvider::self()->loadPlugin ( i.key() );
00271         if ( w && w->canWrite ( file, i.key() ) ) {
00272             i.value().d->writer = w;
00273         }
00274     }
00275 }
00276 
00277 KFileMetaInfo::KFileMetaInfo ( const QString& path, const QString& /*mimetype*/,
00278                                KFileMetaInfo::WhatFlags w )
00279         : d ( new KFileMetaInfoPrivate() )
00280 {
00281     QFileInfo fileinfo ( path );
00282     QFile file ( path );
00283     // only open the file if it is a filetype Qt understands
00284     // if e.g. the path points to a pipe, it is not opened
00285     if ( ( fileinfo.isFile() || fileinfo.isDir() || fileinfo.isSymLink() )
00286             && file.open ( QIODevice::ReadOnly ) ) {
00287         KUrl u ( path );
00288         d->init ( file, u, fileinfo.lastModified().toTime_t(), w );
00289         if ( fileinfo.isWritable() ) {
00290             d->initWriters ( u );
00291         }
00292     }
00293 }
00294 
00295 KFileMetaInfo::KFileMetaInfo ( const KUrl& url )
00296         : d ( new KFileMetaInfoPrivate() )
00297 {
00298     QFileInfo fileinfo ( url.toLocalFile() );
00299     QFile file ( url.toLocalFile() );
00300     if ( file.open ( QIODevice::ReadOnly ) ) {
00301         d->init ( file, url, fileinfo.lastModified().toTime_t() );
00302         if ( fileinfo.isWritable() ) {
00303             d->initWriters ( url );
00304         }
00305     }
00306 }
00307 
00308 KFileMetaInfo::KFileMetaInfo() : d ( new KFileMetaInfoPrivate() )
00309 {
00310 }
00311 
00312 KFileMetaInfo::KFileMetaInfo ( const KFileMetaInfo& k ) : d ( k.d )
00313 {
00314 }
00315 
00316 const KFileMetaInfo& KFileMetaInfo::operator= ( KFileMetaInfo const & kfmi )
00317 {
00318     d = kfmi.d;
00319     return kfmi;
00320 }
00321 
00322 KFileMetaInfo::~KFileMetaInfo()
00323 {
00324 }
00325 
00326 bool KFileMetaInfo::applyChanges()
00327 {
00328     // go through all editable fields and group them by writer
00329     QHash<KFileWritePlugin*, QVariantMap> data;
00330     QHash<QString, KFileMetaInfoItem>::const_iterator i;
00331     for ( i = d->items.constBegin(); i != d->items.constEnd(); ++i ) {
00332         if ( i.value().isModified() && i.value().d->writer ) {
00333             data[i.value().d->writer][i.key() ] = i.value().value();
00334         }
00335     }
00336 
00337     // call the writers on the data they can write
00338     bool ok = true;
00339     QHash<KFileWritePlugin*, QVariantMap>::const_iterator j;
00340     for ( j = data.constBegin(); j != data.constEnd(); ++j ) {
00341         ok &= j.key()->write ( d->m_url, j.value() );
00342     }
00343     return ok;
00344 }
00345 
00346 const KUrl& KFileMetaInfo::url() const
00347 {
00348     return d->m_url;
00349 }
00350 
00351 const QHash<QString, KFileMetaInfoItem>& KFileMetaInfo::items() const
00352 {
00353     return d->items;
00354 }
00355 
00356 const KFileMetaInfoItem& KFileMetaInfo::item ( const QString& key ) const
00357 {
00358     QHash<QString, KFileMetaInfoItem>::const_iterator i = d->items.constFind ( key );
00359     return ( i == d->items.constEnd() ) ? nullitem : i.value();
00360 }
00361 
00362 QStringList KFileMetaInfo::keys() const
00363 {
00364     return d->items.keys();
00365 }
00366 
00367 KFileMetaInfoItem& KFileMetaInfo::item ( const QString& key )
00368 {
00369     return d->items[key];
00370 }
00371 
00372 bool KFileMetaInfo::isValid() const
00373 {
00374     return !d->m_url.isEmpty();
00375 }
00376 
00377 QStringList KFileMetaInfo::preferredKeys() const
00378 {
00379     return QStringList();
00380 }
00381 
00382 QStringList KFileMetaInfo::supportedKeys() const
00383 {
00384     return QStringList();
00385 }
00386 
00387 #ifndef KDE_NO_DEPRECATED
00388 KFileMetaInfoGroupList KFileMetaInfo::preferredGroups() const
00389 {
00390     return KFileMetaInfoGroupList();
00391 }
00392 #endif
00393 
00394 #ifndef KDE_NO_DEPRECATED
00395 KFileMetaInfoGroupList KFileMetaInfo::supportedGroups() const
00396 {
00397     return KFileMetaInfoGroupList();
00398 }
00399 #endif
00400 #else //KIO_NO_STRIGI
00401 
00402 class KFileMetaInfoPrivate : public QSharedData
00403 {
00404 public:
00405 };
00406 
00407 KFileMetaInfo::KFileMetaInfo ( const QString& path, const QString& /*mimetype*/,
00408                                KFileMetaInfo::WhatFlags w )
00409 {
00410 }
00411 
00412 KFileMetaInfo::KFileMetaInfo ( const KUrl& url )
00413 {
00414 }
00415 
00416 KFileMetaInfo::KFileMetaInfo()
00417 {
00418 }
00419 
00420 KFileMetaInfo::KFileMetaInfo ( const KFileMetaInfo& k )
00421 {
00422 }
00423 
00424 const KFileMetaInfo& KFileMetaInfo::operator= ( KFileMetaInfo const & kfmi )
00425 {
00426     return kfmi;
00427 }
00428 
00429 KFileMetaInfo::~KFileMetaInfo()
00430 {
00431 }
00432 
00433 bool KFileMetaInfo::applyChanges()
00434 {
00435     return false;
00436 }
00437 
00438 const KUrl& KFileMetaInfo::url() const
00439 {
00440     static const KUrl item;
00441     return item;
00442 }
00443 
00444 const QHash<QString, KFileMetaInfoItem>& KFileMetaInfo::items() const
00445 {
00446     static const QHash<QString, KFileMetaInfoItem> items;
00447     return items;
00448 }
00449 
00450 const KFileMetaInfoItem& KFileMetaInfo::item ( const QString& key ) const
00451 {
00452     static const KFileMetaInfoItem item;
00453     return item;
00454 }
00455 
00456 QStringList KFileMetaInfo::keys() const
00457 {
00458     return QStringList();
00459 }
00460 
00461 KFileMetaInfoItem& KFileMetaInfo::item ( const QString& key )
00462 {
00463     static KFileMetaInfoItem item;
00464     return item;
00465 }
00466 
00467 bool KFileMetaInfo::isValid() const
00468 {
00469     return false;
00470 }
00471 
00472 QStringList KFileMetaInfo::preferredKeys() const
00473 {
00474     return QStringList();
00475 }
00476 
00477 QStringList KFileMetaInfo::supportedKeys() const
00478 {
00479     return QStringList();
00480 }
00481 #endif
00482 
00483 KFileMetaInfoItemList KFileMetaInfoGroup::items() const
00484 {
00485     return KFileMetaInfoItemList();
00486 }
00487 
00488 const QString& KFileMetaInfoGroup::name() const
00489 {
00490     return d->name;
00491 }

KIO

Skip menu "KIO"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Related Pages

kdelibs

Skip menu "kdelibs"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDEWebKit
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs by doxygen 1.7.5
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal