]> git.tdb.fi Git - libs/net.git/blobdiff - source/net/communicator.h
Prepare for assimilating msphttp
[libs/net.git] / source / net / communicator.h
diff --git a/source/net/communicator.h b/source/net/communicator.h
new file mode 100644 (file)
index 0000000..8530db1
--- /dev/null
@@ -0,0 +1,62 @@
+#ifndef MSP_NET_COMMUNICATOR_H_
+#define MSP_NET_COMMUNICATOR_H_
+
+#include "protocol.h"
+#include "streamsocket.h"
+
+namespace Msp {
+namespace Net {
+
+class sequence_error: public std::logic_error
+{
+public:
+       sequence_error(const std::string &w): std::logic_error(w) { }
+       virtual ~sequence_error() throw() { }
+};
+
+
+class Communicator
+{
+public:
+       sigc::signal<void> signal_handshake_done;
+
+private:
+       StreamSocket &socket;
+       const Protocol &protocol;
+       ReceiverBase &receiver;
+       int handshake_status;
+       unsigned buf_size;
+       char *in_buf;
+       char *in_begin;
+       char *in_end;
+       char *out_buf;
+       bool good;
+
+public:
+       Communicator(StreamSocket &, const Protocol &, ReceiverBase &);
+       ~Communicator();
+
+       void initiate_handshake();
+       bool is_handshake_done() const { return handshake_status==2; }
+
+       template<typename P>
+       void send(const P &pkt)
+       {
+               if(!good)
+                       throw sequence_error("connection aborted");
+               if(handshake_status!=2)
+                       throw sequence_error("handshaking not done");
+               unsigned size = protocol.assemble(pkt, out_buf, buf_size);
+               socket.write(out_buf, size);
+       }
+
+private:
+       void data_available();
+       bool receive_packet(const Protocol &, ReceiverBase &);
+       void send_handshake();
+};
+
+} // namespace Net
+} // namespace Msp
+
+#endif