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/weechatprotocolhandler.cpp \
|
||||
src/protocolhandler.cpp \
|
||||
src/qsslcertificateinfo.cpp
|
||||
src/qsslcertificateinfo.cpp \
|
||||
src/weechat/hdata.cpp \
|
||||
src/weechat/dynamictypeexception.cpp
|
||||
|
||||
OTHER_FILES += qml/harbour-weechatrelay.qml \
|
||||
rpm/harbour-weechatrelay.spec \
|
||||
|
@ -41,7 +43,9 @@ HEADERS += \
|
|||
src/protocolhandler.h \
|
||||
src/weechatprotocolhandler.h \
|
||||
src/connectresolver.h \
|
||||
src/qsslcertificateinfo.h
|
||||
src/qsslcertificateinfo.h \
|
||||
src/weechat/hdata.h \
|
||||
src/weechat/dynamictypeexception.h
|
||||
|
||||
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 "weechatprotocolhandler.h"
|
||||
#include "weechat/dynamictypeexception.h"
|
||||
|
||||
WeeChatProtocolHandler::WeeChatProtocolHandler(QObject* 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
|
||||
|
||||
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)
|
||||
{
|
||||
quint8 c;
|
||||
|
@ -214,17 +259,16 @@ QDateTime WeeChatProtocolHandler::handleTime(QDataStream* data)
|
|||
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
|
||||
// are currently always 'str'
|
||||
QString keyType = handleString(data);
|
||||
QString valueType = handleString(data);
|
||||
// The hashtable first contains the types for the key and value
|
||||
Type keyType = readType(data);
|
||||
Type valueType = readType(data);
|
||||
|
||||
Q_ASSERT_X(keyType == "str" && valueType == "str",
|
||||
"HashTable::readFrom", "HashTable uses type that isn't string.");
|
||||
Q_ASSERT_X(keyType == STRING,
|
||||
"HashTable::readFrom", "HashTable uses non-string keys.");
|
||||
|
||||
// Next is the length of the table as a 4-byte int
|
||||
qint32 length = 0;
|
||||
|
@ -233,7 +277,7 @@ QHash<QString, QString> WeeChatProtocolHandler::handleHashTable(QDataStream* dat
|
|||
for (qint32 i = 0; i < length; ++i)
|
||||
{
|
||||
QString key = handleString(data);
|
||||
QString value = handleString(data);
|
||||
QVariant value = handleDynamicType(valueType, data);
|
||||
|
||||
ret.insert(key, value);
|
||||
}
|
||||
|
@ -241,16 +285,78 @@ QHash<QString, QString> WeeChatProtocolHandler::handleHashTable(QDataStream* dat
|
|||
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
|
||||
QString type = handleString(data);
|
||||
Type type = readType(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
|
||||
#define WEECHATPROTOCOLHANDLER_H
|
||||
|
||||
#include <utility>
|
||||
#include <QObject>
|
||||
#include <QDateTime>
|
||||
#include <QHash>
|
||||
|
@ -16,6 +17,21 @@ class WeeChatProtocolHandler : public ProtocolHandler
|
|||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum Type {
|
||||
CHAR,
|
||||
INTEGER,
|
||||
LONG,
|
||||
STRING,
|
||||
BUFFER,
|
||||
POINTER,
|
||||
TIME,
|
||||
HASHTABLE,
|
||||
HDATA,
|
||||
INFO,
|
||||
INFOLIST,
|
||||
ARRAY
|
||||
};
|
||||
|
||||
explicit WeeChatProtocolHandler(QObject* parent = 0);
|
||||
|
||||
void initialize(QString password);
|
||||
|
@ -38,6 +54,7 @@ protected:
|
|||
void handleUnknown(QDataStream* data);
|
||||
|
||||
// Individual object types
|
||||
QVariant handleDynamicType(Type type, QDataStream* data);
|
||||
char handleChar(QDataStream* data);
|
||||
qint32 handleInt(QDataStream* data);
|
||||
qint64 handleLong(QDataStream* data);
|
||||
|
@ -45,11 +62,13 @@ protected:
|
|||
QByteArray handleBuffer(QDataStream* data);
|
||||
QString handlePointer(QDataStream* data);
|
||||
QDateTime handleTime(QDataStream* data);
|
||||
QHash<QString, QString> handleHashTable(QDataStream* data);
|
||||
// TODO: Hdata, Info, Infolist
|
||||
QList<QString> handleStringArray(QDataStream* data);
|
||||
QList<qint32> handleIntegerArray(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;
|
||||
|
||||
|
|
Loading…
Reference in a new issue