Skip to content

Commit

Permalink
Add poco conversions
Browse files Browse the repository at this point in the history
  • Loading branch information
abedra committed Aug 29, 2021
1 parent 36fb4ee commit 2b0fe96
Show file tree
Hide file tree
Showing 5 changed files with 212 additions and 18 deletions.
16 changes: 2 additions & 14 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,5 @@ add_library(simple_websocket include/simple_websocket.hpp)
set_target_properties(simple_websocket PROPERTIES LINKER_LANGUAGE CXX)

include(FetchContent)
FetchContent_Declare(
Catch2
GIT_SHALLOW TRUE
GIT_REPOSITORY https://github.com/catchorg/Catch2.git
GIT_TAG v2.13.6)
FetchContent_MakeAvailable(Catch2)
list(APPEND CMAKE_MODULE_PATH ${Catch2_SOURCE_DIR}/contrib)
enable_testing()
include_directories(include)
add_executable(simple_websocket_test test/SimpleWebSocketTests.cpp)
target_link_libraries(simple_websocket_test Catch2::Catch2)
include(CTest)
include(Catch)
catch_discover_tests(simple_websocket_test)
include(cmake/poco.cmake)
include(cmake/testing.cmake)
11 changes: 11 additions & 0 deletions cmake/poco.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
FetchContent_Declare(
poco
GIT_SHALLOW TRUE
GIT_REPOSITORY "https://github.com/pocoproject/poco.git"
GIT_TAG "poco-1.11.0-release"
)
FetchContent_MakeAvailable(poco)
FetchContent_GetProperties(poco)
if (NOT poco_POPULATED)
FetchContent_Populate(poco)
endif()
14 changes: 14 additions & 0 deletions cmake/testing.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
FetchContent_Declare(
Catch2
GIT_SHALLOW TRUE
GIT_REPOSITORY https://github.com/catchorg/Catch2.git
GIT_TAG v2.13.6)
FetchContent_MakeAvailable(Catch2)
list(APPEND CMAKE_MODULE_PATH ${Catch2_SOURCE_DIR}/contrib)
enable_testing()
include_directories(include)
add_executable(simple_websocket_test test/SimpleWebSocketTests.cpp)
target_link_libraries(simple_websocket_test Catch2::Catch2 Poco::Net)
include(CTest)
include(Catch)
catch_discover_tests(simple_websocket_test)
124 changes: 120 additions & 4 deletions include/simple_websocket.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,20 @@
#include <memory>

namespace SimpleWebSocket {
template<class... As> struct match : As... { using As::operator()...; };
template<class... As> match(As...) -> match<As...>;

struct PingFrame final {
explicit PingFrame(std::string value) : value_(std::move(value)) {}

bool operator==(const PingFrame &rhs) const {
return value_ == rhs.value_;
}

bool operator!=(const PingFrame &rhs) const {
return !(rhs == *this);
}

[[nodiscard]]
const std::string &value() const {
return value_;
Expand All @@ -22,6 +33,14 @@ namespace SimpleWebSocket {
struct PongFrame final {
explicit PongFrame(std::string value) : value_(std::move(value)) {}

bool operator==(const PongFrame &rhs) const {
return value_ == rhs.value_;
}

bool operator!=(const PongFrame &rhs) const {
return !(rhs == *this);
}

[[nodiscard]]
const std::string &value() const {
return value_;
Expand All @@ -34,6 +53,14 @@ namespace SimpleWebSocket {
struct TextFrame final {
explicit TextFrame(std::string value) : value_(std::move(value)) {}

bool operator==(const TextFrame &rhs) const {
return value_ == rhs.value_;
}

bool operator!=(const TextFrame &rhs) const {
return !(rhs == *this);
}

[[nodiscard]]
const std::string &value() const {
return value_;
Expand All @@ -46,6 +73,14 @@ namespace SimpleWebSocket {
struct BinaryFrame final {
explicit BinaryFrame(std::vector<char> value) : value_(std::move(value)) {}

bool operator==(const BinaryFrame &rhs) const {
return value_ == rhs.value_;
}

bool operator!=(const BinaryFrame &rhs) const {
return !(rhs == *this);
}

[[nodiscard]]
const std::vector<char> &value() const {
return value_;
Expand All @@ -58,6 +93,14 @@ namespace SimpleWebSocket {
struct CloseFrame final {
explicit CloseFrame(std::string value) : value_(std::move(value)) {}

bool operator==(const CloseFrame &rhs) const {
return value_ == rhs.value_;
}

bool operator!=(const CloseFrame &rhs) const {
return !(rhs == *this);
}

[[nodiscard]]
const std::string &value() const {
return value_;
Expand All @@ -67,7 +110,15 @@ namespace SimpleWebSocket {
std::string value_;
};

struct UndefinedFrame final { };
struct UndefinedFrame final {
bool operator==(const UndefinedFrame &rhs) const {
return true;
}

bool operator!=(const UndefinedFrame &rhs) const {
return false;
}
};

struct FrameHandler {
virtual void handlePing(const PingFrame& pingFrame) = 0;
Expand All @@ -83,6 +134,38 @@ namespace SimpleWebSocket {
: value_(std::move(value))
{ }

bool operator==(const Message &rhs) const {
if (std::holds_alternative<PingFrame>(value_) && std::holds_alternative<PingFrame>(rhs.value())) {
return std::get<PingFrame>(value_) == std::get<PingFrame>(rhs.value());
}

if (std::holds_alternative<PongFrame>(value_) && std::holds_alternative<PongFrame>(rhs.value())) {
return std::get<PongFrame>(value_) == std::get<PongFrame>(rhs.value());
}

if (std::holds_alternative<TextFrame>(value_) && std::holds_alternative<TextFrame>(rhs.value())) {
return std::get<TextFrame>(value_) == std::get<TextFrame>(rhs.value());
}

if (std::holds_alternative<BinaryFrame>(value_) && std::holds_alternative<BinaryFrame>(rhs.value())) {
return std::get<BinaryFrame>(value_) == std::get<BinaryFrame>(rhs.value());
}

if (std::holds_alternative<CloseFrame>(value_) && std::holds_alternative<CloseFrame>(rhs.value())) {
return std::get<CloseFrame>(value_) == std::get<CloseFrame>(rhs.value());
}

if (std::holds_alternative<UndefinedFrame>(value_) && std::holds_alternative<UndefinedFrame>(rhs.value())) {
return std::get<UndefinedFrame>(value_) == std::get<UndefinedFrame>(rhs.value());
}

return false;
}

bool operator!=(const Message &rhs) const {
return !(rhs == *this);
}

[[nodiscard]]
const std::variant<PingFrame, PongFrame, TextFrame, BinaryFrame, CloseFrame, UndefinedFrame> &value() const {
return value_;
Expand All @@ -92,8 +175,6 @@ namespace SimpleWebSocket {
std::variant<PingFrame, PongFrame, TextFrame, BinaryFrame, CloseFrame, UndefinedFrame> value_;
};

template<class... As> struct match : As... { using As::operator()...; };
template<class... As> match(As...) -> match<As...>;
struct MessageHandler final {
explicit MessageHandler(std::unique_ptr<FrameHandler> delegate) : delegate_(std::move(delegate)) {}

Expand All @@ -111,4 +192,39 @@ namespace SimpleWebSocket {
private:
std::unique_ptr<FrameHandler> delegate_;
};
}
}

#if __has_include(<Poco/Net/WebSocket.h>)
#include <Poco/Net/WebSocket.h>
namespace SimpleWebSocket {
namespace Poco {
constexpr int PING_FRAME = static_cast<int>(::Poco::Net::WebSocket::FRAME_FLAG_FIN) |
static_cast<int>(::Poco::Net::WebSocket::FRAME_OP_PING);
constexpr int PONG_FRAME = static_cast<int>(::Poco::Net::WebSocket::FRAME_FLAG_FIN) |
static_cast<int>(::Poco::Net::WebSocket::FRAME_OP_PONG);
constexpr int TEXT_FRAME = static_cast<int>(::Poco::Net::WebSocket::FRAME_FLAG_FIN) |
static_cast<int>(::Poco::Net::WebSocket::FRAME_OP_TEXT);
constexpr int BINARY_FRAME = static_cast<int>(::Poco::Net::WebSocket::FRAME_FLAG_FIN) |
static_cast<int>(::Poco::Net::WebSocket::FRAME_OP_BINARY);
constexpr int CLOSE_FRAME = static_cast<int>(::Poco::Net::WebSocket::FRAME_FLAG_FIN) |
static_cast<int>(::Poco::Net::WebSocket::FRAME_OP_CLOSE);

inline SimpleWebSocket::Message fromPoco(int flags, const char *buf, int size) {
switch(flags) {
case PING_FRAME:
return SimpleWebSocket::Message{SimpleWebSocket::PingFrame{std::string(buf, size)}};
case PONG_FRAME:
return SimpleWebSocket::Message{SimpleWebSocket::PongFrame{std::string(buf, size)}};
case TEXT_FRAME:
return SimpleWebSocket::Message{SimpleWebSocket::TextFrame{std::string(buf, size)}};
case BINARY_FRAME:
return SimpleWebSocket::Message{SimpleWebSocket::BinaryFrame{std::vector<char>(buf, buf + size)}};
case CLOSE_FRAME:
return SimpleWebSocket::Message{SimpleWebSocket::CloseFrame{std::string(buf, size)}};
default:
return SimpleWebSocket::Message{SimpleWebSocket::UndefinedFrame{}};
}
}
}
}
#endif
65 changes: 65 additions & 0 deletions test/SimpleWebSocketTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -121,3 +121,68 @@ TEST_CASE("Mixed Frames")
CHECK(messages.at(2) == "close");
}

TEST_CASE("Poco PING_FRAME")
{
int flags = 137;
char buf[5] = "ping";
int size = 4;

SimpleWebSocket::Message actual = SimpleWebSocket::Poco::fromPoco(flags, buf, size);
SimpleWebSocket::Message expected = SimpleWebSocket::Message{SimpleWebSocket::PingFrame{"ping"}};
CHECK(expected == actual);
}

TEST_CASE("Poco PONG_FRAME")
{
int flags = 138;
char buf[5] = "pong";
int size = 4;

SimpleWebSocket::Message actual = SimpleWebSocket::Poco::fromPoco(flags, buf, size);
SimpleWebSocket::Message expected = SimpleWebSocket::Message{SimpleWebSocket::PongFrame{"pong"}};
CHECK(expected == actual);
}

TEST_CASE("Poco TEXT_FRAME")
{
int flags = 129;
char buf[5] = "text";
int size = 4;

SimpleWebSocket::Message actual = SimpleWebSocket::Poco::fromPoco(flags, buf, size);
SimpleWebSocket::Message expected = SimpleWebSocket::Message{SimpleWebSocket::TextFrame{"text"}};
CHECK(expected == actual);
}

TEST_CASE("Poco BINARY_FRAME")
{
int flags = 130;
char buf[7] = "binary";
int size = 6;

SimpleWebSocket::Message actual = SimpleWebSocket::Poco::fromPoco(flags, buf, size);
SimpleWebSocket::Message expected = SimpleWebSocket::Message{SimpleWebSocket::BinaryFrame{{'b', 'i', 'n', 'a', 'r', 'y'}}};
CHECK(expected == actual);
}

TEST_CASE("Poco CLOSE_FRAME")
{
int flags = 136;
char buf[6] = "close";
int size = 5;

SimpleWebSocket::Message actual = SimpleWebSocket::Poco::fromPoco(flags, buf, size);
SimpleWebSocket::Message expected = SimpleWebSocket::Message{SimpleWebSocket::CloseFrame{"close"}};
CHECK(expected == actual);
}

TEST_CASE("Poco Undefined")
{
int flags = 0;
char buf[1] = "";
int size = 1;

SimpleWebSocket::Message actual = SimpleWebSocket::Poco::fromPoco(flags, buf, size);
SimpleWebSocket::Message expected = SimpleWebSocket::Message{SimpleWebSocket::UndefinedFrame{}};
CHECK(expected == actual);
}

0 comments on commit 2b0fe96

Please sign in to comment.