summaryrefslogtreecommitdiffstats
path: root/torrentparser.cpp
diff options
context:
space:
mode:
authorArno <arno@disconnect.de>2016-08-19 17:51:10 +0200
committerArno <arno@disconnect.de>2016-08-19 17:51:10 +0200
commit8ab990b7c6fb5348b09f451878a80e2c70695876 (patch)
tree8a90c848308c09e729d9256a6af921abfeb786b3 /torrentparser.cpp
parentcead61f9598302a83fa72e99f82f7bfa2c0b19cb (diff)
downloadShemovCleaner-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.cpp103
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;
+}