aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt4
-rw-r--r--src/commander.cpp5
-rw-r--r--src/commander.hpp3
-rw-r--r--src/control_connection.cpp25
-rw-r--r--src/control_connection.hpp5
-rw-r--r--src/message.cpp75
-rw-r--r--src/message.hpp28
7 files changed, 132 insertions, 13 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index fc0efe2..4056b5a 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -24,10 +24,12 @@ add_library("core" OBJECT
"src/control_connection.hpp"
"src/control_interface.cpp"
"src/control_interface.hpp"
+ "src/deferred_failure.hpp"
"src/environment.cpp"
"src/environment.hpp"
- "src/deferred_failure.hpp"
"src/keyed.hpp"
+ "src/message.cpp"
+ "src/message.hpp"
"src/optional.hpp"
"src/type_wrapper.hpp"
"src/xdg.cpp"
diff --git a/src/commander.cpp b/src/commander.cpp
index 79294ac..2dada6a 100644
--- a/src/commander.cpp
+++ b/src/commander.cpp
@@ -1,4 +1,5 @@
#include "commander.hpp"
+#include "message.hpp"
#include <iostream>
@@ -23,13 +24,13 @@ void commander::start()
std::clog << "[commander::start] Control connection established\n";
m_connection = wanda::make_control_connection(std::move(m_socket));
m_connection->start();
- send("C:HELLO:1.0.0\n");
+ send({"C", "HELLO", "1.0.0"});
m_connection->close();
}
});
}
-void commander::send(std::string message)
+void commander::send(message message)
{
if (m_connection)
{
diff --git a/src/commander.hpp b/src/commander.hpp
index 9842c9f..89c476a 100644
--- a/src/commander.hpp
+++ b/src/commander.hpp
@@ -2,6 +2,7 @@
#define WANDA_COMMANDER_HPP
#include "control_connection.hpp"
+#include "message.hpp"
#include <boost/system/error_code.hpp>
@@ -16,7 +17,7 @@ struct commander : wanda::control_connection::listener
commander(boost::asio::io_service &service, std::filesystem::path socket);
void start();
- void send(std::string message);
+ void send(message message);
void on_error(wanda::control_connection::pointer connection, boost::system::error_code error) override;
diff --git a/src/control_connection.cpp b/src/control_connection.cpp
index 094a058..586b5de 100644
--- a/src/control_connection.cpp
+++ b/src/control_connection.cpp
@@ -1,5 +1,8 @@
#include "control_connection.hpp"
+#include <iostream>
+#include <limits>
+
namespace wanda
{
@@ -34,10 +37,10 @@ void control_connection::start()
}
}
-void control_connection::send(std::string message)
+void control_connection::send(message message)
{
- m_output << message;
- boost::asio::async_write(m_socket, m_out, boost::asio::transfer_exactly(message.size()), [that = shared_from_this(), this](auto const &error, auto const length) {
+ m_output << message << '\n';
+ boost::asio::async_write(m_socket, m_out, boost::asio::transfer_exactly(message.size() + 1), [that = shared_from_this(), this](auto const &error, auto const length) {
if (error)
{
// TODO: Handle error
@@ -87,11 +90,19 @@ void control_connection::perform_read()
}
else
{
- std::string message{};
- std::getline(m_input, message);
- for (auto &listener : m_listeners)
+ auto msg = message{};
+ m_input >> msg;
+ m_input.ignore(std::numeric_limits<std::streamsize>::max());
+ if (!m_input)
+ {
+ m_input.clear();
+ }
+ else
{
- listener->on_received(shared_from_this(), message);
+ for (auto &listener : m_listeners)
+ {
+ listener->on_received(shared_from_this(), msg);
+ }
}
perform_read();
}
diff --git a/src/control_connection.hpp b/src/control_connection.hpp
index 50eee82..ea2475c 100644
--- a/src/control_connection.hpp
+++ b/src/control_connection.hpp
@@ -2,6 +2,7 @@
#define WANDA_CONTROL_CONNECTION_HPP
#include "keyed.hpp"
+#include "message.hpp"
#include <boost/asio.hpp>
@@ -22,7 +23,7 @@ struct control_connection : keyed<control_connection>, std::enable_shared_from_t
struct listener
{
virtual void on_close(pointer connection) {}
- virtual void on_received(pointer connection, std::string message) {}
+ virtual void on_received(pointer connection, message message) {}
virtual void on_error(pointer connection, boost::system::error_code) {}
};
@@ -58,7 +59,7 @@ struct control_connection : keyed<control_connection>, std::enable_shared_from_t
*/
void close();
- void send(std::string message);
+ void send(message message);
private:
friend pointer make_control_connection(protocol::socket &&socket);
diff --git a/src/message.cpp b/src/message.cpp
new file mode 100644
index 0000000..ad76897
--- /dev/null
+++ b/src/message.cpp
@@ -0,0 +1,75 @@
+#include "message.hpp"
+
+#include <iterator>
+#include <ios>
+#include <sstream>
+
+namespace wanda
+{
+
+message::operator std::string() const
+{
+ std::ostringstream buffer{};
+ buffer << source
+ << ':'
+ << command;
+ if(argument.has_value())
+ {
+ buffer << ':' << *argument;
+ }
+ return buffer.str();
+}
+
+std::size_t message::size() const
+{
+ return static_cast<std::string>(*this).size();
+}
+
+template <typename InputIt, typename OutputIt, typename UnaryPredicate>
+OutputIt copy_until(InputIt first, InputIt last, OutputIt out, UnaryPredicate predicate)
+{
+ while (first != last && !predicate(*first))
+ {
+ *out++ = *first++;
+ }
+ return out;
+}
+
+std::istream &operator>>(std::istream &in, message &message)
+{
+ auto pos = std::istream_iterator<char>{in};
+ auto end = std::istream_iterator<char>{};
+ auto buffer = std::string{};
+
+ copy_until(pos, end, std::back_inserter(buffer), [](auto const &c) { return c == ':'; });
+ if (in.eof() || buffer.size() != 1)
+ {
+ in.setstate(std::ios_base::failbit);
+ return in;
+ }
+ message.source = buffer;
+
+ buffer.clear();
+ copy_until(++pos, end, std::back_inserter(buffer), [](auto const &c) { return c == ':'; });
+ if (in.eof())
+ {
+ in.setstate(std::ios_base::failbit);
+ }
+ message.command = buffer;
+
+ buffer.clear();
+ copy(++pos, end, std::back_inserter(buffer));
+ if (buffer.size())
+ {
+ message.argument = std::optional{std::move(buffer)};
+ }
+
+ return in;
+}
+
+std::ostream & operator<<(std::ostream & out, message const & message)
+{
+ return out << static_cast<std::string>(message);
+}
+
+} // namespace wanda \ No newline at end of file
diff --git a/src/message.hpp b/src/message.hpp
new file mode 100644
index 0000000..f34d19c
--- /dev/null
+++ b/src/message.hpp
@@ -0,0 +1,28 @@
+#ifndef WANDA_MESSAGE_HPP
+#define WANDA_MESSAGE_HPP
+
+#include <cstddef>
+#include <istream>
+#include <string>
+#include <optional>
+
+namespace wanda
+{
+
+struct message
+{
+ explicit operator std::string() const;
+
+ std::size_t size() const;
+
+ std::string source;
+ std::string command;
+ std::optional<std::string> argument;
+};
+
+std::istream & operator>>(std::istream & in, message & message);
+std::ostream & operator<<(std::ostream & out, message const & message);
+
+} // namespace wanda
+
+#endif \ No newline at end of file