#include #include "torrentparser.h" TorrentParser::TorrentParser(const QString file, QObject *parent) : QObject(parent), mFile(file), mPos(0) {} const QList TorrentParser::parse(){ QFile f(mFile); QList retval; if(f.size() > 4*1024*1024){ //this is an arbitray value mLastError = tr("File is too big!"); return retval; } f.open(QIODevice::ReadOnly); mData = f.readAll(); f.close(); while(mPos < mData.size()){ retval << parseObject(); } return retval; } const QStringList TorrentParser::files(QList data){ QStringList retval; foreach(QVariant cur, data){ if(cur.canConvert()){ QVariantHash h = cur.toHash(); QHash::const_iterator it = h.constBegin(); while(it != h.constEnd()){ if(it.key() == "info"){ QVariantHash infoD = it.value().toHash(); if(infoD.contains("files")){ QVariantList fileList = infoD.value("files").toList(); foreach(QVariant fn, fileList){ QVariantHash e = fn.toHash(); QVariantList path = e.value("path").toList(); retval << path.last().toString(); } }else{ retval << infoD.value("name").toString(); } break; } ++it; } } } return retval; } const QVariant TorrentParser::parseObject(){ QChar cur = mData.at(mPos); if(cur == 'i'){ return parseInt(); } if(cur == 'l'){ return parseList(); } if(cur == 'd'){ return parseDict(); } if(cur.isNumber()){ return parseString(); } ++mPos; return QVariant(); } const QByteArray TorrentParser::parseString(){ int lenlen = mData.indexOf(':', mPos) - mPos; if(lenlen <= 0){ ++mPos; return QByteArray(); } int len = mData.mid(mPos, lenlen).toInt(); if(mPos + len > mData.size()){ ++mPos; return QByteArray(); } mPos = mPos + lenlen + 1; QByteArray retval = mData.mid(mPos, len); mPos += len; return retval; } int TorrentParser::parseInt(){ if(mData.at(mPos) != 'i'){ return 0; } ++mPos; int len = mData.indexOf('e', mPos) - mPos; if(len <= 0){ return 0; } int retval = mData.mid(mPos, len).toInt(); mPos = mPos + len + 1; return retval; } const QList TorrentParser::parseList(){ if(mData.at(mPos) != 'l'){ return QList(); } ++mPos; QList retval; while(mPos < mData.size() && mData.at(mPos) != 'e'){ retval.append(parseObject()); } ++mPos; return retval; } const QHash TorrentParser::parseDict(){ QHash retval; if(mData.at(mPos) != 'd'){ return retval; } ++mPos; while(mPos < mData.size() && mData.at(mPos) != 'e'){ QString key = parseString(); QVariant value = parseObject(); if(key.isEmpty() || value.isNull()){ return retval; } retval.insert(key, value); } ++mPos; return retval; }