#ifndef __SOCKET_H__
#define __SOCKET_H__
#ifndef SOCKET_ERROR
#define SOCKET_ERROR (-1)
#endif
#ifndef MSG_NOSIGNAL
#define MSG_NOSIGNAL 0
#endif
#ifndef WSAECONNRESET
#define WSAECONNRESET 10054L
#endif
#ifndef EPIPE
#define EPIPE 32
#endif
#define CASC_PORT_HTTP 80
#define CASC_PORT_RIBBIT 1119
typedef class CASC_SOCKET_CACHE * PCASC_SOCKET_CACHE;
typedef class CASC_SOCKET * PCASC_SOCKET;
typedef struct addrinfo * PADDRINFO;
class CASC_SOCKET
{
public:
char * ReadResponse(const char * request, size_t request_length, CASC_MIME_RESPONSE & MimeResponse);
DWORD AddRef();
void Release();
private:
static int GetSockError();
static DWORD GetAddrInfoWrapper(const char * hostName, unsigned portNum, PADDRINFO hints, PADDRINFO * ppResult);
static HANDLE CreateAndConnect(PADDRINFO remoteItem);
static HANDLE ReconnectAfterShutdown(HANDLE & sock, PADDRINFO remoteItem);
static PCASC_SOCKET New(PADDRINFO remoteList, PADDRINFO remoteItem, const char * hostName, unsigned portNum, HANDLE sock);
static PCASC_SOCKET Connect(const char * hostName, unsigned portNum);
void Delete();
friend CASC_SOCKET * sockets_connect(const char * hostName, unsigned portNum);
friend char * sockets_read_response(PCASC_SOCKET pSocket, const char * request, size_t request_length, size_t * PtrLength);
friend class CASC_SOCKET_CACHE;
PCASC_SOCKET_CACHE pCache; PCASC_SOCKET pPrev; PCASC_SOCKET pNext; PADDRINFO remoteList; PADDRINFO remoteItem; CASC_LOCK Lock; HANDLE sock; DWORD dwRefCount; DWORD portNum; char hostName[1]; };
class CASC_SOCKET_CACHE
{
public:
CASC_SOCKET_CACHE();
~CASC_SOCKET_CACHE();
PCASC_SOCKET Find(const char * hostName, unsigned portNum);
PCASC_SOCKET InsertSocket(PCASC_SOCKET pSocket);
void UnlinkSocket(PCASC_SOCKET pSocket);
void SetCaching(bool bAddRef);
void PurgeAll();
private:
PCASC_SOCKET pFirst;
PCASC_SOCKET pLast;
DWORD dwRefCount;
};
PCASC_SOCKET sockets_connect(const char * hostName, unsigned portNum);
void sockets_set_caching(bool caching);
#endif