//------------------------ CSPSockets.h -----------------------

//*************************************************************
//*****       Copyright ©2002 - 2004 Micronovae Ltd       *****
//*****                All rights reserved                *****
//*************************************************************


#ifndef _CSPSOCKETS
#define _CSPSOCKETS

#include "CSPConf.h"
#include "CSPLib.h"
#include "CSPBuffer.h"

#pragma comment(lib,"ws2_32.lib")

#define SOCK_RECEIVE_ERROR	0xFFFFFFFF
#define SOCK_SEND_ERROR	0xFFFFFFFF


class CSPTOOLS_CLASS_EXPORT CSPSocketAddress : public CSPObject
{
public:
	CSPSocketAddress();
	virtual ~CSPSocketAddress();

	const SOCKADDR& GetSocketAddress() const;
	void SetSocketAddress( SOCKADDR& Address );

protected:
	SOCKADDR m_sockaddr;
};


class CSPTOOLS_CLASS_EXPORT CSPIPSocketAddress : public CSPSocketAddress
{
public:
	CSPIPSocketAddress();
	virtual ~CSPIPSocketAddress();

	void SetIPAddress( unsigned char IPB1, unsigned char IPB2, unsigned char IPB3, unsigned char IPB4, unsigned short ushPort );
	void SetIPAddress( unsigned long ulIPAddress, unsigned short ushPort );
	bool SetIPAddressByName( const CSPString& strName, unsigned short ushPort );
	static unsigned long ResolveName( const CSPString& strName );
};


class CSPTOOLS_CLASS_EXPORT CSPSocket : public CSPObject
{
	friend class CSPServerSocket;
public:
	bool Wait( DWORD dwWaitTime = INFINITE ) const;
	unsigned long GetBytes( bool bWait = true ) const;
	operator SOCKET() const;
	operator HANDLE() const;
	HANDLE GetEventHandle() const;
	bool GetBlockingMode() const;
	void Disconnect();
	bool IsValid() const;

	bool Bind( const CSPSocketAddress& Address );
	virtual bool BindAny();

	bool Connect( const CSPSocketAddress& Address );

	virtual bool Receive( CSPBuffer& Data, unsigned long ulSize = 0 ) const;
	virtual bool Receive( void* pData, unsigned long ulSize ) const;
	virtual bool Send( const CSPBuffer& Data ) const;
	virtual bool Send( const void* pData, unsigned long ulSize ) const;

	bool SetBlockingMode( bool bMode );
	CSPSocket();
	virtual ~CSPSocket();

protected:
	bool m_bBlockingMode;
	SOCKET m_socket;
	mutable WSAOVERLAPPED m_Overlapped;
	bool m_bBound;
	mutable DWORD m_dwBytes;


	bool SetupSocket();
	virtual bool CreateSocket();
	bool SetSocket( SOCKET sSocket, bool bBlockingMode = true );
	unsigned long GetAsyncBytes( bool bWait = true ) const;

private:
	CSPSocket( const CSPSocket& );
	CSPSocket& operator = ( const CSPSocket& );
};


class CSPTOOLS_CLASS_EXPORT CSPTCPSocket : public CSPSocket
{
public:

	virtual bool BindAny( unsigned short ushPort );
	virtual bool BindAny();
	
	CSPTCPSocket();
	virtual ~CSPTCPSocket();

protected:
	virtual bool CreateSocket();

private:
	CSPTCPSocket( const CSPTCPSocket& );
	CSPTCPSocket& operator = ( const CSPTCPSocket& );
};


class CSPTOOLS_CLASS_EXPORT CSPServerSocket : public CSPObject
{
public:
	bool Wait( DWORD dwWaitTime = INFINITE ) const;		
	operator SOCKET() const;
	operator HANDLE() const;
	HANDLE GetEventHandle() const;
	bool GetBlockingMode() const;
	bool Bind( const CSPSocketAddress& Address );
	virtual bool BindAny();
	void Disconnect();
	bool Accept( CSPSocket& socSocket, CSPSocketAddress& Address ) const;
	bool Accept( CSPSocket& socSocket ) const;
	bool Listen( int iBackLog = SOMAXCONN );
	bool SetBlockingMode( bool bMode );
	CSPServerSocket();
	virtual ~CSPServerSocket();

protected:
	bool m_bBlockingMode;
	SOCKET m_socket;
	mutable WSAOVERLAPPED m_Overlapped;
	bool m_bBound;

	bool SetupSocket();
	virtual bool CreateSocket();

private:
	CSPServerSocket( const CSPServerSocket& );
	CSPServerSocket& operator = ( const CSPServerSocket& );
};


class CSPTOOLS_CLASS_EXPORT CSPTCPServerSocket : public CSPServerSocket
{
public:
	virtual bool BindAny( unsigned short ushPort );
	virtual bool BindAny();
	CSPTCPServerSocket();
	virtual ~CSPTCPServerSocket();

protected:
	virtual bool CreateSocket();

private:
	CSPTCPServerSocket( const CSPServerSocket& );
	CSPTCPServerSocket& operator = ( const CSPServerSocket& );
};


#endif
