summaryrefslogtreecommitdiffstats
path: root/torrentparser.cpp
diff options
context:
space:
mode:
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;
+}