diff options
author | Arno <arno@disconnect.de> | 2016-08-19 17:51:10 +0200 |
---|---|---|
committer | Arno <arno@disconnect.de> | 2016-08-19 17:51:10 +0200 |
commit | 8ab990b7c6fb5348b09f451878a80e2c70695876 (patch) | |
tree | 8a90c848308c09e729d9256a6af921abfeb786b3 /torrentparser.cpp | |
parent | cead61f9598302a83fa72e99f82f7bfa2c0b19cb (diff) | |
download | ShemovCleaner-8ab990b7c6fb5348b09f451878a80e2c70695876.tar.gz ShemovCleaner-8ab990b7c6fb5348b09f451878a80e2c70695876.tar.bz2 ShemovCleaner-8ab990b7c6fb5348b09f451878a80e2c70695876.zip |
Added torrent support
The BEncode parser is loosely based on this:
https://github.com/jif/Bencode/blob/master/bencode.cpp
Not perfect, but enough to display all the essential data in the shiny
new TorrentDisplay dialog.
Diffstat (limited to 'torrentparser.cpp')
-rw-r--r-- | torrentparser.cpp | 103 |
1 files changed, 103 insertions, 0 deletions
diff --git a/torrentparser.cpp b/torrentparser.cpp new file mode 100644 index 0000000..fc59233 --- /dev/null +++ b/torrentparser.cpp @@ -0,0 +1,103 @@ +#include <QFile> + +#include "torrentparser.h" + +TorrentParser::TorrentParser(const QString file, QObject *parent) : QObject(parent), mFile(file), mPos(0), mOk(true) {} + +const QList<QVariant> TorrentParser::parse(){ + QFile f(mFile); + QList<QVariant> 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 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){ + mOk = false; + return QByteArray(); + } + int len = mData.mid(mPos, lenlen).toInt(); + if(mPos + len > mData.size()){ + mOk = false; + 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<QVariant> TorrentParser::parseList(){ + if(mData.at(mPos) != 'l'){ + return QList<QVariant>(); + } + ++mPos; + QList<QVariant> retval; + while(mData.at(mPos) != 'e'){ + retval.append(parseObject()); + } + ++mPos; + return retval; +} + + + +const QHash<QString,QVariant> TorrentParser::parseDict(){ + QHash<QString,QVariant> retval; + if(mData.at(mPos) != 'd'){ + return retval; + } + ++mPos; + while(mData.at(mPos) != 'e'){ + QString key = parseString(); + QVariant value = parseObject(); + if(key.isEmpty() || value.isNull()){ + return retval; + } + retval.insert(key, value); + } + ++mPos; + return retval; +} |