1 #ifndef MSP_NET_COMMUNICATOR_H_
2 #define MSP_NET_COMMUNICATOR_H_
4 #include <msp/core/except.h>
5 #include <msp/core/noncopyable.h>
6 #include <sigc++/signal.h>
7 #include "mspnet_api.h"
15 class MSPNET_API sequence_error: public invalid_state
18 sequence_error(const std::string &w): invalid_state(w) { }
21 class MSPNET_API incompatible_protocol: public std::runtime_error
24 incompatible_protocol(const std::string &w): std::runtime_error(w) { }
28 class MSPNET_API Communicator: public NonCopyable
31 sigc::signal<void, const Protocol &> signal_protocol_ready;
32 sigc::signal<void, const std::exception &> signal_error;
37 std::uint64_t hash = 0;
38 std::uint16_t base = 0;
39 std::uint16_t last = 0;
40 bool accepted = false;
42 const Protocol *protocol = nullptr;
43 ReceiverBase *receiver = nullptr;
45 ActiveProtocol(std::uint16_t, const Protocol &, ReceiverBase &);
46 ActiveProtocol(std::uint16_t, std::uint64_t);
52 std::vector<ActiveProtocol> protocols;
53 Handshake *handshake = nullptr;
54 std::size_t buf_size = 65536;
55 char *in_buf = nullptr;
56 char *in_begin = nullptr;
57 char *in_end = nullptr;
58 char *out_buf = nullptr;
62 Communicator(StreamSocket &);
63 Communicator(StreamSocket &, const Protocol &, ReceiverBase &);
66 void add_protocol(const Protocol &, ReceiverBase &);
67 bool is_protocol_ready(const Protocol &) const;
73 void send_data(std::size_t);
75 void connect_finished(const std::exception *);
76 void data_available();
77 bool receive_packet();
79 void prepare_protocol(const ActiveProtocol &);
80 void accept_protocol(ActiveProtocol &);
84 void Communicator::send(const P &pkt)
86 auto i = find_if(protocols, [](const ActiveProtocol &p){ return p.protocol && p.protocol->has_packet<P>(); });
87 if(i==protocols.end())
88 throw key_error(typeid(P).name());
90 throw sequence_error("protocol not ready");
91 send_data(i->protocol->serialize(pkt, out_buf, buf_size, i->base));