From e7936bdaef38e8df1ab0bb674a04e84c2eacba74 Mon Sep 17 00:00:00 2001 From: Benny Baumann <BenBE@geshi.org> Date: Sun, 19 Feb 2023 14:55:23 +0100 Subject: [PATCH] fmt: Code formatting --- src/lib/nccpp/Ncurses.cpp | 10 +- src/lib/nccpp/Ncurses.hpp | 3 +- src/lib/nccpp/Subwindow.hpp | 9 +- src/lib/nccpp/Window.cpp | 56 ++-- src/lib/nccpp/constants.hpp | 12 +- src/mumta/evloop.cpp | 1 + src/net/address.hpp | 16 +- src/net/async_fd.hpp | 10 +- src/net/async_server.cpp | 55 ++-- src/net/connection_client.cpp | 4 +- src/net/connection_client.hpp | 32 ++- src/net/connection_line_buffer.cpp | 132 +++++---- src/net/connection_line_buffer.hpp | 21 +- src/net/ioqueue.cpp | 21 +- src/net/ioqueue.hpp | 1 + src/net/netio_exception.cpp | 12 +- src/net/netio_exception.hpp | 9 +- src/net/socketaddress.hpp | 3 +- src/net/tcp_client.cpp | 354 +++++++++++++----------- src/net/tcp_client.hpp | 41 +-- src/net/tcp_server_socket.cpp | 135 +++++---- src/net/tcp_server_socket.hpp | 22 +- src/test/loopback_connection_client.cpp | 57 ++-- src/test/loopback_connection_client.hpp | 2 + src/ui/event.cpp | 8 +- src/ui/event.hpp | 6 + src/ui/progress_indicator.hpp | 5 + src/ui/view.cpp | 7 +- src/ui/view.hpp | 5 + 29 files changed, 582 insertions(+), 467 deletions(-) diff --git a/src/lib/nccpp/Ncurses.cpp b/src/lib/nccpp/Ncurses.cpp index 59eab32..c5a94d8 100644 --- a/src/lib/nccpp/Ncurses.cpp +++ b/src/lib/nccpp/Ncurses.cpp @@ -270,11 +270,11 @@ inline short Ncurses::color_to_pair_number(Color const &color) { assert(!is_exit_ && "Ncurses mode is off"); auto it = std::find_if( - std::begin(registered_colors_), - std::end(registered_colors_), - [color](Color const & elem) { - return color == elem; - }); + std::begin(registered_colors_), + std::end(registered_colors_), + [color](Color const & elem) { + return color == elem; + }); if (it != std::end(registered_colors_)) { return static_cast<short>(it - std::begin(registered_colors_) + 1); diff --git a/src/lib/nccpp/Ncurses.hpp b/src/lib/nccpp/Ncurses.hpp index 04be1ae..07f74c5 100644 --- a/src/lib/nccpp/Ncurses.hpp +++ b/src/lib/nccpp/Ncurses.hpp @@ -110,8 +110,7 @@ private: * \exception errors::NcursesInit Thrown when ncurses can't be initialized. * \return A reference to the singleton. */ -inline Ncurses &ncurses() -{ +inline Ncurses &ncurses() { static Ncurses nc{}; return nc; } diff --git a/src/lib/nccpp/Subwindow.hpp b/src/lib/nccpp/Subwindow.hpp index 0d0a59a..14f4fd4 100644 --- a/src/lib/nccpp/Subwindow.hpp +++ b/src/lib/nccpp/Subwindow.hpp @@ -7,8 +7,13 @@ namespace nccpp { class Subwindow : public Window { public: - Subwindow(Window &parent, WINDOW* subwin, Window::Key /*dummy*/) - : Window{subwin}, parent_{parent} + Subwindow( + Window &parent, + WINDOW* subwin, + Window::Key /*dummy*/ + ) : + Window{subwin}, + parent_{parent} {} Subwindow(const Subwindow &) = delete; diff --git a/src/lib/nccpp/Window.cpp b/src/lib/nccpp/Window.cpp index 6a5070f..4129c04 100644 --- a/src/lib/nccpp/Window.cpp +++ b/src/lib/nccpp/Window.cpp @@ -11,49 +11,44 @@ namespace nccpp { inline Window::Window(WINDOW* win) : win_{win}, #ifndef NDEBUG - win_save_ {nullptr}, + win_save_{nullptr}, #endif - subwindows_ {} + subwindows_{} { #ifndef NDEBUG - if (win_ != stdscr) { ncurses().register_window_(*this, Key{}); } - #endif } inline Window::Window(int nlines, int ncols, int begin_y, int begin_x) : win_{ncurses().newwin_(nlines, ncols, begin_y, begin_x, Key{})}, #ifndef NDEBUG - win_save_ {nullptr}, + win_save_{nullptr}, #endif - subwindows_ {} + subwindows_{} { if (!win_) { throw errors::WindowInit{}; } #ifndef NDEBUG - try { ncurses().register_window_(*this, Key{}); - } - catch (...) { + } catch (...) { delwin(win_); throw; } - #endif } inline Window::Window(Window const &cp) : win_{nullptr}, #ifndef NDEBUG - win_save_ {nullptr}, + win_save_{nullptr}, #endif - subwindows_ {} + subwindows_{} { assert(!cp.win_save_ && "Can't duplicate windows while ncurses mode is off"); subwindows_.reserve(cp.subwindows_.size()); @@ -63,15 +58,12 @@ inline Window::Window(Window const &cp) : } #ifndef NDEBUG - try { ncurses().register_window_(*this, Key{}); - } - catch (...) { + } catch (...) { delwin(win_); throw; } - #endif } @@ -89,13 +81,14 @@ inline Window::Window(Window &&mv) noexcept #endif : - win_ {mv.win_}, + win_{mv.win_}, #ifndef NDEBUG - win_save_ {mv.win_save_}, + win_save_{mv.win_save_}, #endif - subwindows_ {std::move(mv.subwindows_)} + subwindows_{std::move(mv.subwindows_)} { mv.win_ = nullptr; + #ifndef NDEBUG mv.win_save_ = nullptr; ncurses().register_window_(*this, Key{}); @@ -121,11 +114,9 @@ inline Window &Window::operator=(Window &&mv) noexcept { inline Window::~Window() { #ifndef NDEBUG - if (this != &ncurses()) { ncurses().unregister_window_(*this, Key{}); } - #endif destroy(); @@ -154,7 +145,6 @@ inline void Window::destroy() { delwin(win_save_); win_save_ = nullptr; } - #endif } @@ -191,8 +181,7 @@ inline std::size_t Window::add_subwindow(int lines, int cols, int beg_y, int beg try { subwindows_.emplace_back(*this, new_subw, Window::Key{}); - } - catch (...) { + } catch (...) { delwin(new_subw); throw; } @@ -255,15 +244,16 @@ inline int copywin( bool overlay ) { return ::copywin( - src.get_handle(), - dst.get_handle(), - sminrow, - smincol, - dminrow, - dmincol, - dmaxrow, - dmaxcol, - overlay); + src.get_handle(), + dst.get_handle(), + sminrow, + smincol, + dminrow, + dmincol, + dmaxrow, + dmaxcol, + overlay + ); } } // namespace nccpp diff --git a/src/lib/nccpp/constants.hpp b/src/lib/nccpp/constants.hpp index 0033f61..64a26e5 100644 --- a/src/lib/nccpp/constants.hpp +++ b/src/lib/nccpp/constants.hpp @@ -173,37 +173,37 @@ int constexpr event{KEY_EVENT}; namespace internal { struct ButtonRelease { - mmask_t operator()(mmask_t event, unsigned char button) const { + mmask_t operator()(mmask_t event, unsigned char button) const { return BUTTON_RELEASE(event, button); } }; struct ButtonPress { - mmask_t operator()(mmask_t event, unsigned char button) const { + mmask_t operator()(mmask_t event, unsigned char button) const { return BUTTON_PRESS(event, button); } }; struct ButtonClick { - mmask_t operator()(mmask_t event, unsigned char button) const { + mmask_t operator()(mmask_t event, unsigned char button) const { return BUTTON_CLICK(event, button); } }; struct ButtonDoubleClick { - mmask_t operator()(mmask_t event, unsigned char button) const { + mmask_t operator()(mmask_t event, unsigned char button) const { return BUTTON_DOUBLE_CLICK(event, button); } }; struct ButtonTripleClick { - mmask_t operator()(mmask_t event, unsigned char button) const { + mmask_t operator()(mmask_t event, unsigned char button) const { return BUTTON_TRIPLE_CLICK(event, button); } }; struct ButtonReserved { - mmask_t operator()(mmask_t event, unsigned char button) const { + mmask_t operator()(mmask_t event, unsigned char button) const { return BUTTON_RESERVED_EVENT(event, button); } }; diff --git a/src/mumta/evloop.cpp b/src/mumta/evloop.cpp index 42710e7..3b55825 100644 --- a/src/mumta/evloop.cpp +++ b/src/mumta/evloop.cpp @@ -16,6 +16,7 @@ struct stdin_waiter : std::enable_shared_from_this<stdin_waiter> e_stdin.set(0, ::ev::READ); e_stdin.start(); } + ~stdin_waiter() { e_stdin.stop(); } diff --git a/src/net/address.hpp b/src/net/address.hpp index 3c7c95a..22998fa 100644 --- a/src/net/address.hpp +++ b/src/net/address.hpp @@ -17,13 +17,13 @@ static constexpr T host_to_net(T hostval) { static_assert(std::is_integral<T>::value && (sizeof(T) == 2 || sizeof(T) == 4)); - if constexpr(__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) { + if constexpr (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) { return hostval; } - if constexpr(sizeof(T) == 2) { + if constexpr (sizeof(T) == 2) { return __builtin_bswap16(hostval); - } else if constexpr(sizeof(T) == 4) { + } else if constexpr (sizeof(T) == 4) { return __builtin_bswap32(hostval); } } @@ -87,11 +87,11 @@ static constexpr bool is_valid_digit(char c) { static_assert(base == 8 || base == 10 || base == 16, "Invalid base parameter"); - if constexpr(base == 8) { + if constexpr (base == 8) { return (c >= '0' && c <= '7'); - } else if constexpr(base == 10) { + } else if constexpr (base == 10) { return isdigit(c); - } else if constexpr(base == 16) { + } else if constexpr (base == 16) { return isxdigit(c); } } @@ -450,7 +450,7 @@ static constexpr auto inet_pton(const char (&str)[N]) { static_assert(AddressF == AF_INET || AddressF == AF_INET6, "Unsupported address family."); - if constexpr(AddressF == AF_INET) { + if constexpr (AddressF == AF_INET) { struct in_addr in = {}; details::inet_aton_canonical(str, in); @@ -488,7 +488,7 @@ static constexpr auto operator"" _ipaddr() static_assert(rmrf::net::is_valid_ip4addr(str) || rmrf::net::is_valid_ip6addr(str), "Invalid IP address format."); - if constexpr(rmrf::net::is_valid_ip4addr(str)) { + if constexpr (rmrf::net::is_valid_ip4addr(str)) { return rmrf::net::inet_aton(str); } else { return rmrf::net::inet_pton<AF_INET6>(str); diff --git a/src/net/async_fd.hpp b/src/net/async_fd.hpp index b5a7f0d..42c7fe0 100644 --- a/src/net/async_fd.hpp +++ b/src/net/async_fd.hpp @@ -4,8 +4,7 @@ namespace rmrf::net { - class null_fd - { + class null_fd { public: constexpr explicit null_fd() {} constexpr explicit null_fd(int) {} @@ -14,8 +13,7 @@ namespace rmrf::net { constexpr null_fd nullfd{}; - class auto_fd - { + class auto_fd { private: int _fd; @@ -39,8 +37,7 @@ namespace rmrf::net { inline int get() const noexcept { return _fd; } - int release() noexcept - { + int release() noexcept { int r(_fd); _fd = -1; return r; @@ -67,7 +64,6 @@ namespace rmrf::net { inline bool valid() const { return _fd >= 0; } - }; inline bool operator==(const auto_fd &x, const auto_fd &y) { diff --git a/src/net/async_server.cpp b/src/net/async_server.cpp index 01bd6b9..1b59061 100644 --- a/src/net/async_server.cpp +++ b/src/net/async_server.cpp @@ -13,8 +13,14 @@ namespace rmrf::net { -async_server_socket::async_server_socket(auto_fd&& socket_fd) : - socket(std::forward<auto_fd>(socket_fd)), on_accept{}, on_error{}, io{} { +async_server_socket::async_server_socket( + auto_fd &&socket_fd +) : + socket(std::forward<auto_fd>(socket_fd)), + on_accept{}, + on_error{}, + io{} +{ // This constructor got a constructed socket as an argument // and forwards it to libev io.set<async_server_socket, &async_server_socket::cb_ev>(this); @@ -23,37 +29,38 @@ async_server_socket::async_server_socket(auto_fd&& socket_fd) : async_server_socket::~async_server_socket() { // Remove this socket from libev ... - io.stop(); + io.stop(); } void async_server_socket::cb_ev(::ev::io &w, int events) { - (void) w; - - if (events & ::ev::ERROR) { - // Handle errors - // Rebind socket if missed iov res else - // Log and throw? - return; - } - - if (events & ::ev::READ) { - // Handle incoming clients - auto ah = this->get_accept_handler(); - ah(this->shared_from_this(), this->socket); - } - - if (events & ::ev::WRITE) { - // Handle sending data which should be none here - } + (void) w; + + if (events & ::ev::ERROR) { + // Handle errors + // Rebind socket if missed iov res else + // Log and throw? + return; + } + + if (events & ::ev::READ) { + // Handle incoming clients + auto ah = this->get_accept_handler(); + ah(this->shared_from_this(), this->socket); + } + + if (events & ::ev::WRITE) { + // Handle sending data which should be none here + } } inline void async_server_socket::set_accept_handler( - const accept_handler_type &value) { - on_accept = value; + const accept_handler_type &value +) { + on_accept = value; } inline async_server_socket::accept_handler_type async_server_socket::get_accept_handler() const { - return on_accept; + return on_accept; } } diff --git a/src/net/connection_client.cpp b/src/net/connection_client.cpp index b2cc222..ca1ca07 100644 --- a/src/net/connection_client.cpp +++ b/src/net/connection_client.cpp @@ -10,11 +10,11 @@ namespace rmrf::net { connection_client::connection_client() : in_data_cb{} { - + // Nothing to do here } inline void connection_client::set_incomming_data_callback(const incomming_data_cb &cb) { - this->in_data_cb = cb; + this->in_data_cb = cb; } } diff --git a/src/net/connection_client.hpp b/src/net/connection_client.hpp index d3e0330..8036375 100644 --- a/src/net/connection_client.hpp +++ b/src/net/connection_client.hpp @@ -15,23 +15,25 @@ namespace rmrf::net { class connection_client : public std::enable_shared_from_this<connection_client> { public: - typedef std::function<void(const std::string&)> incomming_data_cb; + typedef std::function<void(const std::string&)> incomming_data_cb; + protected: - incomming_data_cb in_data_cb; + incomming_data_cb in_data_cb; + public: - connection_client(); - - /** - * Use this method to send data to the other endpoint. - */ - virtual void write_data(const std::string& data) = 0; - - /** - * Use this method in order to register your callback function that should be - * called when the client got data to process. - * @param cb The callback function to register [void(std::string data)] - */ - void set_incomming_data_callback(const incomming_data_cb &cb); + connection_client(); + + /** + * Use this method to send data to the other endpoint. + */ + virtual void write_data(const std::string& data) = 0; + + /** + * Use this method in order to register your callback function that should be + * called when the client got data to process. + * @param cb The callback function to register [void(std::string data)] + */ + void set_incomming_data_callback(const incomming_data_cb &cb); }; } diff --git a/src/net/connection_line_buffer.cpp b/src/net/connection_line_buffer.cpp index 7d1c562..fd8a0c2 100644 --- a/src/net/connection_line_buffer.cpp +++ b/src/net/connection_line_buffer.cpp @@ -9,66 +9,86 @@ namespace rmrf::net { -static std::string::size_type default_eol_search(const std::string& data, std::string::size_type start_position) { - const std::string::size_type s = data.size(); - for (std::string::size_type i = start_position; i < s; i++) { - switch (data[i]) { - case '\r': - if(i < s - 1) { - if (data[i + 1] == '\n') { - i++; - } - } - [[fallthrough]]; - case '\n': - return i; - break; - default: - break; - } - } - return std::string::npos; +static std::string::size_type default_eol_search( + const std::string &data, + std::string::size_type start_position +) { + const std::string::size_type s = data.size(); + + for (std::string::size_type i = start_position; i < s; i++) { + switch (data[i]) { + case '\r': + if (i < s - 1) { + if (data[i + 1] == '\n') { + i++; + } + } + + [[fallthrough]]; + + case '\n': + return i; + break; + + default: + break; + } + } + + return std::string::npos; } -connection_line_buffer::connection_line_buffer(std::shared_ptr<connection_client> c, found_next_line_cb_t found_next_line_cb_, - std::string::size_type max_line_size, eol_search_t search_lb) : - search(search_lb), - client(c), - found_next_line_cb(found_next_line_cb_), - max(max_line_size), - data("") { - this->client->set_incomming_data_callback(std::bind(&connection_line_buffer::conn_data_in_cb, this, std::placeholders::_1)); +connection_line_buffer::connection_line_buffer( + std::shared_ptr<connection_client> c, + found_next_line_cb_t found_next_line_cb_, + std::string::size_type max_line_size, + eol_search_t search_lb +) : + search(search_lb), + client(c), + found_next_line_cb(found_next_line_cb_), + max(max_line_size), + data("") +{ + this->client->set_incomming_data_callback(std::bind(&connection_line_buffer::conn_data_in_cb, this, std::placeholders::_1)); } -connection_line_buffer::connection_line_buffer(std::shared_ptr<connection_client> c, found_next_line_cb_t found_next_line_cb_, - std::string::size_type max_line_size) : connection_line_buffer{c, found_next_line_cb_, max_line_size, &default_eol_search} { } - -void connection_line_buffer::conn_data_in_cb(const std::string& data_in) { - - /** - * Known limitation: If the last received data ends with '\r' and the next incoming data would start with '\n' there is no way - * to detect this as the received message might indeed be a complete one ending with '\r' and one cannot wait for a potential - * continuation of said message to arrive. - */ - - std::string::size_type strpos = 0; - - while(strpos != std::string::npos) { - std::string::size_type nextpos = this->search(data_in, strpos); - if (nextpos == std::string::npos) { - this->data += data_in.substr(strpos, data_in.length() - strpos); - break; - } else { - this->found_next_line_cb(this->data + data_in.substr(strpos, nextpos - strpos), true); - this->data = std::string(""); - } - strpos = nextpos; - } - - if (this->data.length() > this->max) { - this->found_next_line_cb(this->data, false); - this->data = std::string(""); - } +connection_line_buffer::connection_line_buffer( + std::shared_ptr<connection_client> c, + found_next_line_cb_t found_next_line_cb_, + std::string::size_type max_line_size +) : + connection_line_buffer{c, found_next_line_cb_, max_line_size, &default_eol_search} +{} + +void connection_line_buffer::conn_data_in_cb(const std::string &data_in) { + + /** + * Known limitation: If the last received data ends with '\r' and the next incoming data would start with '\n' there is no way + * to detect this as the received message might indeed be a complete one ending with '\r' and one cannot wait for a potential + * continuation of said message to arrive. + */ + + std::string::size_type strpos = 0; + + while (strpos != std::string::npos) { + std::string::size_type nextpos = this->search(data_in, strpos); + + if (nextpos == std::string::npos) { + this->data += data_in.substr(strpos, data_in.length() - strpos); + break; + } else { + this->found_next_line_cb(this->data + data_in.substr(strpos, nextpos - strpos), true); + this->data = std::string(""); + } + + strpos = nextpos; + } + + if (this->data.length() > this->max) { + this->found_next_line_cb(this->data, false); + this->data = std::string(""); + } } } diff --git a/src/net/connection_line_buffer.hpp b/src/net/connection_line_buffer.hpp index 6eaf17c..389a94f 100644 --- a/src/net/connection_line_buffer.hpp +++ b/src/net/connection_line_buffer.hpp @@ -21,18 +21,21 @@ static std::string::size_type default_eol_search(const std::string& data, std::s class connection_line_buffer { public: - typedef std::function<void(const std::string&, bool)> found_next_line_cb_t; + typedef std::function<void(const std::string&, bool)> found_next_line_cb_t; + private: - const eol_search_t search; - std::shared_ptr<connection_client> client; - found_next_line_cb_t found_next_line_cb; - std::string::size_type max; - std::string data; + const eol_search_t search; + std::shared_ptr<connection_client> client; + found_next_line_cb_t found_next_line_cb; + std::string::size_type max; + std::string data; + public: - connection_line_buffer(std::shared_ptr<connection_client> c, found_next_line_cb_t found_next_line_cb_, std::string::size_type max_line_size, eol_search_t search_lb = default_eol_search); - connection_line_buffer(std::shared_ptr<connection_client> c, found_next_line_cb_t found_next_line_cb_, std::string::size_type max_line_size); + connection_line_buffer(std::shared_ptr<connection_client> c, found_next_line_cb_t found_next_line_cb_, std::string::size_type max_line_size, eol_search_t search_lb = default_eol_search); + connection_line_buffer(std::shared_ptr<connection_client> c, found_next_line_cb_t found_next_line_cb_, std::string::size_type max_line_size); + private: - void conn_data_in_cb(const std::string& data_in); + void conn_data_in_cb(const std::string& data_in); }; } diff --git a/src/net/ioqueue.cpp b/src/net/ioqueue.cpp index f01262f..5cb1adb 100644 --- a/src/net/ioqueue.cpp +++ b/src/net/ioqueue.cpp @@ -4,16 +4,24 @@ namespace rmrf::net { iorecord::iorecord() : offset{}, data{} {} -iorecord::iorecord(const void *buf, size_t size) : - offset{0}, data((const uint8_t *)buf, (const uint8_t *)buf + size) { +iorecord::iorecord( + const void* buf, + size_t size +) : + offset{0}, + data((const uint8_t*)buf, (const uint8_t*)buf + size) +{ // Nothing special to do here ... } + iorecord::iorecord(const iorecord &other) : offset{other.offset}, data{other.data} { // NOP } iorecord::iorecord(iorecord &&other) : - offset(other.offset), data(std::forward<std::vector<uint8_t>>(other.data)) { + offset(other.offset), + data(std::forward<std::vector<uint8_t>>(other.data)) +{ // Nothing special to do here ... } @@ -24,8 +32,9 @@ size_t iorecord::size() const { bool iorecord::empty() const { return !this->size(); } -void *iorecord::ptr() const { - return (void *)(this->data.data() + this->offset); + +void* iorecord::ptr() const { + return (void*)(this->data.data() + this->offset); } void iorecord::advance(size_t amount) { @@ -49,6 +58,7 @@ void ioqueue::push_back(const iorecord &data) { this->queue.push_back(data); } } + void ioqueue::push_back(iorecord &&data) { if (!data.empty()) { this->queue.emplace_back(std::forward<iorecord>(data)); @@ -60,6 +70,7 @@ void ioqueue::push_front(const iorecord &data) { this->queue.push_front(data); } } + void ioqueue::push_front(iorecord &&data) { if (!data.empty()) { this->queue.emplace_front(std::forward<iorecord>(data)); diff --git a/src/net/ioqueue.hpp b/src/net/ioqueue.hpp index b97ef9f..f44fb09 100644 --- a/src/net/ioqueue.hpp +++ b/src/net/ioqueue.hpp @@ -12,6 +12,7 @@ namespace rmrf::net { private: size_t offset; std::vector<uint8_t> data; + public: iorecord(); iorecord(const void *buf, size_t size); diff --git a/src/net/netio_exception.cpp b/src/net/netio_exception.cpp index 45a720e..b787c1a 100644 --- a/src/net/netio_exception.cpp +++ b/src/net/netio_exception.cpp @@ -8,13 +8,15 @@ #include "netio_exception.hpp" namespace rmrf::net { - netio_exception::netio_exception(const std::string cause_) : cause(cause_) { - } +netio_exception::netio_exception(const std::string cause_) : + cause(cause_) +{} + +const char* netio_exception::what() const throw() { + return this->cause.c_str(); +} - const char* netio_exception::what() const throw(){ - return this->cause.c_str(); - } } diff --git a/src/net/netio_exception.hpp b/src/net/netio_exception.hpp index a73817f..71da706 100644 --- a/src/net/netio_exception.hpp +++ b/src/net/netio_exception.hpp @@ -13,12 +13,13 @@ namespace rmrf::net { -class netio_exception: public std::exception { +class netio_exception : public std::exception { private: - std::string cause; + std::string cause; + public: - netio_exception(const std::string cause_); - virtual const char* what() const throw(); + netio_exception(const std::string cause_); + virtual const char* what() const throw(); }; } diff --git a/src/net/socketaddress.hpp b/src/net/socketaddress.hpp index f7d0a9a..c32867d 100644 --- a/src/net/socketaddress.hpp +++ b/src/net/socketaddress.hpp @@ -102,7 +102,7 @@ COMPILER_RESTORE("-Weffc++"); } socketaddr& operator=(sockaddr *rhs) { - switch(rhs->sa_family) { + switch (rhs->sa_family) { case AF_INET: return *this = (sockaddr_in *)rhs; case AF_INET6: @@ -136,7 +136,6 @@ COMPILER_RESTORE("-Weffc++"); socklen_t size() const { return len; } - }; } diff --git a/src/net/tcp_client.cpp b/src/net/tcp_client.cpp index e62cffd..f5f7b0b 100644 --- a/src/net/tcp_client.cpp +++ b/src/net/tcp_client.cpp @@ -21,197 +21,223 @@ namespace rmrf::net { -tcp_client::tcp_client(const destructor_cb_type destructor_cb_, auto_fd&& socket_fd, std::string peer_address_, uint16_t port_) : - connection_client{}, - destructor_cb(destructor_cb_), - peer_address(peer_address_), port(port_), - net_socket(std::forward<auto_fd>(socket_fd)), - io{}, write_queue{} { - io.set<tcp_client, &tcp_client::cb_ev>(this); - io.start(this->net_socket.get(), ::ev::READ); - // TODO log created client +tcp_client::tcp_client( + const destructor_cb_type destructor_cb_, + auto_fd &&socket_fd, + std::string peer_address_, + uint16_t port_ +) : + connection_client{}, + destructor_cb(destructor_cb_), + peer_address(peer_address_), port(port_), + net_socket(std::forward<auto_fd>(socket_fd)), + io{}, write_queue{} +{ + io.set<tcp_client, &tcp_client::cb_ev>(this); + io.start(this->net_socket.get(), ::ev::READ); + // TODO log created client } -tcp_client::tcp_client(const std::string& peer_address_, const std::string& service_or_port, int ip_addr_family) : - connection_client{}, - destructor_cb(nullptr), - peer_address(peer_address_), - port(0), - net_socket(nullfd), - io{}, - write_queue{} { - if (!(ip_addr_family == AF_INET || ip_addr_family == AF_INET6)) { - throw netio_exception("Invalid IP address family."); - } - - this->net_socket = auto_fd(socket(ip_addr_family, SOCK_STREAM, 0)); - if(!this->net_socket.valid()) { - // TODO implement proper error handling - throw netio_exception("Failed to request socket fd from kernel."); - } - - // TODO Extract DNS/service resolution into separate library - // TODO build another nice HL structure wrapper for outbound connections - std::deque<socketaddr> connection_candidates; - int status; - { - //Reduce scope of locally declared variables - //May be candidate for extraction into own method - addrinfo hints; - addrinfo* servinfo = nullptr; - memset(&hints, 0, sizeof hints); - hints.ai_family = ip_addr_family; - hints.ai_socktype = SOCK_STREAM; - - if ((status = getaddrinfo(peer_address_.c_str(), service_or_port.c_str(), &hints, &servinfo)) != 0) { - throw netio_exception("Failed to resolve address '" + peer_address_ + "' with service '" + service_or_port + "': " + gai_strerror(status)); - } - - // TODO: Prefer IPv6 over IPv4 - for(auto p = servinfo; p != NULL; p = p->ai_next) { - if (p->ai_family == AF_INET) { - socketaddr sa{(sockaddr_in *)p->ai_addr}; - connection_candidates.push_back(sa); - } else if (p->ai_family == AF_INET6) { - socketaddr sa{(sockaddr_in6 *)p->ai_addr}; - connection_candidates.push_front(sa); - } - } - - freeaddrinfo(servinfo); - } - - status = 1; - do { - if(connection_candidates.empty()) { - throw netio_exception("Unable to find suitable connection candidate."); - } - socketaddr socket_identifier = connection_candidates.front(); - connection_candidates.pop_front(); - auto_fd socket_candidate{socket(socket_identifier.family(), SOCK_STREAM, 0)}; - if (socket_candidate.valid()) { - if(connect(socket_candidate.get(), socket_identifier.ptr(), socket_identifier.size()) == 0) { - status = 0; - this->net_socket = std::forward<auto_fd>(socket_candidate); - fcntl(this->net_socket.get(), F_SETFL, fcntl(this->net_socket.get(), F_GETFL, 0) | O_NONBLOCK); - - // Hier bin ich mir nicht sicher, wie ich das am besten mache. Auch mit socketaddr und type cast ist das irgendwie doof. - // Das Problem besteht darin, dass erst nach erfolgreichem connect der Port auf dieser Seite bekannt ist. - socketaddr sa_local; - socklen_t sa_local_len = sizeof(sockaddr_storage); - if (getsockname(this->net_socket.get(), sa_local.ptr(), &sa_local_len)) - { - // Update length field after the internal structure was modified - // TODO: Maybe make this an internal method in socketaddr to update the size - sa_local = sa_local.ptr(); - //The pointer casts are safe due to operator overloading in socketaddr ... - switch(sa_local.family()) { - case AF_INET: - this->port = ntohs(((sockaddr_in*)sa_local)->sin_port); - break; - case AF_INET6: - this->port = ntohs(((sockaddr_in6*)sa_local)->sin6_port); - break; - default: - throw netio_exception("Invalid/unexpected local socket address type"); - } - } - } - } - - // We don't need to worry about closing broken fd as auto_fd handles this for us - } while (status == 1); - - io.set<tcp_client, &tcp_client::cb_ev>(this); - io.start(this->net_socket.get(), ::ev::READ); - //TODO log connected client +tcp_client::tcp_client( + const std::string &peer_address_, + const std::string &service_or_port, + int ip_addr_family +) : + connection_client{}, + destructor_cb(nullptr), + peer_address(peer_address_), + port(0), + net_socket(nullfd), + io{}, + write_queue{} +{ + if (!(ip_addr_family == AF_INET || ip_addr_family == AF_INET6)) { + throw netio_exception("Invalid IP address family."); + } + + this->net_socket = auto_fd(socket(ip_addr_family, SOCK_STREAM, 0)); + + if (!this->net_socket.valid()) { + // TODO implement proper error handling + throw netio_exception("Failed to request socket fd from kernel."); + } + + // TODO Extract DNS/service resolution into separate library + // TODO build another nice HL structure wrapper for outbound connections + std::deque<socketaddr> connection_candidates; + int status; + { + //Reduce scope of locally declared variables + //May be candidate for extraction into own method + addrinfo hints; + addrinfo* servinfo = nullptr; + memset(&hints, 0, sizeof hints); + hints.ai_family = ip_addr_family; + hints.ai_socktype = SOCK_STREAM; + + if ((status = getaddrinfo(peer_address_.c_str(), service_or_port.c_str(), &hints, &servinfo)) != 0) { + throw netio_exception("Failed to resolve address '" + peer_address_ + "' with service '" + service_or_port + "': " + gai_strerror(status)); + } + + // TODO: Prefer IPv6 over IPv4 + for (auto p = servinfo; p != NULL; p = p->ai_next) { + if (p->ai_family == AF_INET) { + socketaddr sa{(sockaddr_in*)p->ai_addr}; + connection_candidates.push_back(sa); + } else if (p->ai_family == AF_INET6) { + socketaddr sa{(sockaddr_in6*)p->ai_addr}; + connection_candidates.push_front(sa); + } + } + + freeaddrinfo(servinfo); + } + + status = 1; + + do { + if (connection_candidates.empty()) { + throw netio_exception("Unable to find suitable connection candidate."); + } + + socketaddr socket_identifier = connection_candidates.front(); + connection_candidates.pop_front(); + auto_fd socket_candidate{socket(socket_identifier.family(), SOCK_STREAM, 0)}; + + if (socket_candidate.valid()) { + if (connect(socket_candidate.get(), socket_identifier.ptr(), socket_identifier.size()) == 0) { + status = 0; + this->net_socket = std::forward<auto_fd>(socket_candidate); + fcntl(this->net_socket.get(), F_SETFL, fcntl(this->net_socket.get(), F_GETFL, 0) | O_NONBLOCK); + + // Hier bin ich mir nicht sicher, wie ich das am besten mache. Auch mit socketaddr und type cast ist das irgendwie doof. + // Das Problem besteht darin, dass erst nach erfolgreichem connect der Port auf dieser Seite bekannt ist. + socketaddr sa_local; + socklen_t sa_local_len = sizeof(sockaddr_storage); + + if (getsockname(this->net_socket.get(), sa_local.ptr(), &sa_local_len)) { + // Update length field after the internal structure was modified + // TODO: Maybe make this an internal method in socketaddr to update the size + sa_local = sa_local.ptr(); + + //The pointer casts are safe due to operator overloading in socketaddr ... + switch (sa_local.family()) { + case AF_INET: + this->port = ntohs(((sockaddr_in*)sa_local)->sin_port); + break; + + case AF_INET6: + this->port = ntohs(((sockaddr_in6*)sa_local)->sin6_port); + break; + + default: + throw netio_exception("Invalid/unexpected local socket address type"); + } + } + } + } + + // We don't need to worry about closing broken fd as auto_fd handles this for us + } while (status == 1); + + io.set<tcp_client, &tcp_client::cb_ev>(this); + io.start(this->net_socket.get(), ::ev::READ); + //TODO log connected client } -tcp_client::tcp_client(const std::string& peer_address_, const std::string& service_or_port) : - tcp_client(peer_address_, service_or_port, AF_UNSPEC) { } +tcp_client::tcp_client( + const std::string &peer_address_, + const std::string &service_or_port +) : + tcp_client(peer_address_, service_or_port, AF_UNSPEC) +{} -tcp_client::tcp_client(const std::string& peer_address_, const uint16_t port_) : - tcp_client(peer_address_, std::to_string(port_)) {} +tcp_client::tcp_client( + const std::string &peer_address_, + const uint16_t port_ +) : + tcp_client(peer_address_, std::to_string(port_)) +{} tcp_client::~tcp_client() { - if(destructor_cb != nullptr) - destructor_cb(exit_status_t::NO_ERROR); - io.stop(); + if (destructor_cb != nullptr) { + destructor_cb(exit_status_t::NO_ERROR); + } + + io.stop(); } -void tcp_client::write_data(const std::string& data) { - // Create NICBuffer from data - this->write_queue.push_back(iorecord{data.c_str(), data.size()}); - this->io.set(::ev::READ | ::ev::WRITE); +void tcp_client::write_data(const std::string &data) { + // Create NICBuffer from data + this->write_queue.push_back(iorecord{data.c_str(), data.size()}); + this->io.set(::ev::READ | ::ev::WRITE); } -inline std::string buffer_to_string(char* buffer, ssize_t bufflen) -{ +inline std::string buffer_to_string(char* buffer, ssize_t bufflen) { return std::string(buffer, (size_t)bufflen); } void tcp_client::cb_ev(::ev::io &w, int events) { - if (events & ::ev::ERROR) { - // Handle errors - // Log and throw? - return; - } - - if (events & ::ev::READ) { - // notify incomming_data_cb - char buffer[1024]; - - ssize_t n_read_bytes = recv(w.fd, buffer, sizeof(buffer), 0); - if(n_read_bytes < 0) { - throw netio_exception("Failed to read from network socket."); - } - - if(n_read_bytes == 0) { - // TODO find a way to properly announce the closed connection - delete this; - } else { - this->in_data_cb(buffer_to_string(buffer, n_read_bytes)); - } - } - - if (events & ::ev::WRITE) { - // Handle sending data - push_write_queue(w); - } - - if (write_queue.empty()) { - io.set(::ev::READ); - } else { - io.set(::ev::READ | ::ev::WRITE); - } + if (events & ::ev::ERROR) { + // Handle errors + // Log and throw? + return; + } + + if (events & ::ev::READ) { + // notify incomming_data_cb + char buffer[1024]; + + ssize_t n_read_bytes = recv(w.fd, buffer, sizeof(buffer), 0); + + if (n_read_bytes < 0) { + throw netio_exception("Failed to read from network socket."); + } + + if (n_read_bytes == 0) { + // TODO find a way to properly announce the closed connection + delete this; + } else { + this->in_data_cb(buffer_to_string(buffer, n_read_bytes)); + } + } + + if (events & ::ev::WRITE) { + // Handle sending data + push_write_queue(w); + } + + if (write_queue.empty()) { + io.set(::ev::READ); + } else { + io.set(::ev::READ | ::ev::WRITE); + } } void tcp_client::push_write_queue(::ev::io &w) { - if (this->write_queue.empty()) { - io.set(::ev::READ); - return; - } + if (this->write_queue.empty()) { + io.set(::ev::READ); + return; + } - iorecord buffer = this->write_queue.pop_front(); - ssize_t written = write(w.fd, buffer.ptr(), buffer.size()); + iorecord buffer = this->write_queue.pop_front(); + ssize_t written = write(w.fd, buffer.ptr(), buffer.size()); - if (written >= 0) { - buffer.advance((size_t)written); - } else if (errno != EAGAIN) { - throw netio_exception("Failed to write latest buffer content."); - } + if (written >= 0) { + buffer.advance((size_t)written); + } else if (errno != EAGAIN) { + throw netio_exception("Failed to write latest buffer content."); + } - this->write_queue.push_front(buffer); + this->write_queue.push_front(buffer); } inline std::string tcp_client::get_peer_address() { - return this->peer_address; + return this->peer_address; } inline uint16_t tcp_client::get_port() { - return this->port; + return this->port; } } - - diff --git a/src/net/tcp_client.hpp b/src/net/tcp_client.hpp index 0ec1720..da08865 100644 --- a/src/net/tcp_client.hpp +++ b/src/net/tcp_client.hpp @@ -22,33 +22,36 @@ namespace rmrf::net { enum class exit_status_t : uint16_t { - NO_ERROR = 0, - TIMEOUT = 1 + NO_ERROR = 0, + TIMEOUT = 1 }; class tcp_client : public connection_client, std::enable_shared_from_this<tcp_client> { public: - typedef std::function<void(exit_status_t)> destructor_cb_type; + typedef std::function<void(exit_status_t)> destructor_cb_type; + private: - const destructor_cb_type destructor_cb; - const std::string peer_address; + const destructor_cb_type destructor_cb; + const std::string peer_address; + + uint16_t port; + auto_fd net_socket; + ::ev::io io; + ioqueue write_queue; - uint16_t port; - auto_fd net_socket; - ::ev::io io; - ioqueue write_queue; public: - tcp_client(const destructor_cb_type destructor_cb_, auto_fd&& socket_fd, std::string peer_address_, uint16_t port_); - tcp_client(const std::string& peer_address_, const uint16_t port_); - tcp_client(const std::string& peer_address_, const std::string& service_or_port); - tcp_client(const std::string& peer_address_, const std::string& service_or_port, int ip_addr_family); - virtual ~tcp_client(); - virtual void write_data(const std::string& data); - std::string get_peer_address(); - uint16_t get_port(); + tcp_client(const destructor_cb_type destructor_cb_, auto_fd&& socket_fd, std::string peer_address_, uint16_t port_); + tcp_client(const std::string& peer_address_, const uint16_t port_); + tcp_client(const std::string& peer_address_, const std::string& service_or_port); + tcp_client(const std::string& peer_address_, const std::string& service_or_port, int ip_addr_family); + virtual ~tcp_client(); + virtual void write_data(const std::string& data); + std::string get_peer_address(); + uint16_t get_port(); + private: - void cb_ev(::ev::io &w, int events); - void push_write_queue(::ev::io &w); + void cb_ev(::ev::io &w, int events); + void push_write_queue(::ev::io &w); }; } diff --git a/src/net/tcp_server_socket.cpp b/src/net/tcp_server_socket.cpp index adbd75b..1979e7e 100644 --- a/src/net/tcp_server_socket.cpp +++ b/src/net/tcp_server_socket.cpp @@ -27,85 +27,100 @@ namespace rmrf::net { -tcp_server_socket::tcp_server_socket(const socketaddr& socket_identifier, incoming_client_listener_type client_listener_) : - ss{nullptr}, client_listener(client_listener_), number_of_connected_clients(0) { - auto_fd socket_fd{socket(socket_identifier.family(), SOCK_STREAM, 0)}; - if(!socket_fd.valid()) { - // TODO implement propper error handling - throw netio_exception("Failed to create socket fd."); - } - - if (bind(socket_fd.get(), socket_identifier.ptr(), socket_identifier.size()) != 0) { - std::string msg = "Failed to bind to all addresses (FIXME)"; - - if (socket_identifier.family() == AF_INET6 || socket_identifier.family() == AF_INET) { - // TODO find a nice way to check for the port - /* - if (port < 1024) { - msg += "\nYou tried to bind to a port smaller than 1024. Are you root?"; - } - */ - } - throw netio_exception(msg); - } - - // Append the non blocking flag to the file state of the socket fd. - // This might be linux only. We should check that - fcntl(socket_fd.get(), F_SETFL, fcntl(socket_fd.get(), F_GETFL, 0) | O_NONBLOCK); - if (listen(socket_fd.get(), 5) == -1) { - throw netio_exception("Failed to enable listening mode for raw socket"); - } - - this->ss = std::make_shared<async_server_socket>(std::forward<auto_fd>(socket_fd)); - - using namespace std::placeholders; - this->ss->set_accept_handler(std::bind(&tcp_server_socket::await_raw_socket_incomming, this, _1, _2)); - +tcp_server_socket::tcp_server_socket( + const socketaddr &socket_identifier, + incoming_client_listener_type client_listener_ +) : + ss{nullptr}, + client_listener(client_listener_), + number_of_connected_clients(0) +{ + auto_fd socket_fd{socket(socket_identifier.family(), SOCK_STREAM, 0)}; + + if (!socket_fd.valid()) { + // TODO implement propper error handling + throw netio_exception("Failed to create socket fd."); + } + + if (bind(socket_fd.get(), socket_identifier.ptr(), socket_identifier.size()) != 0) { + std::string msg = "Failed to bind to all addresses (FIXME)"; + + if (socket_identifier.family() == AF_INET6 || socket_identifier.family() == AF_INET) { + // TODO find a nice way to check for the port + /* + if (port < 1024) { + msg += "\nYou tried to bind to a port smaller than 1024. Are you root?"; + } + */ + } + + throw netio_exception(msg); + } + + // Append the non blocking flag to the file state of the socket fd. + // TODO This might be linux only. We should check that + fcntl(socket_fd.get(), F_SETFL, fcntl(socket_fd.get(), F_GETFL, 0) | O_NONBLOCK); + + if (listen(socket_fd.get(), 5) == -1) { + throw netio_exception("Failed to enable listening mode for raw socket"); + } + + this->ss = std::make_shared<async_server_socket>(std::forward<auto_fd>(socket_fd)); + + using namespace std::placeholders; + this->ss->set_accept_handler(std::bind(&tcp_server_socket::await_raw_socket_incomming, this, _1, _2)); } static inline socketaddr get_ipv6_socketaddr(const uint16_t port) { - sockaddr_in6 addr; - addr.sin6_family = AF_INET6; - addr.sin6_port = htons(port); - addr.sin6_addr = IN6ADDR_ANY_INIT; - socketaddr sa{addr}; - return sa; + sockaddr_in6 addr; + addr.sin6_family = AF_INET6; + addr.sin6_port = htons(port); + addr.sin6_addr = IN6ADDR_ANY_INIT; + socketaddr sa{addr}; + return sa; } -tcp_server_socket::tcp_server_socket(const uint16_t port, incoming_client_listener_type client_listener_) : - tcp_server_socket{get_ipv6_socketaddr(port), client_listener_} { } +tcp_server_socket::tcp_server_socket( + const uint16_t port, + incoming_client_listener_type client_listener_ +) : + tcp_server_socket{get_ipv6_socketaddr(port), client_listener_} +{} +void tcp_server_socket::await_raw_socket_incomming( + async_server_socket::self_ptr_type ass, + const auto_fd &socket +) { + MARK_UNUSED(ass); -void tcp_server_socket::await_raw_socket_incomming(async_server_socket::self_ptr_type ass, const auto_fd& socket) { - MARK_UNUSED(ass); + struct sockaddr_in client_addr; + socklen_t client_len = sizeof(client_addr); + int client_fd_raw = accept(socket.get(), (struct sockaddr*)&client_addr, &client_len); - struct sockaddr_in client_addr; - socklen_t client_len = sizeof(client_addr); - int client_fd_raw = accept(socket.get(), (struct sockaddr *)&client_addr, &client_len); + if (client_fd_raw < 0) { + throw netio_exception("Unable to bind incoming client"); + } - if(client_fd_raw < 0) { - throw netio_exception("Unable to bind incoming client"); - } + fcntl(client_fd_raw, F_SETFL, fcntl(client_fd_raw, F_GETFL, 0) | O_NONBLOCK); - fcntl(client_fd_raw, F_SETFL, fcntl(client_fd_raw, F_GETFL, 0) | O_NONBLOCK); + const std::string address = inet_ntoa(client_addr.sin_addr); + const uint16_t port = ntohs(client_addr.sin_port); - const std::string address = inet_ntoa(client_addr.sin_addr); - const uint16_t port = ntohs(client_addr.sin_port); + // Generate client object from fd and announce it + this->number_of_connected_clients++; - // Generate client object from fd and announce it - this->number_of_connected_clients++; - using namespace std::placeholders; - this->client_listener(tcp_client(std::bind(&tcp_server_socket::client_destructed_cb, this, _1), auto_fd(client_fd_raw), address, port)); + using namespace std::placeholders; + this->client_listener(tcp_client(std::bind(&tcp_server_socket::client_destructed_cb, this, _1), auto_fd(client_fd_raw), address, port)); } int tcp_server_socket::get_number_of_connected_clients() const { - return this->number_of_connected_clients; + return this->number_of_connected_clients; } void tcp_server_socket::client_destructed_cb(exit_status_t exit_status) { - MARK_UNUSED(exit_status); + MARK_UNUSED(exit_status); - this->number_of_connected_clients--; + this->number_of_connected_clients--; } } diff --git a/src/net/tcp_server_socket.hpp b/src/net/tcp_server_socket.hpp index 212806d..c06c898 100644 --- a/src/net/tcp_server_socket.hpp +++ b/src/net/tcp_server_socket.hpp @@ -17,21 +17,23 @@ namespace rmrf::net { - class tcp_server_socket : public std::enable_shared_from_this<tcp_server_socket>{ public: - typedef std::function<void(tcp_client)> incoming_client_listener_type; + typedef std::function<void(tcp_client)> incoming_client_listener_type; + private: - async_server_socket::self_ptr_type ss; - incoming_client_listener_type client_listener; - std::atomic_uint32_t number_of_connected_clients; + async_server_socket::self_ptr_type ss; + incoming_client_listener_type client_listener; + std::atomic_uint32_t number_of_connected_clients; + public: - tcp_server_socket(const uint16_t port, incoming_client_listener_type client_listener_); - tcp_server_socket(const socketaddr& socket_identifier, incoming_client_listener_type client_listener_); - int get_number_of_connected_clients() const; + tcp_server_socket(const uint16_t port, incoming_client_listener_type client_listener_); + tcp_server_socket(const socketaddr& socket_identifier, incoming_client_listener_type client_listener_); + int get_number_of_connected_clients() const; + private: - void await_raw_socket_incomming(async_server_socket::self_ptr_type ass, const auto_fd& socket); - void client_destructed_cb(exit_status_t exit_status); + void await_raw_socket_incomming(async_server_socket::self_ptr_type ass, const auto_fd& socket); + void client_destructed_cb(exit_status_t exit_status); }; } diff --git a/src/test/loopback_connection_client.cpp b/src/test/loopback_connection_client.cpp index 80c825c..2002f59 100644 --- a/src/test/loopback_connection_client.cpp +++ b/src/test/loopback_connection_client.cpp @@ -10,33 +10,38 @@ #include <string.h> namespace rmrf::test { - loopback_connection_client::loopback_connection_client(rmrf::net::connection_client::incomming_data_cb mut_send_data_cb_) : - rmrf::net::connection_client{}, mut_send_data_cb(mut_send_data_cb_), send_data_archive{} { - // Does nothing special - } - - loopback_connection_client::~loopback_connection_client() { - // Also doesn't do anything fancy. - } - - void loopback_connection_client::write_data(const std::string& data) { - // TODO fixme - this->send_data_archive.push_back(data); - if(this->mut_send_data_cb != nullptr) { - this->mut_send_data_cb(data); - } - } - - void loopback_connection_client::send_data_to_incomming_data_cb(const std::string& data) { - if(this->in_data_cb != nullptr) { - this->in_data_cb(data); - } - } - - std::vector<std::string> loopback_connection_client::get_send_data() { - return this->send_data_archive; - } +loopback_connection_client::loopback_connection_client( + rmrf::net::connection_client::incomming_data_cb mut_send_data_cb_ +) : + rmrf::net::connection_client{}, + mut_send_data_cb(mut_send_data_cb_), + send_data_archive{} +{ + // Does nothing special } +loopback_connection_client::~loopback_connection_client() { + // Also doesn't do anything fancy. +} + +void loopback_connection_client::write_data(const std::string &data) { + // TODO fixme + this->send_data_archive.push_back(data); + if (this->mut_send_data_cb != nullptr) { + this->mut_send_data_cb(data); + } +} + +void loopback_connection_client::send_data_to_incomming_data_cb(const std::string &data) { + if (this->in_data_cb != nullptr) { + this->in_data_cb(data); + } +} + +std::vector<std::string> loopback_connection_client::get_send_data() { + return this->send_data_archive; +} + +} diff --git a/src/test/loopback_connection_client.hpp b/src/test/loopback_connection_client.hpp index 71b10dd..c75c678 100644 --- a/src/test/loopback_connection_client.hpp +++ b/src/test/loopback_connection_client.hpp @@ -11,6 +11,7 @@ #include "net/connection_client.hpp" + namespace rmrf::test { /** @@ -20,6 +21,7 @@ class loopback_connection_client : public rmrf::net::connection_client { private: const rmrf::net::connection_client::incomming_data_cb mut_send_data_cb; std::vector<std::string> send_data_archive; + public: /** * This constructor uses the given callback to notify the test suite that the module under test diff --git a/src/ui/event.cpp b/src/ui/event.cpp index 94c4005..8b7c071 100644 --- a/src/ui/event.cpp +++ b/src/ui/event.cpp @@ -2,8 +2,12 @@ namespace rmrf::ui { -event::event(const std::shared_ptr<ui_context> &sender) : event_sender(sender), handled(false) { -} +event::event( + const std::shared_ptr<ui_context> &sender +) : + event_sender(sender), + handled(false) +{} event::~event() { } diff --git a/src/ui/event.hpp b/src/ui/event.hpp index 057421c..ec362a7 100644 --- a/src/ui/event.hpp +++ b/src/ui/event.hpp @@ -15,6 +15,7 @@ class event { private: std::shared_ptr<ui_context> event_sender; bool handled; + public: /** * In order to construct an event one needs at least to specify @@ -23,17 +24,20 @@ public: * @param sender The source of the event. */ explicit event(const std::shared_ptr<ui_context> &sender); + /** * A class implementing an event also needs to make sure that * the special payload of the event is beeing taken care of. */ virtual ~event(); + /** * Use this methos in order to obtain the sender of this event. * * @return The sender */ std::shared_ptr<ui_context> get_sender() const; + /** * Use this function in order to get a human readable description * of the event. @@ -44,12 +48,14 @@ public: * @return A pointer to the description string */ std::shared_ptr<std::string> get_event_description() const; + /** * Use this function in order to check if the event has been handled yet. * * @return true if the event was already dealt with or otherwise false. */ bool has_been_handled() const; + /** * Call this function once the purpose of the event has been taken care of. */ diff --git a/src/ui/progress_indicator.hpp b/src/ui/progress_indicator.hpp index 62bec22..4f5321e 100644 --- a/src/ui/progress_indicator.hpp +++ b/src/ui/progress_indicator.hpp @@ -12,26 +12,31 @@ class progress_indicator { public: progress_indicator() {}; virtual ~progress_indicator() {}; + /** * Query the progress state * @return The current progress in percent */ virtual int get_progress() const; + /** * This method shall be used in order to obtain * the total amount of steps to be done. */ virtual int get_total_work() const; + /** * This method shall be used to retrieve the * current progress as a number of finished jobs. */ virtual int get_current_work() const; + /** * This method shall be used in order to obtain the * description of the total operation. */ virtual std::shared_ptr<std::string> get_operation_description() const; + /** * This method shall be used in order to retrieve a * description of the current step. diff --git a/src/ui/view.cpp b/src/ui/view.cpp index 1b23f5e..d9252fe 100644 --- a/src/ui/view.cpp +++ b/src/ui/view.cpp @@ -2,7 +2,12 @@ namespace rmrf::ui { -view::view(const std::shared_ptr<view> &parent) : parent_view{parent}, child_views{} { +view::view( + const std::shared_ptr<view> &parent +) : + parent_view{parent}, + child_views{} +{ if (this->parent_view) { this->parent_view->add_child(this->shared_from_this()); } diff --git a/src/ui/view.hpp b/src/ui/view.hpp index 0b417cb..de79151 100644 --- a/src/ui/view.hpp +++ b/src/ui/view.hpp @@ -18,9 +18,11 @@ class view : public ui_context, std::enable_shared_from_this<view> { private: std::shared_ptr<view> parent_view; std::list<std::shared_ptr<view>> child_views; + private: void add_child(const std::shared_ptr<view> &child); void remove_child(const std::shared_ptr<view> &child); + public: /** * This method will be called when an operation is taking place. It may add @@ -41,6 +43,7 @@ public: * @return True if rerendering is required or otherwise false. */ // virtual bool update(const std::shared_ptr<display> &display, const std::shared_ptr<event> &event); + /** * This method gets called when events need to be processed that do not * necessarily come from the UI thread. @@ -48,12 +51,14 @@ public: * @param event The event that caused the update. */ // virtual void schedule_update(const std::shared_ptr<event> &event); + /** * Use this method in order to retrieve the parent of this view. * @warn Keep in mind that this might be null. * @return The parent */ std::shared_ptr<view> get_parent() const; + /** * This constructor shall be capable of creating the view. * -- GitLab