summaryrefslogtreecommitdiffstats
path: root/torrentparser.cpp
blob: fc59233a8c1d1fa3c7ce769c3a4ce8a0ddabe5a8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
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;
}