00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "kfilemetainfo_p.h"
00022 #include <strigi/bufferedstream.h>
00023 #include <strigi/indexwriter.h>
00024 #include <strigi/analysisresult.h>
00025 #include <strigi/fieldtypes.h>
00026 #include <kurl.h>
00027 #include <kdebug.h>
00028 #include <QFileInfo>
00029 #include <QDateTime>
00030 #include <QStringList>
00031
00032 using namespace std;
00033 using namespace Strigi;
00034
00035 class KFileMetaInfoGroupPrivate : public QSharedData {
00036 public:
00037 QString name;
00038 };
00039 KFileMetaInfoGroup::~KFileMetaInfoGroup() {
00040 }
00041 KFileMetaInfoGroup::KFileMetaInfoGroup(KFileMetaInfoGroup const& g) {
00042 p = g.p;
00043 }
00044
00045 QDataStream& operator >>(QDataStream& s, KFileMetaInfo& ) {
00046 return s;
00047 }
00048 QDataStream& operator <<(QDataStream& s, const KFileMetaInfo&) {
00049 return s;
00050 }
00051
00055 class QIODeviceInputStream : public BufferedInputStream {
00056 private:
00057 QIODevice& in;
00058 int32_t fillBuffer(char* start, int32_t space);
00059 public:
00060 QIODeviceInputStream(QIODevice& i);
00061 };
00062
00063 int32_t
00064 QIODeviceInputStream::fillBuffer(char* start, int32_t space) {
00065 if (!in.isOpen() || !in.isReadable()) return -1;
00066
00067 int32_t nwritten = in.read(start, space);
00068
00069 if (nwritten < 0) {
00070 m_error = "Could not read from QIODevice.";
00071 in.close();
00072 return -1;
00073 }
00074 if (nwritten == 0 || in.atEnd()) {
00075 in.close();
00076 }
00077 return nwritten;
00078 }
00079
00080 QIODeviceInputStream::QIODeviceInputStream(QIODevice &i) :in(i)
00081 {
00082
00083
00084 if(i.isSequential()) {
00085 in.close();
00086 }
00087 }
00088
00093 class KMetaInfoWriter : public IndexWriter {
00094 public:
00095
00096 void startAnalysis(const AnalysisResult*) {
00097 }
00098
00099
00100 void addText(const AnalysisResult*, const char* , int32_t ) {
00101 }
00102 void addValue(const AnalysisResult* idx, const RegisteredField* field,
00103 const string& value) {
00104 if (idx->writerData()) {
00105 QString val = QString::fromUtf8(value.c_str(), value.size());
00106 addValue(idx, field, val);
00107 }
00108 }
00109 void addValue(const AnalysisResult* idx, const RegisteredField* field,
00110 const unsigned char* data, uint32_t size) {
00111 if (idx->writerData()) {
00112 QByteArray d((const char*)data, size);
00113 addValue(idx, field, QVariant(d));
00114 }
00115 }
00116 void addValue(const AnalysisResult* idx, const RegisteredField* field,
00117 uint32_t value) {
00118 if (idx->writerData()) {
00119 addValue(idx, field, QVariant((quint32)value));
00120 }
00121 }
00122 void addValue(const AnalysisResult* idx, const RegisteredField* field,
00123 int32_t value) {
00124 if (idx->writerData()) {
00125 addValue(idx, field, QVariant((qint32)value));
00126 }
00127 }
00128 void addValue(const AnalysisResult* idx, const RegisteredField* field,
00129 double value) {
00130 if (idx->writerData()) {
00131 addValue(idx, field, QVariant(value));
00132 }
00133 }
00134 void addValue(const AnalysisResult* idx,
00135 const RegisteredField* field, const QVariant& value) {
00136 QHash<QString, KFileMetaInfoItem>* info
00137 = static_cast<QHash<QString, KFileMetaInfoItem>*>(
00138 idx->writerData());
00139 if (info) {
00140 string name(field->key());
00141 QString key = QString::fromUtf8(name.c_str(), name.size());
00142 QHash<QString, KFileMetaInfoItem>::iterator i = info->find(key);
00143 if (i == info->end()) {
00144
00145 PredicateProperties pp(key);
00146 info->insert(key, KFileMetaInfoItem(pp, value, 0, true));
00147 } else {
00148 i.value().addValue(value);
00149 }
00150 }
00151 }
00152 void addValue(const Strigi::AnalysisResult* ar,
00153 const RegisteredField* field, const std::string& name,
00154 const std::string& value) {
00155 if (ar->writerData()) {
00156 QVariantMap m;
00157 m.insert(name.c_str(), value.c_str());
00158 addValue(ar, field, m);
00159 }
00160 }
00161
00162
00163
00164 void addTriplet(const std::string& ,
00165 const std::string& , const std::string& ) {
00166 }
00167
00168 void finishAnalysis(const AnalysisResult*) {}
00169
00170 void deleteEntries(const vector<string>&) {}
00171
00172 void deleteAllEntries() {}
00173 };
00174 class KFileMetaInfoPrivate : public QSharedData {
00175 public:
00176 QHash<QString, KFileMetaInfoItem> items;
00177 KUrl kurl;
00178
00179
00180 void init(QIODevice& stream, const KUrl& url, time_t mtime);
00181 void initWriters(const KUrl& );
00182 void operator=(const KFileMetaInfoPrivate& k) {
00183 items = k.items;
00184 kurl = k.kurl;
00185 }
00186 };
00187 static const KFileMetaInfoItem nullitem;
00188
00189
00190 void
00191 KFileMetaInfoPrivate::init(QIODevice& stream, const KUrl& url, time_t mtime) {
00192
00193 kurl = url;
00194 StreamAnalyzer& indexer = PredicatePropertyProvider::self()->indexer();
00195 KMetaInfoWriter writer;
00196 QIODeviceInputStream strigiStream(stream);
00197 kDebug() << url;
00198 AnalysisResult idx(url.url().toUtf8().constData(), mtime, writer, indexer);
00199
00200 idx.setWriterData(&items);
00201 indexer.analyze(idx, &strigiStream);
00202
00203
00204 }
00205 void
00206 KFileMetaInfoPrivate::initWriters(const KUrl& file) {
00207 QStringList mimetypes;
00208 QHash<QString, KFileMetaInfoItem>::iterator i;
00209 for (i = items.begin(); i != items.end(); ++i) {
00210 KFileWritePlugin *w =
00211 KFileWriterProvider::self()->loadPlugin(i.key());
00212 if (w && w->canWrite(file, i.key())) {
00213 i.value().p->writer = w;
00214 }
00215 }
00216 }
00217 KFileMetaInfo::KFileMetaInfo(const QString& path, const QString& ,
00218 KFileMetaInfo::WhatFlags )
00219 : p(new KFileMetaInfoPrivate())
00220 {
00221 QFileInfo fileinfo(path);
00222 QFile file(path);
00223
00224
00225 if ((fileinfo.isFile() || fileinfo.isDir() || fileinfo.isSymLink())
00226 && file.open(QIODevice::ReadOnly)) {
00227 KUrl u(path);
00228 p->init(file, u, fileinfo.lastModified().toTime_t());
00229 if (fileinfo.isWritable()) {
00230 p->initWriters(u);
00231 }
00232 }
00233 }
00234 KFileMetaInfo::KFileMetaInfo(const KUrl& url)
00235 : p(new KFileMetaInfoPrivate())
00236 {
00237 QFileInfo fileinfo(url.path());
00238 QFile file(url.path());
00239 if (file.open(QIODevice::ReadOnly)) {
00240 p->init(file, url, fileinfo.lastModified().toTime_t());
00241 if (fileinfo.isWritable()) {
00242 p->initWriters(url);
00243 }
00244 }
00245 }
00246 KFileMetaInfo::KFileMetaInfo() :p(new KFileMetaInfoPrivate()) {
00247 }
00248 KFileMetaInfo::KFileMetaInfo(const KFileMetaInfo& k) :p(k.p) {
00249 }
00250 const KFileMetaInfo&
00251 KFileMetaInfo::operator=(KFileMetaInfo const& kfmi) {
00252 p = kfmi.p;
00253 return kfmi;
00254 }
00255 KFileMetaInfo::~KFileMetaInfo() {
00256 }
00257 bool
00258 KFileMetaInfo::applyChanges() {
00259
00260 QHash<KFileWritePlugin*, QVariantMap> data;
00261 QHash<QString, KFileMetaInfoItem>::const_iterator i;
00262 for (i = p->items.constBegin(); i != p->items.constEnd(); ++i) {
00263 if (i.value().isModified() && i.value().p->writer) {
00264 data[i.value().p->writer][i.key()] = i.value().value();
00265 }
00266 }
00267
00268
00269 bool ok = true;
00270 QHash<KFileWritePlugin*, QVariantMap>::const_iterator j;
00271 QFile file(p->kurl.path());
00272 file.open(QIODevice::ReadOnly);
00273 for (j = data.constBegin(); j != data.constEnd(); ++j) {
00274 ok &= j.key()->write(p->kurl, j.value());
00275 }
00276 return ok;
00277 }
00278 const KUrl&
00279 KFileMetaInfo::url() const {
00280 return p->kurl;
00281 }
00282 const QHash<QString, KFileMetaInfoItem>&
00283 KFileMetaInfo::items() const {
00284 return p->items;
00285 }
00286 const KFileMetaInfoItem&
00287 KFileMetaInfo::item(const QString& key) const {
00288 QHash<QString, KFileMetaInfoItem>::const_iterator i = p->items.constFind(key);
00289 return (i == p->items.constEnd()) ?nullitem :i.value();
00290 }
00291 QStringList
00292 KFileMetaInfo::keys() const {
00293 return p->items.keys();
00294 }
00295 KFileMetaInfoItem&
00296 KFileMetaInfo::item(const QString& key) {
00297 return p->items[key];
00298 }
00299 bool
00300 KFileMetaInfo::isValid() const {
00301 return !p->kurl.isEmpty();
00302 }
00303 QStringList KFileMetaInfo::preferredKeys() const { return QStringList(); }
00304 QStringList KFileMetaInfo::supportedKeys() const { return QStringList(); }
00305
00306 KFileMetaInfoGroupList
00307 KFileMetaInfo::preferredGroups() const {
00308 return KFileMetaInfoGroupList();
00309 }
00310 KFileMetaInfoGroupList
00311 KFileMetaInfo::supportedGroups() const {
00312 return KFileMetaInfoGroupList();
00313 }
00314 KFileMetaInfoItemList
00315 KFileMetaInfoGroup::items() const {
00316 return KFileMetaInfoItemList();
00317 }
00318 const QString&
00319 KFileMetaInfoGroup::name() const {
00320 return p->name;
00321 }
00322