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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
|
#include <QFile>
#include "torrentparser.h"
TorrentParser::TorrentParser(const QString file, QObject *parent) : QObject(parent), mFile(file), mPos(0) {}
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 QStringList TorrentParser::files(QList<QVariant> data){
QStringList retval;
for(QVariant cur : data){
if(cur.canConvert<QVariantHash>()){
QVariantHash h = cur.toHash();
QHash<QString, QVariant>::const_iterator it = h.constBegin();
while(it != h.constEnd()){
if(it.key() == "info"){
QVariantHash infoD = it.value().toHash();
if(infoD.contains("files")){
QVariantList fileList = infoD.value("files").toList();
for(QVariant fn : fileList){
QVariantHash e = fn.toHash();
QVariantList path = e.value("path").toList();
retval << path.last().toString();
}
}else{
retval << infoD.value("name").toString();
}
break;
}
++it;
}
}
}
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){
++mPos;
return QByteArray();
}
int len = mData.mid(mPos, lenlen).toInt();
if(mPos + len > mData.size()){
++mPos;
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(mPos < mData.size() && 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(mPos < mData.size() && mData.at(mPos) != 'e'){
QString key = parseString();
QVariant value = parseObject();
if(key.isEmpty() || value.isNull()){
return retval;
}
retval.insert(key, value);
}
++mPos;
return retval;
}
|