#ifndef _NPT_SOCKETS_H_
#define _NPT_SOCKETS_H_
#include "NptTypes.h"
#include "NptConstants.h"
#include "NptStreams.h"
#include "NptStrings.h"
#include "NptDataBuffer.h"
#include "NptNetwork.h"
const int NPT_ERROR_CONNECTION_RESET = NPT_ERROR_BASE_SOCKET - 0;
const int NPT_ERROR_CONNECTION_ABORTED = NPT_ERROR_BASE_SOCKET - 1;
const int NPT_ERROR_CONNECTION_REFUSED = NPT_ERROR_BASE_SOCKET - 2;
const int NPT_ERROR_CONNECTION_FAILED = NPT_ERROR_BASE_SOCKET - 3;
const int NPT_ERROR_HOST_UNKNOWN = NPT_ERROR_BASE_SOCKET - 4;
const int NPT_ERROR_SOCKET_FAILED = NPT_ERROR_BASE_SOCKET - 5;
const int NPT_ERROR_GETSOCKOPT_FAILED = NPT_ERROR_BASE_SOCKET - 6;
const int NPT_ERROR_SETSOCKOPT_FAILED = NPT_ERROR_BASE_SOCKET - 7;
const int NPT_ERROR_SOCKET_CONTROL_FAILED = NPT_ERROR_BASE_SOCKET - 8;
const int NPT_ERROR_BIND_FAILED = NPT_ERROR_BASE_SOCKET - 9;
const int NPT_ERROR_LISTEN_FAILED = NPT_ERROR_BASE_SOCKET - 10;
const int NPT_ERROR_ACCEPT_FAILED = NPT_ERROR_BASE_SOCKET - 11;
const int NPT_ERROR_ADDRESS_IN_USE = NPT_ERROR_BASE_SOCKET - 12;
const int NPT_ERROR_NETWORK_DOWN = NPT_ERROR_BASE_SOCKET - 13;
const int NPT_ERROR_NETWORK_UNREACHABLE = NPT_ERROR_BASE_SOCKET - 14;
const int NPT_ERROR_NOT_CONNECTED = NPT_ERROR_BASE_SOCKET - 15;
const unsigned int NPT_SOCKET_FLAG_CANCELLABLE = 1;
class NPT_Socket;
class NPT_SocketAddress
{
public:
NPT_SocketAddress() : m_Port(0) {}
NPT_SocketAddress(const NPT_IpAddress& address, NPT_IpPort port) :
m_IpAddress(address),
m_Port(port) {}
NPT_Result SetIpAddress(const NPT_IpAddress& address) {
m_IpAddress = address;
return NPT_SUCCESS;
}
const NPT_IpAddress& GetIpAddress() const {
return m_IpAddress;
}
NPT_Result SetPort(NPT_IpPort port) {
m_Port = port;
return NPT_SUCCESS;
}
NPT_IpPort GetPort() const {
return m_Port;
}
NPT_String ToString() const;
bool operator==(const NPT_SocketAddress& other) const;
private:
NPT_IpAddress m_IpAddress;
NPT_IpPort m_Port;
};
typedef struct {
NPT_SocketAddress local_address;
NPT_SocketAddress remote_address;
} NPT_SocketInfo;
class NPT_SocketInterface
{
public:
virtual ~NPT_SocketInterface() {}
virtual NPT_Result Bind(const NPT_SocketAddress& address, bool reuse_address = true) = 0;
virtual NPT_Result Connect(const NPT_SocketAddress& address, NPT_Timeout timeout) = 0;
virtual NPT_Result WaitForConnection(NPT_Timeout timeout) = 0;
virtual NPT_Result GetInputStream(NPT_InputStreamReference& stream) = 0;
virtual NPT_Result GetOutputStream(NPT_OutputStreamReference& stream) = 0;
virtual NPT_Result GetInfo(NPT_SocketInfo& info) = 0;
virtual NPT_Result SetReadTimeout(NPT_Timeout timeout) = 0;
virtual NPT_Result SetWriteTimeout(NPT_Timeout timeout) = 0;
virtual NPT_Result Cancel(bool shutdown=true) = 0;
};
class NPT_UdpSocketInterface
{
public:
virtual ~NPT_UdpSocketInterface() {}
virtual NPT_Result Send(const NPT_DataBuffer& packet,
const NPT_SocketAddress* address = NULL) = 0;
virtual NPT_Result Receive(NPT_DataBuffer& packet,
NPT_SocketAddress* address = NULL) = 0;
};
class NPT_UdpMulticastSocketInterface
{
public:
virtual ~NPT_UdpMulticastSocketInterface() {}
virtual NPT_Result JoinGroup(const NPT_IpAddress& group,
const NPT_IpAddress& iface) = 0;
virtual NPT_Result LeaveGroup(const NPT_IpAddress& group,
const NPT_IpAddress& iface) = 0;
virtual NPT_Result SetTimeToLive(unsigned char ttl) = 0;
virtual NPT_Result SetInterface(const NPT_IpAddress& iface) = 0;
};
class NPT_TcpServerSocketInterface
{
public:
virtual ~NPT_TcpServerSocketInterface() {}
virtual NPT_Result Listen(unsigned int max_clients) = 0;
virtual NPT_Result WaitForNewClient(NPT_Socket*& client,
NPT_Timeout timeout,
NPT_Flags flags) = 0;
};
class NPT_Socket : public NPT_SocketInterface
{
public:
explicit NPT_Socket(NPT_SocketInterface* delegate) : m_SocketDelegate(delegate) {}
virtual ~NPT_Socket();
NPT_Result Bind(const NPT_SocketAddress& address, bool reuse_address = true) {
return m_SocketDelegate->Bind(address, reuse_address);
}
NPT_Result Connect(const NPT_SocketAddress& address,
NPT_Timeout timeout = NPT_TIMEOUT_INFINITE) {
return m_SocketDelegate->Connect(address, timeout);
}
NPT_Result WaitForConnection(NPT_Timeout timeout = NPT_TIMEOUT_INFINITE) {
return m_SocketDelegate->WaitForConnection(timeout);
}
NPT_Result GetInputStream(NPT_InputStreamReference& stream) {
return m_SocketDelegate->GetInputStream(stream);
}
NPT_Result GetOutputStream(NPT_OutputStreamReference& stream) {
return m_SocketDelegate->GetOutputStream(stream);
}
NPT_Result GetInfo(NPT_SocketInfo& info) {
return m_SocketDelegate->GetInfo(info);
}
NPT_Result SetReadTimeout(NPT_Timeout timeout) {
return m_SocketDelegate->SetReadTimeout(timeout);
}
NPT_Result SetWriteTimeout(NPT_Timeout timeout) {
return m_SocketDelegate->SetWriteTimeout(timeout);
}
NPT_Result Cancel(bool shutdown=true) {
return m_SocketDelegate->Cancel(shutdown);
}
protected:
NPT_Socket() {}
NPT_SocketInterface* m_SocketDelegate;
};
typedef NPT_Reference<NPT_Socket> NPT_SocketReference;
class NPT_UdpSocket : public NPT_Socket,
public NPT_UdpSocketInterface
{
public:
NPT_UdpSocket(NPT_Flags flags=NPT_SOCKET_FLAG_CANCELLABLE);
virtual ~NPT_UdpSocket();
NPT_Result Send(const NPT_DataBuffer& packet,
const NPT_SocketAddress* address = NULL) {
return m_UdpSocketDelegate->Send(packet, address);
}
NPT_Result Receive(NPT_DataBuffer& packet,
NPT_SocketAddress* address = NULL) {
return m_UdpSocketDelegate->Receive(packet, address);
}
protected:
NPT_UdpSocket(NPT_UdpSocketInterface* delegate);
NPT_UdpSocketInterface* m_UdpSocketDelegate;
};
class NPT_UdpMulticastSocket : public NPT_UdpSocket,
public NPT_UdpMulticastSocketInterface
{
public:
NPT_UdpMulticastSocket(NPT_Flags flags=NPT_SOCKET_FLAG_CANCELLABLE);
virtual ~NPT_UdpMulticastSocket();
NPT_Result JoinGroup(const NPT_IpAddress& group,
const NPT_IpAddress& iface =
NPT_IpAddress::Any) {
return m_UdpMulticastSocketDelegate->JoinGroup(group, iface);
}
NPT_Result LeaveGroup(const NPT_IpAddress& group,
const NPT_IpAddress& iface =
NPT_IpAddress::Any) {
return m_UdpMulticastSocketDelegate->LeaveGroup(group, iface);
}
NPT_Result SetTimeToLive(unsigned char ttl) {
return m_UdpMulticastSocketDelegate->SetTimeToLive(ttl);
}
NPT_Result SetInterface(const NPT_IpAddress& iface) {
return m_UdpMulticastSocketDelegate->SetInterface(iface);
}
protected:
NPT_UdpMulticastSocketInterface* m_UdpMulticastSocketDelegate;
};
class NPT_TcpClientSocket : public NPT_Socket
{
public:
NPT_TcpClientSocket(NPT_Flags flags=NPT_SOCKET_FLAG_CANCELLABLE);
virtual ~NPT_TcpClientSocket();
};
class NPT_TcpServerSocket : public NPT_Socket,
public NPT_TcpServerSocketInterface
{
public:
NPT_TcpServerSocket(NPT_Flags flags=NPT_SOCKET_FLAG_CANCELLABLE);
virtual ~NPT_TcpServerSocket();
NPT_Result Listen(unsigned int max_clients) {
return m_TcpServerSocketDelegate->Listen(max_clients);
}
NPT_Result WaitForNewClient(NPT_Socket*& client,
NPT_Timeout timeout = NPT_TIMEOUT_INFINITE,
NPT_Flags flags = 0) {
return m_TcpServerSocketDelegate->WaitForNewClient(client, timeout, flags);
}
protected:
NPT_TcpServerSocketInterface* m_TcpServerSocketDelegate;
};
#endif