diff --git a/qml/js/connection.js b/qml/js/connection.js index ba7da7d..e66f6f8 100644 --- a/qml/js/connection.js +++ b/qml/js/connection.js @@ -37,6 +37,7 @@ function init(connectionHandler, pageStack) { function newEvent(id, data) { debugViewPage.display("Event received: " + id); debugViewPage.display(JSON.stringify(data)); + _handleEvent(id, data); } function onDisplayDebugData(str) { @@ -156,7 +157,16 @@ function debug(str) { // Private API +var _pendingEvents = {}; +function _handleEvent(id, data) { + if (id in _pendingEvents) { + _pendingEvents.id(data); + delete _pendingEvents.id; + } +} - +function _addPendingEvent(id, callback) { + _pendingEvents.id = callback; +} diff --git a/src/connectionhandler.cpp b/src/connectionhandler.cpp index 386b5e5..ca96e65 100644 --- a/src/connectionhandler.cpp +++ b/src/connectionhandler.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include "connectionhandler.h" #include "sslrelayconnection.h" @@ -173,6 +174,11 @@ void ConnectionHandler::sendDebugData(QString string) } +void ConnectionHandler::send(QString string) +{ + connection->write(string.toUtf8()); +} + void ConnectionHandler::connectSignals() { QObject::connect(connection, &RelayConnection::connected, this, &ConnectionHandler::relayConnected); diff --git a/src/connectionhandler.h b/src/connectionhandler.h index 22dd3ad..a0e53b4 100644 --- a/src/connectionhandler.h +++ b/src/connectionhandler.h @@ -60,6 +60,7 @@ public slots: void handleDebugData(QString hexstring); void sendDebugData(QString string); + void send(QString string); private: RelayConnection* connection; diff --git a/src/weechatprotocolhandler.cpp b/src/weechatprotocolhandler.cpp index 118747a..7253bf2 100644 --- a/src/weechatprotocolhandler.cpp +++ b/src/weechatprotocolhandler.cpp @@ -23,7 +23,7 @@ WeeChatProtocolHandler::WeeChatProtocolHandler(QObject* parent) : void WeeChatProtocolHandler::initialize(QString password) { emitData("init compression=off,password=" + password); - emitData("test"); + emitData("(starttest) test"); emitData("sync"); } @@ -74,11 +74,11 @@ QVariant WeeChatProtocolHandler::handleDynamicType(Type type, QDataStream* data) } } -char WeeChatProtocolHandler::handleChar(QDataStream* data) +QString WeeChatProtocolHandler::handleChar(QDataStream* data) { quint8 c; *data >> c; - return static_cast(c); + return QString(static_cast(c)); } qint32 WeeChatProtocolHandler::handleInt(QDataStream* data) @@ -101,19 +101,15 @@ qint64 WeeChatProtocolHandler::handleLong(QDataStream* data) { *data >> current; - if (i == 0) + if (i == 0 && current == '-') { - if (current == '-') - { - magnitude = -1; - } + magnitude = -1; } else { ret *= 10; + ret += magnitude * static_cast(current - '0'); } - - ret += magnitude * static_cast(current - '0'); } return ret; @@ -122,13 +118,13 @@ qint64 WeeChatProtocolHandler::handleLong(QDataStream* data) QString WeeChatProtocolHandler::handleString(QDataStream* data) { // Strings are just buffers interpreted as string data - QByteArray bytes = handleBuffer(data); + QByteArray bytes = handleRawBuffer(data); // Lovely WeeChat sends everything our way in UTF-8 <3 return QString::fromUtf8(bytes); } -QByteArray WeeChatProtocolHandler::handleBuffer(QDataStream* data) +QByteArray WeeChatProtocolHandler::handleRawBuffer(QDataStream* data) { // Buffers consist of a length (4 bytes) + data QByteArray ret; @@ -151,6 +147,19 @@ QByteArray WeeChatProtocolHandler::handleBuffer(QDataStream* data) return ret; } +QVariantList WeeChatProtocolHandler::handleBuffer(QDataStream* data) +{ + QByteArray rawData = handleRawBuffer(data); + QVariantList ret; + + for (int i = 0; i < rawData.length(); ++i) { + char b = rawData.at(i); + ret.append(static_cast(b)); + } + + return ret; +} + QString WeeChatProtocolHandler::handlePointer(QDataStream* data) { // Pointers are stored as length (1 byte) + data as hex string @@ -176,7 +185,7 @@ QString WeeChatProtocolHandler::handlePointer(QDataStream* data) qDebug() << "Pointer data: " << ret; - return ret.prepend("0x"); + return ret; } QDateTime WeeChatProtocolHandler::handleTime(QDataStream* data) @@ -362,8 +371,14 @@ WeeChatProtocolHandler::Type WeeChatProtocolHandler::stringToType(QString type) return INFO; else if (type == "inl") return INFOLIST; - else //if (type == "arr") + else if (type == "arr") return ARRAY; + + else + { + qDebug() << "Unknown type: " << type; + throw new DynamicTypeException("Unknown type!"); + } } @@ -430,32 +445,22 @@ void WeeChatProtocolHandler::handleBody(QDataStream* data) qDebug() << "ID: " << id; - - Type type = readType(data); - qDebug() << "Type: " << type; - - - // IDs for all event types - if (id == "_pong") { handlePong(id, data); } else if (id == "_upgrade") { - handleUpgrade(id, data); + handleUpgrade(id); } else if (id == "_upgrade_ended") { - handleUpgradeEnded(id, data); + handleUpgradeEnded(id); } - else if (type == HDATA) { - handleDefaultEvent(id, data); + else + { + handleOtherEvent(id, data); } - else { - qDebug() << "Unknown type!"; - } - delete[] dataArr; dataArr = 0; @@ -464,7 +469,8 @@ void WeeChatProtocolHandler::handleBody(QDataStream* data) // EVENTS -void WeeChatProtocolHandler::handleDefaultEvent(QString id, QDataStream* data) +// Handle event containing a hdata +void WeeChatProtocolHandler::handleHdataEvent(QString id, QDataStream* data) { qDebug() << "Making hdata!"; QVariantMap hdata = handleHdata(data); @@ -478,14 +484,44 @@ void WeeChatProtocolHandler::handlePong(QString id, QDataStream* data) emit newEvent(id, response); } -void WeeChatProtocolHandler::handleUpgrade(QString id, QDataStream* data) +void WeeChatProtocolHandler::handleUpgrade(QString id) { // There is no data to read for this message emit newEvent(id, QVariant()); } -void WeeChatProtocolHandler::handleUpgradeEnded(QString id, QDataStream* data) +void WeeChatProtocolHandler::handleUpgradeEnded(QString id) { // There is no data to read for this message emit newEvent(id, QVariant()); } + +void WeeChatProtocolHandler::handleOtherEvent(QString id, QDataStream* data) +{ + // In this case we don't know the structure of the event, so we will + // read all incoming types into a list + QVariantList ret; + + // If the first element is a hdata, it is the only element + bool first = true; + + while (!data->atEnd()) + { + Type type = readType(data); + + if (first && type == HDATA) + { + handleHdataEvent(id, data); + return; + } + else + { + first = false; + } + + QVariant obj = handleDynamicType(type, data); + ret.append(obj); + } + + emit newEvent(id, ret); +} diff --git a/src/weechatprotocolhandler.h b/src/weechatprotocolhandler.h index 9da977c..3ab79e6 100644 --- a/src/weechatprotocolhandler.h +++ b/src/weechatprotocolhandler.h @@ -46,11 +46,12 @@ public: // Individual object types static QVariant handleDynamicType(Type type, QDataStream* data); - static char handleChar(QDataStream* data); + static QString handleChar(QDataStream* data); static qint32 handleInt(QDataStream* data); static qint64 handleLong(QDataStream* data); static QString handleString(QDataStream* data); - static QByteArray handleBuffer(QDataStream* data); + static QByteArray handleRawBuffer(QDataStream* data); + static QVariantList handleBuffer(QDataStream* data); static QString handlePointer(QDataStream* data); static QDateTime handleTime(QDataStream* data); static QVariantMap handleHashTable(QDataStream* data); @@ -75,9 +76,10 @@ protected: // WeeChat event types void handlePong(QString id, QDataStream* data); - void handleUpgrade(QString id, QDataStream* data); - void handleUpgradeEnded(QString id, QDataStream* data); - void handleDefaultEvent(QString id, QDataStream* data); + void handleUpgrade(QString id); + void handleUpgradeEnded(QString id); + void handleHdataEvent(QString id, QDataStream* data); + void handleOtherEvent(QString id, QDataStream* data); bool readingBody;