diff options
| author | Dennis Brentjes <d.brentjes@gmail.com> | 2016-12-01 14:34:18 +0100 |
|---|---|---|
| committer | Dennis Brentjes <d.brentjes@gmail.com> | 2016-12-01 14:43:00 +0100 |
| commit | bc39d05453340257fff986edfdd728f2a89d13ad (patch) | |
| tree | 34fe208d1ccba0ae891dc23851352d3af6f7ee0f | |
| parent | 95283582a0392633974d1f3f67d5510a16eb104c (diff) | |
| download | cmix-bc39d05453340257fff986edfdd728f2a89d13ad.tar.gz cmix-bc39d05453340257fff986edfdd728f2a89d13ad.tar.bz2 cmix-bc39d05453340257fff986edfdd728f2a89d13ad.zip | |
Removed a large chunk of code duplication in the network code.
| -rw-r--r-- | libcmix-common/receiver.hpp | 58 | ||||
| -rw-r--r-- | libcmix-common/sender.hpp | 62 | ||||
| -rw-r--r-- | libcmix-common/senderreceiver.hpp | 80 | ||||
| -rw-r--r-- | libcmix-network/client.hpp | 31 | ||||
| -rw-r--r-- | libcmix-network/protobufclient.hpp | 77 |
5 files changed, 102 insertions, 206 deletions
diff --git a/libcmix-common/receiver.hpp b/libcmix-common/receiver.hpp index efd3753..ddb2826 100644 --- a/libcmix-common/receiver.hpp +++ b/libcmix-common/receiver.hpp @@ -7,56 +7,44 @@ /*! * \file */ -struct SenderReceiver; /*! - * \brief The Receiver struct is a shim around ProtobufClient and only exposes things needed - * for receiving messages. + * \brief BaseReceiver */ -struct Receiver : private ProtobufClient<CMixProtoFunctor> +template<template <typename T> class C, typename F> +struct BaseReceiver : private C<CMixProtoFunctor> { /*! * \brief friend decleration allowing Receivers to be upgraded to SenderReceivers. */ - friend SenderReceiver; + friend F; - using ProtobufClient::ProtobufClient; - using ProtobufClient::operator=; + using C<CMixProtoFunctor>::C; + using C<CMixProtoFunctor>::operator=; - using ProtobufClient::async_receive; + using C<CMixProtoFunctor>::async_receive; - using ProtobufClient::async_connect; + using C<CMixProtoFunctor>::async_connect; - using ProtobufClient::close; + using C<CMixProtoFunctor>::close; - using ProtobufClient::on_done; + using C<CMixProtoFunctor>::on_done; - using ProtobufClient::is_open; + using C<CMixProtoFunctor>::is_open; }; -struct SSLSenderReceiver; +/*! + * \brief Forward decleration the ability to convert Receivers to SenderReceivers. + */ +template <template <typename T> class C> +struct BaseSenderReceiver; /*! - * \brief The Receiver struct is a shim around ProtobufClient and only exposes things needed - * for receiving messages. + * \brief Conveniance typedef for Receiver. */ -struct SSLReceiver : private SSLProtobufClient<CMixProtoFunctor> -{ - /*! - * \brief friend decleration allowing Receivers to be upgraded to SenderReceivers. - */ - friend SSLSenderReceiver; - - using SSLProtobufClient::SSLProtobufClient; - using SSLProtobufClient::operator=; - - using SSLProtobufClient::async_receive; - - using SSLProtobufClient::async_connect; - - using SSLProtobufClient::close; - - using SSLProtobufClient::on_done; - - using SSLProtobufClient::is_open; -}; +using Receiver = BaseReceiver<ProtobufClient, BaseSenderReceiver<ProtobufClient>>; + +/*! + * \brief Conveniance typedef for SSLReceiver. + */ +using SSLReceiver = BaseReceiver<SSLProtobufClient, BaseSenderReceiver<SSLProtobufClient>>;
\ No newline at end of file diff --git a/libcmix-common/sender.hpp b/libcmix-common/sender.hpp index c722e30..d1baabe 100644 --- a/libcmix-common/sender.hpp +++ b/libcmix-common/sender.hpp @@ -9,61 +9,43 @@ */ /*! - * \brief forward declaration for SenderReceiver to allow for the friend declaration. + * \brief BaseSender */ -struct SenderReceiver; - -/*! - * \brief The Sender struct is a shim around ProtobufClient and only exposes things needed - * for sending messages. - */ -struct Sender : private ProtobufClient<CMixProtoFunctor> +template<template <typename T> class C, typename F> +struct BaseSender : private C<CMixProtoFunctor> { /*! * The friend declaration that allows for the Sender to be upgraded to a SenderReceiver. */ - friend SenderReceiver; + friend F; - using ProtobufClient::ProtobufClient; - using ProtobufClient::operator=; + using C<CMixProtoFunctor>::C; + using C<CMixProtoFunctor>::operator=; - using ProtobufClient::async_send; + using C<CMixProtoFunctor>::async_send; - using ProtobufClient::async_connect; + using C<CMixProtoFunctor>::async_connect; - using ProtobufClient::close; + using C<CMixProtoFunctor>::close; - using ProtobufClient::on_done; + using C<CMixProtoFunctor>::on_done; - using ProtobufClient::is_open; + using C<CMixProtoFunctor>::is_open; }; /*! - * \brief forward declaration for SenderReceiver to allow for the friend declaration. + * \brief forward declaration for BaseSenderReceiver to allow for the friend declaration. */ -struct SSLSenderReceiver; +template <template <typename T> class C> +struct BaseSenderReceiver; /*! - * \brief The Sender struct is a shim around ProtobufClient and only exposes things needed - * for sending messages. + * \brief Conveniance typedef for Sender */ -struct SSLSender : private SSLProtobufClient<CMixProtoFunctor> -{ - /*! - * The friend declaration that allows for the Sender to be upgraded to a SenderReceiver. - */ - friend SSLSenderReceiver; - - using SSLProtobufClient::SSLProtobufClient; - using SSLProtobufClient::operator=; - - using SSLProtobufClient::async_send; - - using SSLProtobufClient::async_connect; - - using SSLProtobufClient::close; - - using SSLProtobufClient::on_done; - - using SSLProtobufClient::is_open; -}; +using Sender = BaseSender<ProtobufClient, BaseSenderReceiver<ProtobufClient>>; + +/*! + * \brief Conveniance typedef for SSLSender + */ + +using SSLSender = BaseSender<SSLProtobufClient, BaseSenderReceiver<SSLProtobufClient>>;
\ No newline at end of file diff --git a/libcmix-common/senderreceiver.hpp b/libcmix-common/senderreceiver.hpp index 6654809..3514c7e 100644 --- a/libcmix-common/senderreceiver.hpp +++ b/libcmix-common/senderreceiver.hpp @@ -9,76 +9,54 @@ /*! * \file */ - + /*! - * \brief The SenderReciever struct is a shim around ProtobufClient and only exposes things needed - * for Sending and Receiving messages. + * \brief BaseSenderReceiver */ -struct SenderReceiver : private ProtobufClient<CMixProtoFunctor> -{ - /*! +template<template <typename T1> class C> +struct BaseSenderReceiver : private C<CMixProtoFunctor> { +/*! * \brief SenderReceiver Explicit conversion to SenderReceiver * \param r The Receiver to upgrade */ - explicit SenderReceiver(Receiver&& r) - : ProtobufClient(std::move(r)) + explicit BaseSenderReceiver(BaseReceiver<C, BaseSenderReceiver<C>>&& r) + : C<CMixProtoFunctor>(std::move(r)) {} - /*! - * \brief SenderReceiver Explicit conversion to SenderReceiver - * \param s The Sender to upgrade - */ - explicit SenderReceiver(Sender&& s) - : ProtobufClient(std::move(s)) - {} - - using ProtobufClient::ProtobufClient; - using ProtobufClient::operator=; - - using ProtobufClient::async_receive; - - using ProtobufClient::async_send; - - using ProtobufClient::async_connect; - - using ProtobufClient::close; - - using ProtobufClient::on_done; - - using ProtobufClient::is_open; -}; - -struct SSLSenderReceiver : private SSLProtobufClient<CMixProtoFunctor> -{ - /*! - * \brief SenderReceiver Explicit conversion to SenderReceiver - * \param r The Receiver to upgrade - */ - explicit SSLSenderReceiver(SSLReceiver&& r) - : SSLProtobufClient(std::move(r)) - {} /*! * \brief SenderReceiver Explicit conversion to SenderReceiver * \param s The Sender to upgrade */ - explicit SSLSenderReceiver(SSLSender&& s) - : SSLProtobufClient(std::move(s)) + explicit BaseSenderReceiver(BaseSender<C, BaseSenderReceiver<C>> && s) + : C<CMixProtoFunctor>(std::move(s)) {} - using SSLProtobufClient::SSLProtobufClient; - using SSLProtobufClient::operator=; - using SSLProtobufClient::async_receive; + using C<CMixProtoFunctor>::C; + using C<CMixProtoFunctor>::operator=; + + using C<CMixProtoFunctor>::async_receive; - using SSLProtobufClient::async_send; + using C<CMixProtoFunctor>::async_send; - using SSLProtobufClient::async_connect; + using C<CMixProtoFunctor>::async_connect; - using SSLProtobufClient::close; + using C<CMixProtoFunctor>::close; - using SSLProtobufClient::on_done; + using C<CMixProtoFunctor>::on_done; - using SSLProtobufClient::is_open; + using C<CMixProtoFunctor>::is_open; }; +/*! + * \brief Conveniance typedef for SenderReceiver + */ +using SenderReceiver = BaseSenderReceiver<ProtobufClient>; + +/*! + * \brief Conveniance typedef for SSLSenderReceiver + */ + +using SSLSenderReceiver = BaseSenderReceiver<SSLProtobufClient>; + diff --git a/libcmix-network/client.hpp b/libcmix-network/client.hpp index b43f32b..7b2b16f 100644 --- a/libcmix-network/client.hpp +++ b/libcmix-network/client.hpp @@ -23,11 +23,13 @@ */ /*! - * \brief The Client class + * \brief Forward decl for the friend decleration in BaseClient; */ - struct SSLClient; +/*! + * \brief The BaseClient class takes care of all ssl agnostic operations. + */ template <typename T> class BaseClient { friend SSLClient; @@ -209,25 +211,14 @@ public: } }; -struct Client : private BaseClient<boost::asio::ip::tcp::socket> { - - using BaseClient::BaseClient; - using BaseClient::operator=; - - using BaseClient::async_receive; - - using BaseClient::async_send; - - using BaseClient::async_connect; - - using BaseClient::close; - - using BaseClient::on_done; - - using BaseClient::is_open; - -}; +/*! + * \brief Conveniance wrapper around BaseClient for non SSL sockets. + */ +using Client = BaseClient<boost::asio::ip::tcp::socket>; +/*! + * \brief The SSLClient struct A wrapper around BaseClient that takes care of some of the SSL specific things. + */ struct SSLClient : private BaseClient<boost::asio::ssl::stream<boost::asio::ip::tcp::socket>> { using BaseClient::BaseClient; diff --git a/libcmix-network/protobufclient.hpp b/libcmix-network/protobufclient.hpp index df84152..15bcaec 100644 --- a/libcmix-network/protobufclient.hpp +++ b/libcmix-network/protobufclient.hpp @@ -20,14 +20,13 @@ * in to a desired wireformat to serialize and send or receive via the Client. * \tparam T The Protobuf functor to use when transforming messages. */ - -template <typename T> -class ProtobufClient : private Client +template <typename C, typename T> +class BaseProtobufClient : private C { public: - using Client::Client; - using Client::operator=; - using Client::async_connect; + using C::C; + using C::operator=; + using C::async_connect; /*! * \brief an async_send wrapper that transforms a specific message to the container message an sends it @@ -38,7 +37,7 @@ public: void async_send(V value, F on_sent) { typename T::proto_type m = T()(value); - Client::async_send(m.SerializeAsString(), on_sent); + C::async_send(m.SerializeAsString(), on_sent); } /*! @@ -65,61 +64,19 @@ public: } message_handler(message); }; - Client::async_receive(f); + C::async_receive(f); } - using Client::close; - using Client::on_done; - using Client::is_open; + using C::close; + using C::on_done; + using C::is_open; }; template <typename T> -class SSLProtobufClient : private SSLClient -{ -public: - using SSLClient::SSLClient; - using SSLClient::operator=; - using SSLClient::async_connect; - - /*! - * \brief an async_send wrapper that transforms a specific message to the container message an sends it - * \param value The specific message to send. - * \param on_sent The function to call after succesfully sending the message. - */ - template<typename V, typename F> - void async_send(V value, F on_sent) { - typename T::proto_type m = T()(value); - SSLClient::async_send(m.SerializeAsString(), on_sent); - } - - /*! - * \brief an async_send wrapper, like the above but without the on_sent callback. - * \param value The specific message to send. - */ - template<typename V> - void async_send(V value) { - async_send(value, []{}); - } - - /*! - * \brief An async_receive wrapper that transforms the wireformat to the protobuf - * container message type. - * \param message_handler The callback to call after receiving a message. - */ - template <typename F> - void async_receive(F message_handler) { - auto f = [message_handler](std::vector<uint8_t> const& buffer) { - typename T::proto_type message; - if(!message.ParseFromArray(buffer.data(), buffer.size())) { - BOOST_LOG_TRIVIAL(error) << "Received something which was not a CMixMessage"; - throw std::runtime_error("Network communication was disrupted in a unrecoverable way."); - } - message_handler(message); - }; - SSLClient::async_receive(f); - } - - using SSLClient::close; - using SSLClient::on_done; - using SSLClient::is_open; -}; +using ProtobufClient = BaseProtobufClient<Client, T>; + +/*! + * \brief The same as the ProtobufClient but for ssl_stream sockets. + */ +template <typename T> +using SSLProtobufClient = BaseProtobufClient<SSLClient, T>; |
