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:
Mikko Ahlroth 2014-06-30 22:33:24 +03:00
parent 4a8945d38d
commit 4a9eeb850b
7 changed files with 192 additions and 20 deletions

View file

@ -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

View file

@ -0,0 +1,6 @@
#include "dynamictypeexception.h"
DynamicTypeException::DynamicTypeException(const std::string &__arg):
std::runtime_error(__arg)
{
}

View 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
View file

@ -0,0 +1,6 @@
#include "hdata.h"
Hdata::Hdata(QObject *parent) :
QObject(parent)
{
}

18
src/weechat/hdata.h Normal file
View 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

View file

@ -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;
}

View file

@ -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;