#ifndef MSP_NET_COMMUNICATOR_H_
#define MSP_NET_COMMUNICATOR_H_
+#include <msp/core/except.h>
+#include <sigc++/signal.h>
#include "protocol.h"
-#include "streamsocket.h"
namespace Msp {
namespace Net {
-class sequence_error: public std::logic_error
+class StreamSocket;
+
+class sequence_error: public invalid_state
+{
+public:
+ sequence_error(const std::string &w): invalid_state(w) { }
+};
+
+class incompatible_protocol: public std::runtime_error
{
public:
- sequence_error(const std::string &w): std::logic_error(w) { }
- virtual ~sequence_error() throw() { }
+ incompatible_protocol(const std::string &w): std::runtime_error(w) { }
};
{
public:
sigc::signal<void> signal_handshake_done;
+ sigc::signal<void, const std::exception &> signal_error;
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;
+ int handshake_status = 0;
+ std::size_t buf_size = 65536;
+ char *in_buf = nullptr;
+ char *in_begin = nullptr;
+ char *in_end = nullptr;
+ char *out_buf = nullptr;
+ bool good = true;
public:
Communicator(StreamSocket &, const Protocol &, ReceiverBase &);
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);
- }
+ void send(const P &);
private:
+ void send_data(std::size_t);
+
void data_available();
bool receive_packet(const Protocol &, ReceiverBase &);
void send_handshake();
};
+template<typename P>
+void Communicator::send(const P &pkt)
+{
+ send_data(protocol.serialize(pkt, out_buf, buf_size));
+}
+
} // namespace Net
} // namespace Msp