#ifndef TOOLBOX_SOCKET_H
#define TOOLBOX_SOCKET_H

#include "cfileno.h"
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

class cTBSocket: public cTBFileNo {
private:
	struct sockaddr_in m_LocalAddr;
	struct sockaddr_in m_RemoteAddr;

protected:
	virtual ssize_t SysRead(void *Buffer, size_t Length);
	virtual ssize_t SysWrite(const void *Buffer, size_t Length);

public:
	cTBSocket(void);
	virtual ~cTBSocket();

	virtual bool Connect(const char *Host, unsigned int Port);

	virtual bool Listen(unsigned int Port, int BackLog);
	virtual cTBSocket *Accept(void);

	virtual bool Shutdown(int how);

	virtual bool Close(void);

	virtual int LocalPort(void) const { return ntohs(m_LocalAddr.sin_port); }
	virtual int RemotePort(void) const { return ntohs(m_RemoteAddr.sin_port); }

	virtual const char *LocalIp(void) const 
			{ return inet_ntoa(m_LocalAddr.sin_addr); }
	virtual const char *RemoteIp(void) const 
			{ return inet_ntoa(m_RemoteAddr.sin_addr); }
};

inline ssize_t cTBSocket::SysRead(void *Buffer, size_t Length) {
	return ::recv(FileNo(), Buffer, Length, 0);
}

inline ssize_t cTBSocket::SysWrite(const void *Buffer, size_t Length) {
	return ::send(FileNo(), Buffer, Length, 0);
}

#endif // TOOLBOX_SOCKET_H
