]> git.tdb.fi Git - libs/net.git/blob - source/net/communicator.h
Massive overhaul of the Protocol class
[libs/net.git] / source / net / communicator.h
1 #ifndef MSP_NET_COMMUNICATOR_H_
2 #define MSP_NET_COMMUNICATOR_H_
3
4 #include "protocol.h"
5 #include "streamsocket.h"
6
7 namespace Msp {
8 namespace Net {
9
10 class sequence_error: public std::logic_error
11 {
12 public:
13         sequence_error(const std::string &w): std::logic_error(w) { }
14         virtual ~sequence_error() throw() { }
15 };
16
17
18 class Communicator
19 {
20 public:
21         sigc::signal<void> signal_handshake_done;
22         sigc::signal<void, const std::exception &> signal_error;
23
24 private:
25         StreamSocket &socket;
26         const Protocol &protocol;
27         ReceiverBase &receiver;
28         int handshake_status;
29         unsigned buf_size;
30         char *in_buf;
31         char *in_begin;
32         char *in_end;
33         char *out_buf;
34         bool good;
35
36 public:
37         Communicator(StreamSocket &, const Protocol &, ReceiverBase &);
38         ~Communicator();
39
40         void initiate_handshake();
41         bool is_handshake_done() const { return handshake_status==2; }
42
43         template<typename P>
44         void send(const P &pkt)
45         {
46                 if(!good)
47                         throw sequence_error("connection aborted");
48                 if(handshake_status!=2)
49                         throw sequence_error("handshaking not done");
50                 unsigned size = protocol.serialize(pkt, out_buf, buf_size);
51                 try
52                 {
53                         socket.write(out_buf, size);
54                 }
55                 catch(const std::exception &e)
56                 {
57                         good = false;
58                         if(signal_error.empty())
59                                 throw;
60                         signal_error.emit(e);
61                 }
62         }
63
64 private:
65         void data_available();
66         bool receive_packet(const Protocol &, ReceiverBase &);
67         void send_handshake();
68 };
69
70 } // namespace Net
71 } // namespace Msp
72
73 #endif