Initial commit
This commit is contained in:
commit
b3cc535790
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
*.pro.user
|
8
STOMPClient.pro
Normal file
8
STOMPClient.pro
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
QT += network gui widgets
|
||||||
|
CONFIG += c++14 console
|
||||||
|
CONFIG -= app_bundle
|
||||||
|
HEADERS += \
|
||||||
|
stompframe.h
|
||||||
|
SOURCES += \
|
||||||
|
main.cpp \
|
||||||
|
stompframe.cpp
|
7
main.cpp
Normal file
7
main.cpp
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
#include <QApplication>
|
||||||
|
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
QApplication application(argc, argv);
|
||||||
|
|
||||||
|
return application.exec();
|
||||||
|
}
|
151
stompframe.cpp
Normal file
151
stompframe.cpp
Normal file
@ -0,0 +1,151 @@
|
|||||||
|
#include "stompframe.h"
|
||||||
|
|
||||||
|
STOMPFrame::STOMPFrame(Command command, std::initializer_list<QPair<QString, QString>> headers, const QByteArray& body):
|
||||||
|
command_(command), body_(body) {
|
||||||
|
for (const auto& header: headers) {
|
||||||
|
headers_[header.first] = header.second;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
qint64 STOMPFrame::send(QIODevice& device) {
|
||||||
|
QByteArray encoded;
|
||||||
|
QTextStream out {&encoded};
|
||||||
|
out << command_ << "\n";
|
||||||
|
for (const auto& key: headers_.keys()) {
|
||||||
|
out << key << ":" << headers_[key] << "\n";
|
||||||
|
}
|
||||||
|
if (!headers_.contains("content-length")) {
|
||||||
|
out << "content-length" << ":" << body_.size() << "\n";
|
||||||
|
}
|
||||||
|
out << "\n" << body_ << '\0';
|
||||||
|
out.flush();
|
||||||
|
return device.write(encoded);
|
||||||
|
}
|
||||||
|
|
||||||
|
STOMPFrame STOMPFrame::receive(QIODevice& device) {
|
||||||
|
STOMPFrame frame;
|
||||||
|
QTextStream in(&device);
|
||||||
|
|
||||||
|
QString commandStr;
|
||||||
|
if (!in.readLineInto(&commandStr)) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
if (commandStr == "STOMP") {
|
||||||
|
frame.command_ = STOMPFrame::STOMP;
|
||||||
|
} else if (commandStr == "SEND") {
|
||||||
|
frame.command_ = STOMPFrame::SEND;
|
||||||
|
} else if (commandStr == "SUBSCRIBE") {
|
||||||
|
frame.command_ = STOMPFrame::SUBSCRIBE;
|
||||||
|
} else if (commandStr == "UNSUBSCRIBE") {
|
||||||
|
frame.command_ = STOMPFrame::UNSUBSCRIBE;
|
||||||
|
} else if (commandStr == "BEGIN") {
|
||||||
|
frame.command_ = STOMPFrame::BEGIN;
|
||||||
|
} else if (commandStr == "COMMIT") {
|
||||||
|
frame.command_ = STOMPFrame::COMMIT;
|
||||||
|
} else if (commandStr == "ABORT") {
|
||||||
|
frame.command_ = STOMPFrame::ABORT;
|
||||||
|
} else if (commandStr == "ACK") {
|
||||||
|
frame.command_ = STOMPFrame::ACK;
|
||||||
|
} else if (commandStr == "NACK") {
|
||||||
|
frame.command_ = STOMPFrame::NACK;
|
||||||
|
} else if (commandStr == "DISCONNECT") {
|
||||||
|
frame.command_ = STOMPFrame::DISCONNECT;
|
||||||
|
} else if (commandStr == "CONNECTED") {
|
||||||
|
frame.command_ = STOMPFrame::CONNECTED;
|
||||||
|
} else if (commandStr == "MESSAGE") {
|
||||||
|
frame.command_ = STOMPFrame::MESSAGE;
|
||||||
|
} else if (commandStr == "RECEIPT") {
|
||||||
|
frame.command_ = STOMPFrame::RECEIPT;
|
||||||
|
} else if (commandStr == "ERROR") {
|
||||||
|
frame.command_ = STOMPFrame::ERROR;
|
||||||
|
} else {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
QString headerLine;
|
||||||
|
while (in.readLineInto(&headerLine) && headerLine != "") {
|
||||||
|
auto components = headerLine.split(':');
|
||||||
|
if (components.count() != 2) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
frame.headers_.insert(components[0].trimmed(), components[1].trimmed());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (frame.headers_.contains("content-length")) {
|
||||||
|
bool conversionOk;
|
||||||
|
qint64 length = frame.headers_["content-length"].toLongLong(&conversionOk);
|
||||||
|
if (!conversionOk) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
while (frame.body_.length() < length) {
|
||||||
|
frame.body_ += in.read(length - frame.body_.length()).toUtf8();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
in >> frame.body_;
|
||||||
|
}
|
||||||
|
|
||||||
|
return frame;
|
||||||
|
}
|
||||||
|
|
||||||
|
QTextStream& operator <<(QTextStream& out, STOMPFrame::Command command) {
|
||||||
|
switch (command) {
|
||||||
|
case STOMPFrame::INVALID:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case STOMPFrame::STOMP:
|
||||||
|
out << "STOMP";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case STOMPFrame::SEND:
|
||||||
|
out << "SEND";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case STOMPFrame::SUBSCRIBE:
|
||||||
|
out << "SUBSCRIBE";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case STOMPFrame::UNSUBSCRIBE:
|
||||||
|
out << "UNSUBSCRIBE";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case STOMPFrame::BEGIN:
|
||||||
|
out << "BEGIN";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case STOMPFrame::COMMIT:
|
||||||
|
out << "COMMIT";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case STOMPFrame::ABORT:
|
||||||
|
out << "ABORT";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case STOMPFrame::ACK:
|
||||||
|
out << "ACK";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case STOMPFrame::NACK:
|
||||||
|
out << "NACK";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case STOMPFrame::DISCONNECT:
|
||||||
|
out << "DISCONNECT";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case STOMPFrame::CONNECTED:
|
||||||
|
out << "CONNECTED";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case STOMPFrame::MESSAGE:
|
||||||
|
out << "MESSAGE";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case STOMPFrame::RECEIPT:
|
||||||
|
out << "RECEIPT";
|
||||||
|
break;
|
||||||
|
case STOMPFrame::ERROR:
|
||||||
|
out << "ERROR";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
62
stompframe.h
Normal file
62
stompframe.h
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <QString>
|
||||||
|
#include <QPair>
|
||||||
|
#include <QByteArray>
|
||||||
|
#include <QMap>
|
||||||
|
#include <QIODevice>
|
||||||
|
#include <QTextStream>
|
||||||
|
|
||||||
|
class STOMPFrame {
|
||||||
|
public:
|
||||||
|
enum Command {
|
||||||
|
INVALID,
|
||||||
|
|
||||||
|
// Client messages
|
||||||
|
STOMP, SEND, SUBSCRIBE, UNSUBSCRIBE, BEGIN, COMMIT, ABORT, ACK, NACK, DISCONNECT,
|
||||||
|
|
||||||
|
// Server messages
|
||||||
|
CONNECTED, MESSAGE, RECEIPT, ERROR
|
||||||
|
};
|
||||||
|
|
||||||
|
explicit STOMPFrame(Command command, std::initializer_list<QPair<QString,QString>> headers = {}, const QByteArray& body = {});
|
||||||
|
|
||||||
|
bool isNull() const {
|
||||||
|
return command_ == INVALID;
|
||||||
|
}
|
||||||
|
|
||||||
|
Command command() const {
|
||||||
|
return command_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setCommand(Command command) {
|
||||||
|
command_ = command;
|
||||||
|
}
|
||||||
|
|
||||||
|
const QMap<QString, QString>& headers() const {
|
||||||
|
return headers_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setHeaders(const QMap<QString, QString>& headers) {
|
||||||
|
headers_ = headers;
|
||||||
|
}
|
||||||
|
|
||||||
|
const QByteArray& body() const {
|
||||||
|
return body_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setBody(const QByteArray& body) {
|
||||||
|
body_ = body;
|
||||||
|
}
|
||||||
|
|
||||||
|
qint64 send(QIODevice& device);
|
||||||
|
static STOMPFrame receive(QIODevice& device);
|
||||||
|
|
||||||
|
private:
|
||||||
|
STOMPFrame() = default;
|
||||||
|
|
||||||
|
Command command_ = INVALID;
|
||||||
|
QMap<QString,QString> headers_;
|
||||||
|
QByteArray body_;
|
||||||
|
};
|
||||||
|
|
||||||
|
QTextStream& operator <<(QTextStream& out, STOMPFrame::Command command);
|
Reference in New Issue
Block a user