src/proto2/NetworkTCP.hh
author terom
Thu, 20 Nov 2008 20:27:12 +0000
branchno-netsession
changeset 37 ed2957490bbf
parent 36 785d220fc6b7
child 38 4189b8bf3a5b
permissions -rw-r--r--
compile step complete
#ifndef NETWORK_TCP_HH
#define NETWORK_TCP_HH

#include <ClanLib/core.h>

#include "NetworkSocket.hh"
#include "NetworkAddress.hh"
#include "NetworkPacket.hh"
#include "Error.hh"

const size_t NETWORK_TCP_CHUNK_SIZE = 1024;
const size_t NETWORK_TCP_INITIAL_IN_BUF = 4096;
const size_t NETWORK_TCP_INITIAL_OUT_BUF = 0;

class NetworkDisconnectError : public Error {
    public:
        NetworkDisconnectError (const std::string &message) : Error(message) { }
};

class NetworkBufferError : public Error {
    public:
        NetworkBufferError (const std::string &message) : Error(message) { }
};

class NetworkBuffer {
    private:
        NetworkSocket &socket;

        char *buf;
        size_t size, offset;
    
    public:
        NetworkBuffer (NetworkSocket &socket, size_t size_hint);
        ~NetworkBuffer (void);
    
    private:
        NetworkBuffer (const NetworkBuffer &copy);
        NetworkBuffer& operator= (const NetworkBuffer &copy);

        void resize (size_t item_size);
        void trim (size_t prefix_size);

    public:    
        void push_write (char *buf_ptr, size_t buf_size);
        void flush_write (void);
        template <typename PrefixType> void write_prefix (char *buf, PrefixType prefix);
        
        bool try_read (size_t item_size);
        bool peek_prefix (uint16_t &ref);
        bool peek_prefix (uint32_t &ref);
        template <typename PrefixType> PrefixType read_prefix (char *buf_ptr, size_t buf_max);
};

class NetworkTCPTransport {
    protected:
        NetworkSocket socket;

        NetworkBuffer in, out;
    
        CL_SlotContainer slots; 
    
    public:
        NetworkTCPTransport (NetworkSocket socket);

    private:
        void on_read (void);
        void on_write (void);
        void on_disconnected (void);

        CL_Signal_v1<const NetworkPacket &> _sig_packet;
        CL_Signal_v0 _sig_disconnect;

    public:
        NetworkAddress getRemoteAddress (void) { return socket.get_dest_address(); }

        void write_packet (const NetworkPacket &packet);
        
        CL_Signal_v1<const NetworkPacket&>& sig_packet (void) { return _sig_packet; }
        CL_Signal_v0& sig_disconnect (void) { return _sig_disconnect; }
};

class NetworkTCPServer {
    private:
        NetworkSocket socket;

        CL_SlotContainer slots; 

    public:
        NetworkTCPServer (const NetworkAddress &listen_addr);

    private:
        void on_accept (void);

        CL_Signal_v1<NetworkTCPTransport *> _sig_client;

    protected:
        virtual NetworkTCPTransport* buildTransport (CL_Socket &socket);

    public:
        CL_Signal_v1<NetworkTCPTransport *>& sig_client (void) { return _sig_client; }
};

class NetworkTCPClient : public NetworkTCPTransport {
    public:
        NetworkTCPClient (const NetworkAddress &connect_addr);
};

#endif /* NETWORK_TCP_HH */