Implement more datatypes and Type enum, create stub file for Hdata
We'll use QVariant for dynamic typing, it offers easy storage of even complex QObjects in a dynamic type.
This commit is contained in:
parent
4a8945d38d
commit
4a9eeb850b
7 changed files with 192 additions and 20 deletions
|
@ -16,7 +16,9 @@ SOURCES += src/harbour-weechatrelay.cpp \
|
||||||
src/connectionhandler.cpp \
|
src/connectionhandler.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
|
||||||
|
|
||||||
OTHER_FILES += qml/harbour-weechatrelay.qml \
|
OTHER_FILES += qml/harbour-weechatrelay.qml \
|
||||||
rpm/harbour-weechatrelay.spec \
|
rpm/harbour-weechatrelay.spec \
|
||||||
|
@ -41,7 +43,9 @@ HEADERS += \
|
||||||
src/protocolhandler.h \
|
src/protocolhandler.h \
|
||||||
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
|
||||||
|
|
||||||
QT += network
|
QT += network
|
||||||
|
|
||||||
|
|
6
src/weechat/dynamictypeexception.cpp
Normal file
6
src/weechat/dynamictypeexception.cpp
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
#include "dynamictypeexception.h"
|
||||||
|
|
||||||
|
DynamicTypeException::DynamicTypeException(const std::string &__arg):
|
||||||
|
std::runtime_error(__arg)
|
||||||
|
{
|
||||||
|
}
|
13
src/weechat/dynamictypeexception.h
Normal file
13
src/weechat/dynamictypeexception.h
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
#ifndef DYNAMICTYPEEXCEPTION_H
|
||||||
|
#define DYNAMICTYPEEXCEPTION_H
|
||||||
|
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
class DynamicTypeException : public std::runtime_error
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit DynamicTypeException(const std::string& __arg);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // DYNAMICTYPEEXCEPTION_H
|
6
src/weechat/hdata.cpp
Normal file
6
src/weechat/hdata.cpp
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
#include "hdata.h"
|
||||||
|
|
||||||
|
Hdata::Hdata(QObject *parent) :
|
||||||
|
QObject(parent)
|
||||||
|
{
|
||||||
|
}
|
18
src/weechat/hdata.h
Normal file
18
src/weechat/hdata.h
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
#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
|
|
@ -8,6 +8,7 @@
|
||||||
#include <QDataStream>
|
#include <QDataStream>
|
||||||
|
|
||||||
#include "weechatprotocolhandler.h"
|
#include "weechatprotocolhandler.h"
|
||||||
|
#include "weechat/dynamictypeexception.h"
|
||||||
|
|
||||||
WeeChatProtocolHandler::WeeChatProtocolHandler(QObject* parent) :
|
WeeChatProtocolHandler::WeeChatProtocolHandler(QObject* parent) :
|
||||||
ProtocolHandler(parent),
|
ProtocolHandler(parent),
|
||||||
|
@ -101,7 +102,7 @@ void WeeChatProtocolHandler::handleBufferLineAdded(QDataStream* data)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void WeeChatProtocolHandler::handleUnknown(QDataStream *data)
|
void WeeChatProtocolHandler::handleUnknown(QDataStream* data)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -109,6 +110,50 @@ void WeeChatProtocolHandler::handleUnknown(QDataStream *data)
|
||||||
|
|
||||||
// TYPES
|
// TYPES
|
||||||
|
|
||||||
|
QVariant WeeChatProtocolHandler::handleDynamicType(Type type, QDataStream* data)
|
||||||
|
{
|
||||||
|
if (type == CHAR)
|
||||||
|
{
|
||||||
|
return QVariant(handleChar(data));
|
||||||
|
}
|
||||||
|
else if (type == INTEGER)
|
||||||
|
{
|
||||||
|
return QVariant(handleInt(data));
|
||||||
|
}
|
||||||
|
else if (type == LONG)
|
||||||
|
{
|
||||||
|
return QVariant(handleLong(data));
|
||||||
|
}
|
||||||
|
else if (type == STRING)
|
||||||
|
{
|
||||||
|
return QVariant(handleString(data));
|
||||||
|
}
|
||||||
|
else if (type == BUFFER)
|
||||||
|
{
|
||||||
|
return QVariant(handleBuffer(data));
|
||||||
|
}
|
||||||
|
else if (type == POINTER)
|
||||||
|
{
|
||||||
|
return QVariant(handlePointer(data));
|
||||||
|
}
|
||||||
|
else if (type == TIME)
|
||||||
|
{
|
||||||
|
return QVariant(handleTime(data));
|
||||||
|
}
|
||||||
|
else if (type == HASHTABLE)
|
||||||
|
{
|
||||||
|
return QVariant(handleHashTable(data));
|
||||||
|
}
|
||||||
|
else if (type == ARRAY)
|
||||||
|
{
|
||||||
|
return QVariant(handleArray(data));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new DynamicTypeException("Cannot read hdata as QVariant.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
char WeeChatProtocolHandler::handleChar(QDataStream* data)
|
char WeeChatProtocolHandler::handleChar(QDataStream* data)
|
||||||
{
|
{
|
||||||
quint8 c;
|
quint8 c;
|
||||||
|
@ -214,17 +259,16 @@ QDateTime WeeChatProtocolHandler::handleTime(QDataStream* data)
|
||||||
return ret.fromMSecsSinceEpoch(timestamp);
|
return ret.fromMSecsSinceEpoch(timestamp);
|
||||||
}
|
}
|
||||||
|
|
||||||
QHash<QString, QString> WeeChatProtocolHandler::handleHashTable(QDataStream* data)
|
QHash<QString, QVariant> WeeChatProtocolHandler::handleHashTable(QDataStream* data)
|
||||||
{
|
{
|
||||||
QHash<QString, QString> ret;
|
QHash<QString, QVariant> ret;
|
||||||
|
|
||||||
// The hashtable first contains the types for the key and value, these
|
// The hashtable first contains the types for the key and value
|
||||||
// are currently always 'str'
|
Type keyType = readType(data);
|
||||||
QString keyType = handleString(data);
|
Type valueType = readType(data);
|
||||||
QString valueType = handleString(data);
|
|
||||||
|
|
||||||
Q_ASSERT_X(keyType == "str" && valueType == "str",
|
Q_ASSERT_X(keyType == STRING,
|
||||||
"HashTable::readFrom", "HashTable uses type that isn't string.");
|
"HashTable::readFrom", "HashTable uses non-string keys.");
|
||||||
|
|
||||||
// Next is the length of the table as a 4-byte int
|
// Next is the length of the table as a 4-byte int
|
||||||
qint32 length = 0;
|
qint32 length = 0;
|
||||||
|
@ -233,7 +277,7 @@ QHash<QString, QString> WeeChatProtocolHandler::handleHashTable(QDataStream* dat
|
||||||
for (qint32 i = 0; i < length; ++i)
|
for (qint32 i = 0; i < length; ++i)
|
||||||
{
|
{
|
||||||
QString key = handleString(data);
|
QString key = handleString(data);
|
||||||
QString value = handleString(data);
|
QVariant value = handleDynamicType(valueType, data);
|
||||||
|
|
||||||
ret.insert(key, value);
|
ret.insert(key, value);
|
||||||
}
|
}
|
||||||
|
@ -241,16 +285,78 @@ QHash<QString, QString> WeeChatProtocolHandler::handleHashTable(QDataStream* dat
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<QString> WeeChatProtocolHandler::handleStringArray(QDataStream* data)
|
std::pair<QString, QString> WeeChatProtocolHandler::handleInfo(QDataStream* data)
|
||||||
{
|
{
|
||||||
QList<QString> ret;
|
// Info consists of a string key and a string value
|
||||||
|
QString key = handleString(data);
|
||||||
|
QString value = handleString(data);
|
||||||
|
return std::pair<QString, QString>(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::pair<QString, QHash<QString, QVariant> > WeeChatProtocolHandler::handleInfoList(QDataStream* data)
|
||||||
|
{
|
||||||
|
// Infolist consists of name, count and then name, type and value for each element
|
||||||
|
QString name = handleString(data);
|
||||||
|
qint32 length = handleInt(data);
|
||||||
|
|
||||||
|
QHash<QString, QVariant> values;
|
||||||
|
for (qint32 i = 0; i < length; ++i)
|
||||||
|
{
|
||||||
|
QString key = handleString(data);
|
||||||
|
Type type = readType(data);
|
||||||
|
QVariant value = handleDynamicType(type, data);
|
||||||
|
values.insert(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::pair<QString, QHash<QString, QVariant> >(name, values);
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<QVariant> WeeChatProtocolHandler::handleArray(QDataStream* data)
|
||||||
|
{
|
||||||
|
QList<QVariant> 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
|
||||||
QString type = handleString(data);
|
Type type = readType(data);
|
||||||
qint32 length = handleInt(data);
|
qint32 length = handleInt(data);
|
||||||
|
|
||||||
|
for (qint32 i = 0; i < length; ++i)
|
||||||
|
{
|
||||||
|
ret.append(handleDynamicType(type, data));
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<qint32> WeeChatProtocolHandler::handleIntegerArray(QDataStream* data)
|
WeeChatProtocolHandler::Type WeeChatProtocolHandler::readType(QDataStream* data)
|
||||||
{
|
{
|
||||||
|
// Type is stored as three chars
|
||||||
|
QString type = "";
|
||||||
|
type.append(handleChar(data));
|
||||||
|
type.append(handleChar(data));
|
||||||
|
type.append(handleChar(data));
|
||||||
|
|
||||||
|
if (type == "chr")
|
||||||
|
return CHAR;
|
||||||
|
else if (type == "int")
|
||||||
|
return INTEGER;
|
||||||
|
else if (type == "lon")
|
||||||
|
return LONG;
|
||||||
|
else if (type == "str")
|
||||||
|
return STRING;
|
||||||
|
else if (type == "buf")
|
||||||
|
return BUFFER;
|
||||||
|
else if (type == "ptr")
|
||||||
|
return POINTER;
|
||||||
|
else if (type == "tim")
|
||||||
|
return TIME;
|
||||||
|
else if (type == "htb")
|
||||||
|
return HASHTABLE;
|
||||||
|
else if (type == "hda")
|
||||||
|
return HDATA;
|
||||||
|
else if (type == "inf")
|
||||||
|
return INFO;
|
||||||
|
else if (type == "inl")
|
||||||
|
return INFOLIST;
|
||||||
|
else //if (type == "arr")
|
||||||
|
return ARRAY;
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#ifndef WEECHATPROTOCOLHANDLER_H
|
#ifndef WEECHATPROTOCOLHANDLER_H
|
||||||
#define WEECHATPROTOCOLHANDLER_H
|
#define WEECHATPROTOCOLHANDLER_H
|
||||||
|
|
||||||
|
#include <utility>
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QDateTime>
|
#include <QDateTime>
|
||||||
#include <QHash>
|
#include <QHash>
|
||||||
|
@ -16,6 +17,21 @@ class WeeChatProtocolHandler : public ProtocolHandler
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
|
enum Type {
|
||||||
|
CHAR,
|
||||||
|
INTEGER,
|
||||||
|
LONG,
|
||||||
|
STRING,
|
||||||
|
BUFFER,
|
||||||
|
POINTER,
|
||||||
|
TIME,
|
||||||
|
HASHTABLE,
|
||||||
|
HDATA,
|
||||||
|
INFO,
|
||||||
|
INFOLIST,
|
||||||
|
ARRAY
|
||||||
|
};
|
||||||
|
|
||||||
explicit WeeChatProtocolHandler(QObject* parent = 0);
|
explicit WeeChatProtocolHandler(QObject* parent = 0);
|
||||||
|
|
||||||
void initialize(QString password);
|
void initialize(QString password);
|
||||||
|
@ -38,6 +54,7 @@ protected:
|
||||||
void handleUnknown(QDataStream* data);
|
void handleUnknown(QDataStream* data);
|
||||||
|
|
||||||
// Individual object types
|
// Individual object types
|
||||||
|
QVariant handleDynamicType(Type type, QDataStream* data);
|
||||||
char handleChar(QDataStream* data);
|
char handleChar(QDataStream* data);
|
||||||
qint32 handleInt(QDataStream* data);
|
qint32 handleInt(QDataStream* data);
|
||||||
qint64 handleLong(QDataStream* data);
|
qint64 handleLong(QDataStream* data);
|
||||||
|
@ -45,11 +62,13 @@ protected:
|
||||||
QByteArray handleBuffer(QDataStream* data);
|
QByteArray handleBuffer(QDataStream* data);
|
||||||
QString handlePointer(QDataStream* data);
|
QString handlePointer(QDataStream* data);
|
||||||
QDateTime handleTime(QDataStream* data);
|
QDateTime handleTime(QDataStream* data);
|
||||||
QHash<QString, QString> handleHashTable(QDataStream* data);
|
QHash<QString, QVariant> handleHashTable(QDataStream* data);
|
||||||
// TODO: Hdata, Info, Infolist
|
// TODO: Hdata
|
||||||
QList<QString> handleStringArray(QDataStream* data);
|
std::pair<QString, QString> handleInfo(QDataStream* data);
|
||||||
QList<qint32> handleIntegerArray(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