Skip to content

Commit

Permalink
Added stomp frame parsing
Browse files Browse the repository at this point in the history
  • Loading branch information
xxxcucus committed Nov 25, 2023
1 parent 6165de2 commit ef272c9
Show file tree
Hide file tree
Showing 14 changed files with 363 additions and 125 deletions.
2 changes: 2 additions & 0 deletions c_plus_plus/stomp/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,14 @@ set(STOMP_HEADR
stompframe.h
stompclient.h
stompframecreator.h
stompframeparser.h
)

set(STOMP_SRCS
stompframe.cpp
stompclient.cpp
stompframecreator.cpp
stompframeparser.cpp
)


Expand Down
13 changes: 11 additions & 2 deletions c_plus_plus/stomp/stompclient.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
#include "stompclient.h"
#include "stompframeparser.h"
#include "stompframe.h"

#include <memory>

StompClient::StompClient() {
QObject::connect(&m_Socket, &QWebSocket::connected, this, &StompClient::socketConnected);
Expand Down Expand Up @@ -28,8 +32,6 @@ void StompClient::setUrl(const QString& url) {

void StompClient::socketConnected() {
qDebug() << "Connected to socket";
qDebug() << "Socket version " << m_Socket.version();
qDebug() << "Max incoming message size " << QWebSocket::maxIncomingMessageSize();
emit clientConnected();
}

Expand Down Expand Up @@ -65,6 +67,13 @@ void StompClient::binaryMessageReceived(const QByteArray& ba) {

void StompClient::textMessageReceived(const QString& message) {
qDebug() << "Received stomp text message " << message;
StompFrameParser parser;

bool error = true;
std::shared_ptr<StompFrame> stompFrame = parser.parseFromTextMessage(message, error);
if (error && stompFrame->getCommand() == StompFrame::HeaderTypes::MESSAGE) {
emit stompMessageReceived(stompFrame->getTextBody());
}
}

void StompClient::textFrameReceived(const QString &frame, bool isLastFrame) {
Expand Down
1 change: 1 addition & 0 deletions c_plus_plus/stomp/stompclient.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ class StompClient : public QObject {

signals:
void clientConnected();
void stompMessageReceived(const QString& message);

private slots:
void socketConnected();
Expand Down
92 changes: 38 additions & 54 deletions c_plus_plus/stomp/stompframe.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,18 @@ bool StompFrame::setCommand(HeaderTypes command) {
return true;
}

bool StompFrame::setCommand(const QString& command) {
m_Command = convertCommandFromString(command);
m_CommandString = command;
QByteArray convertedArray = convertCommandToQByteArray(m_Command);
m_CommandBA = convertedArray;

if (convertedArray == QByteArray(1, 0))
return false;

return true;
}

QString StompFrame::convertCommandToQString(HeaderTypes command) const {
switch(command) {
case HeaderTypes::CONNECT:
Expand Down Expand Up @@ -99,19 +111,11 @@ StompFrame::HeaderTypes StompFrame::convertCommandFromString(const QString& stri
retVal = HeaderTypes::ERROR;
else
retVal = HeaderTypes::UNKNOWN;

//check that the original command was really what was converted
QByteArray convertedRetVal = convertCommandToQByteArray(retVal);

if (convertedRetVal == m_CommandBA)
return retVal;

return HeaderTypes::UNKNOWN;
return retVal;
}

bool StompFrame::addHeader(const QString& key, const QString& value) {
//escape the strings and create headers as QString

assert(m_HeadersBA.size() == m_ValuesBA.size());
assert(m_HeadersString.size() == m_ValuesString.size());
QByteArray baKey = escapeSpecialSymbols(key.toUtf8());
Expand All @@ -123,6 +127,18 @@ bool StompFrame::addHeader(const QString& key, const QString& value) {
return true;
}

bool StompFrame::addHeader(const QByteArray& key, const QByteArray& value) {
assert(m_HeadersBA.size() == m_ValuesBA.size());
assert(m_HeadersString.size() == m_ValuesString.size());
QByteArray baKey = escapeSpecialSymbols(key);
QByteArray baValue = escapeSpecialSymbols(value);
m_HeadersBA.push_back(baKey);
m_ValuesBA.push_back(baValue);
m_HeadersString.push_back(QString(baKey));
m_ValuesString.push_back(QString(baValue));
return true;
}

QByteArray StompFrame::escapeSpecialSymbols(const QByteArray& ba) {
QByteArray::const_iterator it = ba.begin();
QByteArray retVal;
Expand All @@ -149,50 +165,6 @@ QByteArray StompFrame::escapeSpecialSymbols(const QByteArray& ba) {
return retVal;
}


std::pair<bool, QByteArray> StompFrame::unescapeSpecialSymbols(const QByteArray& ba) {
QByteArray::const_iterator it = ba.begin();
QByteArray retVal;

bool found92 = false;
while (it != ba.end()) {
if (*it == 92) {
if (found92) {
retVal.append(92);
found92 = false;
} else {
found92 = true;
}
} else if (*it == 110) {
if (found92)
retVal.append(10);
else
retVal.append(110);
found92 = false;
} else if (*it == 114) {
if (found92)
retVal.append(13);
else
retVal.append(114);
found92 = false;
} else if (*it == 99) {
if (found92)
retVal.append(58);
else
retVal.append(99);
found92 = false;
} else {
if (found92)
return std::make_pair(false, QByteArray(1, 0));
retVal.append(*it);
}
it++;
}

return std::make_pair(true, retVal);
}


std::tuple<bool, QString, QString> StompFrame::getHeader(int i) const {
if (i < 0 || i >= m_HeadersBA.size() || i >= m_ValuesBA.size())
return std::tuple(false, QString(), QString());
Expand Down Expand Up @@ -244,7 +216,7 @@ QByteArray StompFrame::convertToByteArray() {


bool StompFrame::addTextBody(const QString& body) {
if (body.size() == 0)
if (body.isEmpty())
return true;

if (m_BodyBA.size() > 0)
Expand All @@ -264,3 +236,15 @@ bool StompFrame::addByteArrayBody(const QByteArray& body) {
return true;
}

QStringList StompFrame::getCommandQStringList() {
if(!m_CommandTypeStringList.isEmpty())
return m_CommandTypeStringList;
for (auto headerType : m_HeaderTypesList) {
m_CommandTypeStringList.push_back(convertCommandToQString(headerType));
}
return m_CommandTypeStringList;
}

QString StompFrame::getTextBody() const {
return m_BodyString;
}
23 changes: 9 additions & 14 deletions c_plus_plus/stomp/stompframe.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#define _STOMPFRAME_H

#include <QString>
#include <QStringList>
#include <vector>

class StompFrame {
Expand All @@ -13,23 +14,26 @@ class StompFrame {
StompFrame() {}

bool setCommand(HeaderTypes command);
bool setCommand(const QString& commannd);
bool addHeader(const QString& key, const QString& value);
bool addHeader(const QByteArray& key, const QByteArray& value);
HeaderTypes getCommand() const;
std::tuple<bool, QString, QString> getHeader(int i) const;
bool addTextBody(const QString& body);
bool addByteArrayBody(const QByteArray& body);
QString getTextBody() const;

QByteArray convertToByteArray();
QString convertToQString();

bool isBinaryBody();

QStringList getCommandQStringList();

private:
QString convertCommandToQString(HeaderTypes command) const;
QByteArray convertCommandToQByteArray(HeaderTypes command) const;
HeaderTypes convertCommandFromString(const QString& stringCommand) const;
QByteArray escapeSpecialSymbols(const QByteArray& ba);
std::pair<bool, QByteArray> unescapeSpecialSymbols(const QByteArray& ba);

private:
//values as they are written in the frame
Expand All @@ -42,21 +46,12 @@ class StompFrame {
std::vector<QString> m_ValuesString;
QByteArray m_BodyBA;
QString m_BodyString;

bool m_BinaryBody = false;
QStringList m_CommandTypeStringList;

const std::vector<HeaderTypes> m_HeaderTypesList { HeaderTypes::CONNECT, HeaderTypes::STOMP, HeaderTypes::CONNECTED, HeaderTypes::SEND, HeaderTypes::SUBSCRIBE, HeaderTypes::UNSUBSCRIBE, HeaderTypes::ACK, HeaderTypes::NACK, HeaderTypes::BEGIN, HeaderTypes::COMMIT, HeaderTypes::ABORT, HeaderTypes::DISCONNECT, HeaderTypes::MESSAGE, HeaderTypes::RECEIPT, HeaderTypes::ERROR, HeaderTypes::UNKNOWN };

friend class StompFrameTest;
};












#endif
2 changes: 1 addition & 1 deletion c_plus_plus/stomp/stompframecreator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ std::shared_ptr<StompFrame> StompFrameCreator::createSendTextFrame(const QString
auto stompFrame = std::make_shared<StompFrame>();
stompFrame->setCommand(StompFrame::HeaderTypes::SEND);
stompFrame->addHeader("destination", destination);
stompFrame->addHeader("content-type", "application/json");
stompFrame->addHeader("content-type", QString("application/json"));
stompFrame->addTextBody(message);
return stompFrame;
}
Loading

0 comments on commit ef272c9

Please sign in to comment.