aboutsummaryrefslogtreecommitdiff
path: root/src/message.cpp
diff options
context:
space:
mode:
authorFelix Morgner <felix.morgner@gmail.com>2018-11-30 15:53:53 +0100
committerFelix Morgner <felix.morgner@gmail.com>2018-11-30 15:53:53 +0100
commit9c2231c8fb45f32c7b1d23e14125bc58ea405e60 (patch)
tree907b72521a0c8bf03c99432817be11ddc12eef3a /src/message.cpp
parent106eb9578179b04dbe9278e3197391db168e6ebb (diff)
downloadwanda-9c2231c8fb45f32c7b1d23e14125bc58ea405e60.tar.xz
wanda-9c2231c8fb45f32c7b1d23e14125bc58ea405e60.zip
core: implement basic message type
Diffstat (limited to 'src/message.cpp')
-rw-r--r--src/message.cpp75
1 files changed, 75 insertions, 0 deletions
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