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
|
#include <QtCore/QDateTime>
#include <QtCore/QDebug>
#include <QtNetwork/QNetworkRequest>
#include "xmlrpcinterface.h"
XmlRpcInterface::XmlRpcInterface(const QUrl& endpoint, QObject *parent) :
QObject(parent), _endpoint(endpoint),
_manager(new QNetworkAccessManager(this))
{
}
XmlRpcPendingCall *XmlRpcInterface::asyncCallWithArgumentList(const QString &method,
const QList<QVariant> &args)
{
QNetworkRequest request(_endpoint);
QByteArray data = encodeCall(method, args);
request.setHeader(QNetworkRequest::ContentTypeHeader, "text/xml");
request.setRawHeader("User-Agent", "Tapasboard/1.0");
#if XML_RPC_DEBUG
qDebug() << "Request:" << data;
#endif
QNetworkReply *reply = _manager->post(request, data);
return new XmlRpcPendingCall(reply, this);
}
QByteArray XmlRpcInterface::encodeCall(const QString &method, const QList<QVariant> &args)
{
QByteArray buffer;
QXmlStreamWriter writer(&buffer);
writer.writeStartDocument();
writer.writeStartElement("methodCall");
writer.writeTextElement("methodName", method);
if (!args.isEmpty()) {
writer.writeStartElement("params");
foreach (const QVariant& arg, args) {
writer.writeStartElement("param");
encodeValue(&writer, arg);
writer.writeEndElement(); // param
}
writer.writeEndElement(); // params
}
writer.writeEndElement(); // methodCall
writer.writeEndDocument();
return buffer;
}
void XmlRpcInterface::encodeValue(QXmlStreamWriter *w, const QVariant &value)
{
w->writeStartElement("value");
switch (value.type()) {
case QVariant::String:
w->writeTextElement("string", value.toString());
break;
case QVariant::Int:
w->writeTextElement("int", value.toString());
break;
case QVariant::Bool:
w->writeTextElement("boolean", value.toBool() ? "1" : "0");
break;
case QVariant::Double:
w->writeTextElement("double", value.toString());
break;
case QVariant::DateTime:
w->writeTextElement("dateTime.iso8601", value.toDateTime().toString(Qt::ISODate));
break;
case QVariant::ByteArray:
w->writeTextElement("base64", value.toByteArray().toBase64());
break;
case QVariant::List:
w->writeStartElement("array");
w->writeStartElement("data");
{
QVariantList list = value.toList();
foreach (const QVariant& v, list) {
encodeValue(w, v);
}
}
w->writeEndElement(); // data
w->writeEndElement(); // array
break;
case QVariant::Map:
w->writeStartElement("struct");
{
QVariantMap map = value.toMap();
for (QVariantMap::Iterator i = map.begin(); i != map.end(); i++) {
w->writeStartElement("member");
w->writeTextElement("name", i.key());
encodeValue(w, i.value());
w->writeEndElement(); // member
}
}
w->writeEndElement(); // struct
break;
default:
qWarning() << "Unhandled value type:" << value.typeName();
break;
}
w->writeEndElement(); // value
}
|