Change Hdata from QObject to QVariantHash, combine all parsing to WCPH
This commit is contained in:
parent
4a9eeb850b
commit
56d7c58ac0
5 changed files with 230 additions and 141 deletions
|
@ -17,7 +17,6 @@ SOURCES += src/harbour-weechatrelay.cpp \
|
||||||
src/weechatprotocolhandler.cpp \
|
src/weechatprotocolhandler.cpp \
|
||||||
src/protocolhandler.cpp \
|
src/protocolhandler.cpp \
|
||||||
src/qsslcertificateinfo.cpp \
|
src/qsslcertificateinfo.cpp \
|
||||||
src/weechat/hdata.cpp \
|
|
||||||
src/weechat/dynamictypeexception.cpp
|
src/weechat/dynamictypeexception.cpp
|
||||||
|
|
||||||
OTHER_FILES += qml/harbour-weechatrelay.qml \
|
OTHER_FILES += qml/harbour-weechatrelay.qml \
|
||||||
|
@ -44,7 +43,6 @@ HEADERS += \
|
||||||
src/weechatprotocolhandler.h \
|
src/weechatprotocolhandler.h \
|
||||||
src/connectresolver.h \
|
src/connectresolver.h \
|
||||||
src/qsslcertificateinfo.h \
|
src/qsslcertificateinfo.h \
|
||||||
src/weechat/hdata.h \
|
|
||||||
src/weechat/dynamictypeexception.h
|
src/weechat/dynamictypeexception.h
|
||||||
|
|
||||||
QT += network
|
QT += network
|
||||||
|
|
|
@ -1,6 +0,0 @@
|
||||||
#include "hdata.h"
|
|
||||||
|
|
||||||
Hdata::Hdata(QObject *parent) :
|
|
||||||
QObject(parent)
|
|
||||||
{
|
|
||||||
}
|
|
|
@ -1,18 +0,0 @@
|
||||||
#ifndef HDATA_H
|
|
||||||
#define HDATA_H
|
|
||||||
|
|
||||||
#include <QObject>
|
|
||||||
|
|
||||||
class Hdata : public QObject
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
explicit Hdata(QObject *parent = 0);
|
|
||||||
|
|
||||||
signals:
|
|
||||||
|
|
||||||
public slots:
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // HDATA_H
|
|
|
@ -6,6 +6,9 @@
|
||||||
|
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QDataStream>
|
#include <QDataStream>
|
||||||
|
#include <QQmlEngine>
|
||||||
|
#include <QStringList>
|
||||||
|
#include <QJsonDocument>
|
||||||
|
|
||||||
#include "weechatprotocolhandler.h"
|
#include "weechatprotocolhandler.h"
|
||||||
#include "weechat/dynamictypeexception.h"
|
#include "weechat/dynamictypeexception.h"
|
||||||
|
@ -25,90 +28,7 @@ void WeeChatProtocolHandler::initialize(QString password)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Handle incoming data from the socket and emit the appropriate signals
|
// INDIVIDUAL OBJECT TYPES
|
||||||
void WeeChatProtocolHandler::handleNewData(RelayConnection* connection)
|
|
||||||
{
|
|
||||||
// If we cannot read the amount of bytes we want, skip and retry next time
|
|
||||||
if (connection->bytesAvailable() < bytesNeeded)
|
|
||||||
{
|
|
||||||
qDebug() << connection->bytesAvailable() << " was lower than " << bytesNeeded << "... Skipping.";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
QDataStream* data = read(connection, bytesNeeded);
|
|
||||||
|
|
||||||
if (!readingBody)
|
|
||||||
{
|
|
||||||
// The header contains the length of the message and compression specifier
|
|
||||||
quint32 length;
|
|
||||||
quint8 compression;
|
|
||||||
|
|
||||||
(*data) >> length;
|
|
||||||
(*data) >> compression;
|
|
||||||
|
|
||||||
qDebug() << length << " " << compression;
|
|
||||||
|
|
||||||
// The length includes the header
|
|
||||||
readingBody = true;
|
|
||||||
bytesNeeded = length - HEADER_BYTES;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
handleBody(data);
|
|
||||||
readingBody = false;
|
|
||||||
bytesNeeded = HEADER_BYTES;
|
|
||||||
}
|
|
||||||
|
|
||||||
delete data;
|
|
||||||
data = 0;
|
|
||||||
|
|
||||||
emit debugData("");
|
|
||||||
}
|
|
||||||
|
|
||||||
void WeeChatProtocolHandler::sendDebugData(QString string)
|
|
||||||
{
|
|
||||||
emitData(string);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void WeeChatProtocolHandler::emitData(QString data)
|
|
||||||
{
|
|
||||||
ProtocolHandler::emitData(data + "\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
void WeeChatProtocolHandler::handleBody(QDataStream* data)
|
|
||||||
{
|
|
||||||
// The first element is the id which will affect how we interpret the rest
|
|
||||||
char* idData = 0;
|
|
||||||
(*data) >> idData;
|
|
||||||
|
|
||||||
qDebug() << "Id: " << idData;
|
|
||||||
|
|
||||||
QString id(idData);
|
|
||||||
if (id == "_buffer_line_added")
|
|
||||||
{
|
|
||||||
handleBufferLineAdded(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
delete idData;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// EVENTS
|
|
||||||
|
|
||||||
void WeeChatProtocolHandler::handleBufferLineAdded(QDataStream* data)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void WeeChatProtocolHandler::handleUnknown(QDataStream* data)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// TYPES
|
|
||||||
|
|
||||||
QVariant WeeChatProtocolHandler::handleDynamicType(Type type, QDataStream* data)
|
QVariant WeeChatProtocolHandler::handleDynamicType(Type type, QDataStream* data)
|
||||||
{
|
{
|
||||||
|
@ -247,7 +167,7 @@ QString WeeChatProtocolHandler::handlePointer(QDataStream* data)
|
||||||
ret.append(static_cast<char>(current));
|
ret.append(static_cast<char>(current));
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret.prepend("0x");
|
||||||
}
|
}
|
||||||
|
|
||||||
QDateTime WeeChatProtocolHandler::handleTime(QDataStream* data)
|
QDateTime WeeChatProtocolHandler::handleTime(QDataStream* data)
|
||||||
|
@ -259,9 +179,9 @@ QDateTime WeeChatProtocolHandler::handleTime(QDataStream* data)
|
||||||
return ret.fromMSecsSinceEpoch(timestamp);
|
return ret.fromMSecsSinceEpoch(timestamp);
|
||||||
}
|
}
|
||||||
|
|
||||||
QHash<QString, QVariant> WeeChatProtocolHandler::handleHashTable(QDataStream* data)
|
QVariantHash WeeChatProtocolHandler::handleHashTable(QDataStream* data)
|
||||||
{
|
{
|
||||||
QHash<QString, QVariant> ret;
|
QVariantHash ret;
|
||||||
|
|
||||||
// The hashtable first contains the types for the key and value
|
// The hashtable first contains the types for the key and value
|
||||||
Type keyType = readType(data);
|
Type keyType = readType(data);
|
||||||
|
@ -285,21 +205,84 @@ QHash<QString, QVariant> WeeChatProtocolHandler::handleHashTable(QDataStream* da
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<QString, QString> WeeChatProtocolHandler::handleInfo(QDataStream* data)
|
QVariantHash WeeChatProtocolHandler::handleHdata(QDataStream* data)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* A Hdata consists of:
|
||||||
|
* H-path, a string giving the path to the data
|
||||||
|
* Keys, a dict of keys and their types (in a string, comma separated)
|
||||||
|
* Integer count of object sets
|
||||||
|
* N object sets which themselves consist of:
|
||||||
|
* * P-path, list of pointers to objects (the same amount as the amount
|
||||||
|
* of parts in H-path
|
||||||
|
* * List of objects, with the same keys and types as defined in Keys
|
||||||
|
*/
|
||||||
|
QVariantHash hdata;
|
||||||
|
QVariantList objectSets;
|
||||||
|
QVariantHash keys;
|
||||||
|
|
||||||
|
QString hPath = WeeChatProtocolHandler::handleString(data);
|
||||||
|
|
||||||
|
QString keyString = WeeChatProtocolHandler::handleString(data);
|
||||||
|
QStringList keyList = keyString.split(",");
|
||||||
|
QStringList orderedKeys;
|
||||||
|
|
||||||
|
for (QString keyStr : keyList)
|
||||||
|
{
|
||||||
|
QStringList keySplit = keyStr.split(":");
|
||||||
|
QString keyName = keySplit.at(0);
|
||||||
|
QString keyTypeStr = keySplit.at(1);
|
||||||
|
keys.insert(keyName, keyTypeStr);
|
||||||
|
orderedKeys.append(keyName);
|
||||||
|
}
|
||||||
|
|
||||||
|
qint32 objectSetCount = WeeChatProtocolHandler::handleInt(data);
|
||||||
|
|
||||||
|
for (qint32 i = 0; i < objectSetCount; ++i)
|
||||||
|
{
|
||||||
|
QVariantHash objectSet;
|
||||||
|
|
||||||
|
// The amount of pointers is the amount of parts in H-path,
|
||||||
|
// separated by /
|
||||||
|
QVariantList pointers;
|
||||||
|
int pointerCount = hPath.split("/").size();
|
||||||
|
for (int r = 0; r < pointerCount; ++r)
|
||||||
|
{
|
||||||
|
pointers.append(WeeChatProtocolHandler::handlePointer(data));
|
||||||
|
}
|
||||||
|
|
||||||
|
objectSet.insert(QString("__path"), pointers);
|
||||||
|
|
||||||
|
for (QString keyName : orderedKeys)
|
||||||
|
{
|
||||||
|
Type type = stringToType(keys.value(keyName).toString());
|
||||||
|
objectSet.insert(keyName, WeeChatProtocolHandler::handleDynamicType(type, data));
|
||||||
|
}
|
||||||
|
|
||||||
|
objectSets.append(objectSet);
|
||||||
|
}
|
||||||
|
|
||||||
|
hdata.insert("objectSets", objectSets);
|
||||||
|
hdata.insert("keys", keys);
|
||||||
|
hdata.insert("hpath", hPath);
|
||||||
|
return hdata;
|
||||||
|
}
|
||||||
|
|
||||||
|
QPair<QString, QString> WeeChatProtocolHandler::handleInfo(QDataStream* data)
|
||||||
{
|
{
|
||||||
// Info consists of a string key and a string value
|
// Info consists of a string key and a string value
|
||||||
QString key = handleString(data);
|
QString key = handleString(data);
|
||||||
QString value = handleString(data);
|
QString value = handleString(data);
|
||||||
return std::pair<QString, QString>(key, value);
|
return QPair<QString, QString>(key, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<QString, QHash<QString, QVariant> > WeeChatProtocolHandler::handleInfoList(QDataStream* data)
|
QPair<QString, QVariantHash> WeeChatProtocolHandler::handleInfoList(QDataStream* data)
|
||||||
{
|
{
|
||||||
// Infolist consists of name, count and then name, type and value for each element
|
// Infolist consists of name, count and then name, type and value for each element
|
||||||
QString name = handleString(data);
|
QString name = handleString(data);
|
||||||
qint32 length = handleInt(data);
|
qint32 length = handleInt(data);
|
||||||
|
|
||||||
QHash<QString, QVariant> values;
|
QVariantHash values;
|
||||||
for (qint32 i = 0; i < length; ++i)
|
for (qint32 i = 0; i < length; ++i)
|
||||||
{
|
{
|
||||||
QString key = handleString(data);
|
QString key = handleString(data);
|
||||||
|
@ -308,12 +291,12 @@ std::pair<QString, QHash<QString, QVariant> > WeeChatProtocolHandler::handleInfo
|
||||||
values.insert(key, value);
|
values.insert(key, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
return std::pair<QString, QHash<QString, QVariant> >(name, values);
|
return QPair<QString, QVariantHash>(name, values);
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<QVariant> WeeChatProtocolHandler::handleArray(QDataStream* data)
|
QVariantList WeeChatProtocolHandler::handleArray(QDataStream* data)
|
||||||
{
|
{
|
||||||
QList<QVariant> ret;
|
QVariantList ret;
|
||||||
|
|
||||||
// Array consists of type (string), number of elements (int 4 bytes) and data
|
// Array consists of type (string), number of elements (int 4 bytes) and data
|
||||||
Type type = readType(data);
|
Type type = readType(data);
|
||||||
|
@ -334,7 +317,11 @@ WeeChatProtocolHandler::Type WeeChatProtocolHandler::readType(QDataStream* data)
|
||||||
type.append(handleChar(data));
|
type.append(handleChar(data));
|
||||||
type.append(handleChar(data));
|
type.append(handleChar(data));
|
||||||
type.append(handleChar(data));
|
type.append(handleChar(data));
|
||||||
|
return stringToType(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
WeeChatProtocolHandler::Type WeeChatProtocolHandler::stringToType(QString type)
|
||||||
|
{
|
||||||
if (type == "chr")
|
if (type == "chr")
|
||||||
return CHAR;
|
return CHAR;
|
||||||
else if (type == "int")
|
else if (type == "int")
|
||||||
|
@ -360,3 +347,122 @@ WeeChatProtocolHandler::Type WeeChatProtocolHandler::readType(QDataStream* data)
|
||||||
else //if (type == "arr")
|
else //if (type == "arr")
|
||||||
return ARRAY;
|
return ARRAY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Handle incoming data from the socket and emit the appropriate signals
|
||||||
|
void WeeChatProtocolHandler::handleNewData(RelayConnection* connection)
|
||||||
|
{
|
||||||
|
// If we cannot read the amount of bytes we want, skip and retry next time
|
||||||
|
if (connection->bytesAvailable() < bytesNeeded)
|
||||||
|
{
|
||||||
|
qDebug() << connection->bytesAvailable() << " was lower than " << bytesNeeded << "... Skipping.";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QDataStream* data = read(connection, bytesNeeded);
|
||||||
|
|
||||||
|
if (!readingBody)
|
||||||
|
{
|
||||||
|
// The header contains the length of the message and compression specifier
|
||||||
|
quint32 length;
|
||||||
|
quint8 compression;
|
||||||
|
|
||||||
|
(*data) >> length;
|
||||||
|
(*data) >> compression;
|
||||||
|
|
||||||
|
qDebug() << length << " " << compression;
|
||||||
|
|
||||||
|
// The length includes the header
|
||||||
|
readingBody = true;
|
||||||
|
bytesNeeded = length - HEADER_BYTES;
|
||||||
|
|
||||||
|
// Attempt to read the body right away
|
||||||
|
handleNewData(connection);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
handleBody(data);
|
||||||
|
readingBody = false;
|
||||||
|
bytesNeeded = HEADER_BYTES;
|
||||||
|
}
|
||||||
|
|
||||||
|
delete data;
|
||||||
|
data = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WeeChatProtocolHandler::sendDebugData(QString string)
|
||||||
|
{
|
||||||
|
emitData(string);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void WeeChatProtocolHandler::emitData(QString data)
|
||||||
|
{
|
||||||
|
ProtocolHandler::emitData(data + "\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void WeeChatProtocolHandler::handleBody(QDataStream* data)
|
||||||
|
{
|
||||||
|
// The first element is the id which will affect how we interpret the rest
|
||||||
|
char* dataArr = 0;
|
||||||
|
(*data) >> dataArr;
|
||||||
|
QString id(dataArr);
|
||||||
|
|
||||||
|
qDebug() << "ID: " << id;
|
||||||
|
|
||||||
|
|
||||||
|
// IDs for all event types
|
||||||
|
|
||||||
|
if (id == "_pong")
|
||||||
|
{
|
||||||
|
handlePong(id, data);
|
||||||
|
}
|
||||||
|
else if (id == "_upgrade")
|
||||||
|
{
|
||||||
|
handleUpgrade(id, data);
|
||||||
|
}
|
||||||
|
else if (id == "_upgrade_ended")
|
||||||
|
{
|
||||||
|
handleUpgradeEnded(id, data);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
handleDefaultEvent(id, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
delete[] dataArr;
|
||||||
|
dataArr = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// EVENTS
|
||||||
|
|
||||||
|
void WeeChatProtocolHandler::handleDefaultEvent(QString id, QDataStream* data)
|
||||||
|
{
|
||||||
|
// Type for default events is hda, so skip it
|
||||||
|
readType(data);
|
||||||
|
|
||||||
|
QVariantHash hdata = handleHdata(data);
|
||||||
|
emit event(id, hdata);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WeeChatProtocolHandler::handlePong(QString id, QDataStream* data)
|
||||||
|
{
|
||||||
|
QString response = handleString(data);
|
||||||
|
emit event(id, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WeeChatProtocolHandler::handleUpgrade(QString id, QDataStream* data)
|
||||||
|
{
|
||||||
|
// There is no data to read for this message
|
||||||
|
emit event(id, QVariant());
|
||||||
|
}
|
||||||
|
|
||||||
|
void WeeChatProtocolHandler::handleUpgradeEnded(QString id, QDataStream* data)
|
||||||
|
{
|
||||||
|
// There is no data to read for this message
|
||||||
|
emit event(id, QVariant());
|
||||||
|
}
|
||||||
|
|
|
@ -7,11 +7,14 @@
|
||||||
#ifndef WEECHATPROTOCOLHANDLER_H
|
#ifndef WEECHATPROTOCOLHANDLER_H
|
||||||
#define WEECHATPROTOCOLHANDLER_H
|
#define WEECHATPROTOCOLHANDLER_H
|
||||||
|
|
||||||
|
#include "protocolhandler.h"
|
||||||
|
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QDateTime>
|
#include <QDateTime>
|
||||||
#include <QHash>
|
#include <QHash>
|
||||||
#include "protocolhandler.h"
|
#include <QPair>
|
||||||
|
#include <QVariant>
|
||||||
|
|
||||||
class WeeChatProtocolHandler : public ProtocolHandler
|
class WeeChatProtocolHandler : public ProtocolHandler
|
||||||
{
|
{
|
||||||
|
@ -32,14 +35,35 @@ public:
|
||||||
ARRAY
|
ARRAY
|
||||||
};
|
};
|
||||||
|
|
||||||
explicit WeeChatProtocolHandler(QObject* parent = 0);
|
Q_ENUMS(Type)
|
||||||
|
|
||||||
|
explicit WeeChatProtocolHandler(QObject* parent = 0);
|
||||||
void initialize(QString password);
|
void initialize(QString password);
|
||||||
|
|
||||||
// How many bytes at least each message contains
|
// How many bytes at least each message contains
|
||||||
static const qint64 HEADER_BYTES = 5;
|
static const qint64 HEADER_BYTES = 5;
|
||||||
|
|
||||||
|
|
||||||
|
// Individual object types
|
||||||
|
static QVariant handleDynamicType(Type type, QDataStream* data);
|
||||||
|
static char handleChar(QDataStream* data);
|
||||||
|
static qint32 handleInt(QDataStream* data);
|
||||||
|
static qint64 handleLong(QDataStream* data);
|
||||||
|
static QString handleString(QDataStream* data);
|
||||||
|
static QByteArray handleBuffer(QDataStream* data);
|
||||||
|
static QString handlePointer(QDataStream* data);
|
||||||
|
static QDateTime handleTime(QDataStream* data);
|
||||||
|
static QVariantHash handleHashTable(QDataStream* data);
|
||||||
|
static QVariantHash handleHdata(QDataStream* data);
|
||||||
|
static QPair<QString, QString> handleInfo(QDataStream* data);
|
||||||
|
static QPair<QString, QVariantHash> handleInfoList(QDataStream* data);
|
||||||
|
static QVariantList handleArray(QDataStream* data);
|
||||||
|
|
||||||
|
static Type readType(QDataStream* data);
|
||||||
|
static Type stringToType(QString type);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
void event(QString id, QVariant data);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void handleNewData(RelayConnection* connection);
|
void handleNewData(RelayConnection* connection);
|
||||||
|
@ -50,25 +74,10 @@ protected:
|
||||||
void handleBody(QDataStream* data);
|
void handleBody(QDataStream* data);
|
||||||
|
|
||||||
// WeeChat event types
|
// WeeChat event types
|
||||||
void handleBufferLineAdded(QDataStream* data);
|
void handlePong(QString id, QDataStream* data);
|
||||||
void handleUnknown(QDataStream* data);
|
void handleUpgrade(QString id, QDataStream* data);
|
||||||
|
void handleUpgradeEnded(QString id, QDataStream* data);
|
||||||
// Individual object types
|
void handleDefaultEvent(QString id, QDataStream* data);
|
||||||
QVariant handleDynamicType(Type type, QDataStream* data);
|
|
||||||
char handleChar(QDataStream* data);
|
|
||||||
qint32 handleInt(QDataStream* data);
|
|
||||||
qint64 handleLong(QDataStream* data);
|
|
||||||
QString handleString(QDataStream* data);
|
|
||||||
QByteArray handleBuffer(QDataStream* data);
|
|
||||||
QString handlePointer(QDataStream* data);
|
|
||||||
QDateTime handleTime(QDataStream* data);
|
|
||||||
QHash<QString, QVariant> handleHashTable(QDataStream* data);
|
|
||||||
// TODO: Hdata
|
|
||||||
std::pair<QString, QString> handleInfo(QDataStream* data);
|
|
||||||
std::pair<QString, QHash<QString, QVariant>> handleInfoList(QDataStream* data);
|
|
||||||
QList<QVariant> handleArray(QDataStream* data);
|
|
||||||
|
|
||||||
Type readType(QDataStream* data);
|
|
||||||
|
|
||||||
bool readingBody;
|
bool readingBody;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue