Initial commit
This commit is contained in:
		
							
								
								
									
										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