#ifndef SOCOPCLI_MASTER_HPP_INCLUDED
#define SOCOPCLI_MASTER_HPP_INCLUDED
#include "gate/interfaces/socop.hpp"
#include "gate/net/sockets.hpp"
#include "gate/wrappers.hpp"
#include "gate/maps.hpp"
#include "gate/synchronization.hpp"
#include "gate/atomics.hpp"
#include "gate/streams.hpp"
#include "gate/threading.hpp"
class GATE_API_LOCAL SocopMaster : public SocopDriver, public SocopServer, public gate::IRunnable
{
public:
SocopMaster() noexcept;
virtual ~SocopMaster() noexcept;
bool start(gate::Stream& strm) noexcept;
bool stop() noexcept;
bool isStarted() noexcept;
protected: // implementation of SocopDriver
virtual Socop::Result do_read(unsigned char& received_byte, bool want_more);
virtual Socop::Result do_write(unsigned char byte_to_send, bool send_more);
protected: // implementation of SocopServer
virtual Socop::Result on_reset();
virtual Socop::Result on_net_status();
virtual Socop::Result on_net_start(char const* parameter, unsigned parameter_length);
virtual Socop::Result on_net_stop();
virtual Socop::Result on_connect(Address const& addr, Socket& new_sock);
virtual Socop::Result on_bind(Address const& addr, Socket& new_sock);
virtual Socop::Result on_listen(Address const& addr, Socket& new_sock);
virtual Socop::Result on_accept(Socket listen_sock, Socket& new_sock);
virtual Socop::Result on_close(Socket sock);
virtual Socop::Result on_receive(Socket sock, void* buffer, unsigned buffer_length, unsigned& buffer_used);
virtual Socop::Result on_receive_from(Socket sock, void* buffer, unsigned buffer_length, unsigned& buffer_used, Address& addr);
virtual Socop::Result on_send(Socket sock, void const* buffer, unsigned buffer_length, unsigned& buffer_sent);
virtual Socop::Result on_send_to(Socket sock, void const* buffer, unsigned buffer_length, unsigned& buffer_sent, Address const& addr);
virtual Socop::Result on_shutdown(Socket sock, unsigned flags);
virtual Socop::Result on_select(Socket sock, unsigned& flags);
virtual Socop::Result on_peer(Socket sock);
virtual Socop::Result on_iocontrol(Socket sock);
protected:
virtual void run();
public:
struct Resource
{
Socop::Socket id;
gate::net::Socket native;
Resource(gate::net::Socket::SocketTypeEnum type);<--- Struct 'Resource' has a constructor with 1 argument that is not explicit. [+]Struct 'Resource' has a constructor with 1 argument that is not explicit. Such constructors should in general be explicit for type safety reasons. Using the explicit keyword in the constructor means some mistakes when using the class can be avoided.
};
typedef gate::Ref<Resource> ResourceRef;
private:
gate::AtomicInt server_state;
gate::Thread server_thread;
gate::Stream server_stream;
gate::Mutex res_mutex;
gate::AtomicInt next_sock_id;
typedef gate::Map<Socop::Socket, ResourceRef> ResourceMap;
ResourceMap tcp_clients;
ResourceMap tcp_servers;
ResourceMap udp_sockets;
private:
Socop::Socket get_next_socket_id();
ResourceRef find_resource(Socop::Socket sock_id);
};
#endif