From 8ab990b7c6fb5348b09f451878a80e2c70695876 Mon Sep 17 00:00:00 2001 From: Arno Date: Fri, 19 Aug 2016 17:51:10 +0200 Subject: 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. --- torrentparser.cpp | 103 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 103 insertions(+) create mode 100644 torrentparser.cpp (limited to 'torrentparser.cpp') 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 + +#include "torrentparser.h" + +TorrentParser::TorrentParser(const QString file, QObject *parent) : QObject(parent), mFile(file), mPos(0), mOk(true) {} + +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 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 TorrentParser::parseList(){ + if(mData.at(mPos) != 'l'){ + return QList(); + } + ++mPos; + QList retval; + while(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(mData.at(mPos) != 'e'){ + QString key = parseString(); + QVariant value = parseObject(); + if(key.isEmpty() || value.isNull()){ + return retval; + } + retval.insert(key, value); + } + ++mPos; + return retval; +} -- cgit v1.2.3-70-g09d2