/*-------------------------------------------------------------------------
 * drawElements Utility Library
 * ----------------------------
 *
 * Copyright 2014 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 *//*!
 * \file
 * \brief Socket abstraction.
 *//*--------------------------------------------------------------------*/

#include "deSocket.h"
#include "deMemory.h"
#include "deMutex.h"
#include "deInt32.h"

#if (DE_OS == DE_OS_WIN32)
#	define DE_USE_WINSOCK
#elif (DE_OS == DE_OS_UNIX) || (DE_OS == DE_OS_OSX) || (DE_OS == DE_OS_IOS) || (DE_OS == DE_OS_ANDROID) || (DE_OS == DE_OS_SYMBIAN) || (DE_OS == DE_OS_QNX) || (DE_OS == DE_OS_FUCHSIA)
#	define DE_USE_BERKELEY_SOCKETS
#else
#	error Implement deSocket for your OS.
#endif

/* Common utilities. */

const char* deGetSocketResultName (deSocketResult result)
{
	switch (result)
	{
		case DE_SOCKETRESULT_SUCCESS:				return "DE_SOCKETRESULT_SUCCESS";
		case DE_SOCKETRESULT_WOULD_BLOCK:			return "DE_SOCKETRESULT_WOULD_BLOCK";
		case DE_SOCKETRESULT_CONNECTION_CLOSED:		return "DE_SOCKETRESULT_CONNECTION_CLOSED";
		case DE_SOCKETRESULT_CONNECTION_TERMINATED:	return "DE_SOCKETRESULT_CONNECTION_TERMINATED";
		case DE_SOCKETRESULT_ERROR:					return "DE_SOCKETRESULT_ERROR";
		default:									return DE_NULL;
	}
}

const char* deGetSocketFamilyName (deSocketFamily family)
{
	switch (family)
	{
		case DE_SOCKETFAMILY_INET4:		return "DE_SOCKETFAMILY_INET4";
		case DE_SOCKETFAMILY_INET6:		return "DE_SOCKETFAMILY_INET6";
		default:						return DE_NULL;
	}
}

#if defined(DE_USE_WINSOCK) || defined(DE_USE_BERKELEY_SOCKETS)

/* Common deSocketAddress implementation. */

struct deSocketAddress_s
{
	char*				host;
	int					port;
	deSocketFamily		family;
	deSocketType		type;
	deSocketProtocol	protocol;
};

deSocketAddress* deSocketAddress_create (void)
{
	deSocketAddress* addr = (deSocketAddress*)deCalloc(sizeof(deSocketAddress));
	if (!addr)
		return addr;

	/* Sane defaults. */
	addr->family	= DE_SOCKETFAMILY_INET4;
	addr->type		= DE_SOCKETTYPE_STREAM;
	addr->protocol	= DE_SOCKETPROTOCOL_TCP;

	return addr;
}

deBool deSocketAddress_setFamily (deSocketAddress* address, deSocketFamily family)
{
	address->family = family;
	return DE_TRUE;
}

deSocketFamily deSocketAddress_getFamily (const deSocketAddress* address)
{
	return address->family;
}

void deSocketAddress_destroy (deSocketAddress* address)
{
	deFree(address->host);
	deFree(address);
}

deBool deSocketAddress_setPort (deSocketAddress* address, int port)
{
	address->port = port;
	return DE_TRUE;
}

int deSocketAddress_getPort (const deSocketAddress* address)
{
	return address->port;
}

deBool deSocketAddress_setHost (deSocketAddress* address, const char* host)
{
	if (address->host)
	{
		deFree(address->host);
		address->host = DE_NULL;
	}

	address->host = deStrdup(host);
	return address->host != DE_NULL;
}

const char* deSocketAddress_getHost (const deSocketAddress* address)
{
	return address->host;
}


deBool deSocketAddress_setType (deSocketAddress* address, deSocketType type)
{
	address->type = type;
	return DE_TRUE;
}

deSocketType deSocketAddress_getType (const deSocketAddress* address)
{
	return address->type;
}

deBool deSocketAddress_setProtocol (deSocketAddress* address, deSocketProtocol protocol)
{
	address->protocol = protocol;
	return DE_TRUE;
}

deSocketProtocol deSocketAddress_getProtocol (const deSocketAddress* address)
{
	return address->protocol;
}

#endif

#if defined(DE_USE_WINSOCK)

	/* WinSock spesific. */
#	include <WinSock2.h>
#	include <WS2tcpip.h>
#	include <WinDef.h>

static deBool initWinsock (void)
{
	WSADATA wsaData;
	if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
		return DE_FALSE;

	return DE_TRUE;
}

#elif defined(DE_USE_BERKELEY_SOCKETS)

	/* Berkeley Socket includes. */
#	include <sys/socket.h>
#	include <netinet/in.h>
#	include <netinet/tcp.h>
#	include <arpa/inet.h>
#	include <netdb.h>
#	include <unistd.h>
#	include <fcntl.h>
#	include <errno.h>

#endif

/* Socket type. */
#if defined(DE_USE_WINSOCK)
	/* \note SOCKET is unsigned type! */
	typedef SOCKET					deSocketHandle;
	typedef int						NativeSocklen;
	typedef int						NativeSize;
#	define DE_INVALID_SOCKET_HANDLE	INVALID_SOCKET
#else
	typedef int						deSocketHandle;
	typedef socklen_t				NativeSocklen;
	typedef size_t					NativeSize;
#	define DE_INVALID_SOCKET_HANDLE	(-1)
#endif

DE_INLINE deBool deSocketHandleIsValid (deSocketHandle handle)
{
	return handle != DE_INVALID_SOCKET_HANDLE;
}

#if defined(DE_USE_WINSOCK) || defined(DE_USE_BERKELEY_SOCKETS)

/* Shared berkeley and winsock implementation. */

struct deSocket_s
{
	deSocketHandle			handle;

	deMutex					stateLock;
	volatile deSocketState	state;
	volatile deUint32		openChannels;
};

/* Common socket functions. */

static deUint16 deHostToNetworkOrder16 (deUint16 v)
{
#if (DE_ENDIANNESS == DE_LITTLE_ENDIAN)
	return deReverseBytes16(v);
#else
	return v;
#endif
}

static deUint16 deNetworkToHostOrder16 (deUint16 v)
{
#if (DE_ENDIANNESS == DE_LITTLE_ENDIAN)
	return deReverseBytes16(v);
#else
	return v;
#endif
}

DE_STATIC_ASSERT(sizeof(((struct sockaddr_in*)DE_NULL)->sin_port) == sizeof(deUint16));
DE_STATIC_ASSERT(sizeof(((struct sockaddr_in6*)DE_NULL)->sin6_port) == sizeof(deUint16));

static int deSocketFamilyToBsdFamily (deSocketFamily family)
{
	switch (family)
	{
		case DE_SOCKETFAMILY_INET4:	return AF_INET;
		case DE_SOCKETFAMILY_INET6:	return AF_INET6;
		default:
			DE_ASSERT(DE_FALSE);
			return 0;
	}
}

static int deSocketTypeToBsdType (deSocketType type)
{
	switch (type)
	{
		case DE_SOCKETTYPE_STREAM:		return SOCK_STREAM;
		case DE_SOCKETTYPE_DATAGRAM:	return SOCK_DGRAM;
		default:
			DE_ASSERT(DE_FALSE);
			return 0;
	}
}

static int deSocketProtocolToBsdProtocol (deSocketProtocol protocol)
{
	switch (protocol)
	{
		case DE_SOCKETPROTOCOL_TCP:	return IPPROTO_TCP;
		case DE_SOCKETPROTOCOL_UDP:	return IPPROTO_UDP;
		default:
			DE_ASSERT(DE_FALSE);
			return 0;
	}
}

static deBool deSocketAddressToBsdAddress (const deSocketAddress* address, size_t bsdAddrBufSize, struct sockaddr* bsdAddr, NativeSocklen* bsdAddrLen)
{
	deMemset(bsdAddr, 0, bsdAddrBufSize);

	/* Resolve host. */
	if (address->host != DE_NULL)
	{
		struct addrinfo*	result	= DE_NULL;
		struct addrinfo		hints;

		deMemset(&hints, 0, sizeof(hints));
		hints.ai_family		= deSocketFamilyToBsdFamily(address->family);
		hints.ai_socktype	= deSocketTypeToBsdType(address->type);
		hints.ai_protocol	= deSocketProtocolToBsdProtocol(address->protocol);

		if (getaddrinfo(address->host, DE_NULL, &hints, &result) != 0 || !result)
		{
			if (result)
				freeaddrinfo(result);
			return DE_FALSE;
		}

		/* \note Always uses first address. */

		if (bsdAddrBufSize < (size_t)result->ai_addrlen)
		{
			DE_FATAL("Too small bsdAddr buffer");
			freeaddrinfo(result);
			return DE_FALSE;
		}

		*bsdAddrLen	= (NativeSocklen)result->ai_addrlen;

		deMemcpy(bsdAddr, result->ai_addr, (size_t)result->ai_addrlen);
		freeaddrinfo(result);

		/* Add port. */
		if (bsdAddr->sa_family == AF_INET)
		{
			if (*bsdAddrLen < (NativeSocklen)sizeof(struct sockaddr_in))
				return DE_FALSE;
			((struct sockaddr_in*)bsdAddr)->sin_port = deHostToNetworkOrder16((deUint16)address->port);
		}
		else if (bsdAddr->sa_family == AF_INET6)
		{
			if (*bsdAddrLen < (NativeSocklen)sizeof(struct sockaddr_in6))
				return DE_FALSE;
			((struct sockaddr_in6*)bsdAddr)->sin6_port = deHostToNetworkOrder16((deUint16)address->port);
		}
		else
			return DE_FALSE;

		return DE_TRUE;
	}
	else if (address->family == DE_SOCKETFAMILY_INET4)
	{
		struct sockaddr_in* addr4 = (struct sockaddr_in*)bsdAddr;

		if (bsdAddrBufSize < sizeof(struct sockaddr_in))
		{
			DE_FATAL("Too small bsdAddr buffer");
			return DE_FALSE;
		}

		addr4->sin_port			= deHostToNetworkOrder16((deUint16)address->port);
		addr4->sin_family		= AF_INET;
		addr4->sin_addr.s_addr	= INADDR_ANY;

		*bsdAddrLen	= (NativeSocklen)sizeof(struct sockaddr_in);

		return DE_TRUE;
	}
	else if (address->family == DE_SOCKETFAMILY_INET6)
	{
		struct sockaddr_in6* addr6 = (struct sockaddr_in6*)bsdAddr;

		if (bsdAddrBufSize < sizeof(struct sockaddr_in6))
		{
			DE_FATAL("Too small bsdAddr buffer");
			return DE_FALSE;
		}

		addr6->sin6_port	= deHostToNetworkOrder16((deUint16)address->port);
		addr6->sin6_family	= AF_INET6;

		*bsdAddrLen	= (NativeSocklen)sizeof(struct sockaddr_in6);

		return DE_TRUE;
	}
	else
		return DE_FALSE;
}

void deBsdAddressToSocketAddress (deSocketAddress* address, const struct sockaddr* bsdAddr, int addrLen)
{
	/* Decode client address info. */
	if (bsdAddr->sa_family == AF_INET)
	{
		const struct sockaddr_in* addr4 = (const struct sockaddr_in*)bsdAddr;
		DE_ASSERT(addrLen >= (int)sizeof(struct sockaddr_in));
		DE_UNREF(addrLen);

		deSocketAddress_setFamily(address, DE_SOCKETFAMILY_INET4);
		deSocketAddress_setPort(address, (int)deNetworkToHostOrder16((deUint16)addr4->sin_port));

		{
			char buf[16]; /* Max valid address takes 3*4 + 3 = 15 chars */
			inet_ntop(AF_INET, (void*)&addr4->sin_addr, buf, sizeof(buf));
			deSocketAddress_setHost(address, buf);
		}
	}
	else if (bsdAddr->sa_family == AF_INET6)
	{
		const struct sockaddr_in6* addr6 = (const struct sockaddr_in6*)bsdAddr;
		DE_ASSERT(addrLen >= (int)sizeof(struct sockaddr_in6));
		DE_UNREF(addrLen);

		deSocketAddress_setFamily(address, DE_SOCKETFAMILY_INET6);
		deSocketAddress_setPort(address, (int)deNetworkToHostOrder16((deUint16)addr6->sin6_port));

		{
			char buf[40]; /* Max valid address takes 8*4 + 7 = 39 chars */
			inet_ntop(AF_INET6, (void*)&addr6->sin6_addr, buf, sizeof(buf));
			deSocketAddress_setHost(address, buf);
		}
	}
	else
		DE_ASSERT(DE_FALSE);
}

deSocket* deSocket_create (void)
{
	deSocket* sock = (deSocket*)deCalloc(sizeof(deSocket));
	if (!sock)
		return sock;

#if defined(DE_USE_WINSOCK)
	/* Make sure WSA is up. */
	if (!initWinsock())
		return DE_NULL;
#endif

	sock->stateLock	= deMutex_create(0);
	sock->handle	= DE_INVALID_SOCKET_HANDLE;
	sock->state		= DE_SOCKETSTATE_CLOSED;

	return sock;
}

void deSocket_destroy (deSocket* sock)
{
	if (sock->state != DE_SOCKETSTATE_CLOSED)
		deSocket_close(sock);

	deMutex_destroy(sock->stateLock);
	deFree(sock);
}

deSocketState deSocket_getState (const deSocket* sock)
{
	return sock->state;
}

deUint32 deSocket_getOpenChannels (const deSocket* sock)
{
	return sock->openChannels;
}

deBool deSocket_setFlags (deSocket* sock, deUint32 flags)
{
	deSocketHandle fd = sock->handle;

	if (sock->state == DE_SOCKETSTATE_CLOSED)
		return DE_FALSE;

	/* Keepalive. */
	{
		int mode = (flags & DE_SOCKET_KEEPALIVE) ? 1 : 0;
		if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (const char*)&mode, sizeof(mode)) != 0)
			return DE_FALSE;
	}

	/* Nodelay. */
	{
		int mode = (flags & DE_SOCKET_NODELAY) ? 1 : 0;
		if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (const char*)&mode, sizeof(mode)) != 0)
			return DE_FALSE;
	}

	/* Non-blocking. */
	{
#if defined(DE_USE_WINSOCK)
		u_long mode = (flags & DE_SOCKET_NONBLOCKING) ? 1 : 0;
		if (ioctlsocket(fd, FIONBIO, &mode) != 0)
			return DE_FALSE;
#else
		int oldFlags	= fcntl(fd, F_GETFL, 0);
		int newFlags	= (flags & DE_SOCKET_NONBLOCKING) ? (oldFlags | O_NONBLOCK) : (oldFlags & ~O_NONBLOCK);
		if (fcntl(fd, F_SETFL, newFlags) != 0)
			return DE_FALSE;
#endif
	}

	/* Close on exec. */
	{
#if defined(DE_USE_BERKELEY_SOCKETS)
		int oldFlags = fcntl(fd, F_GETFD, 0);
		int newFlags = (flags & DE_SOCKET_CLOSE_ON_EXEC) ? (oldFlags | FD_CLOEXEC) : (oldFlags & ~FD_CLOEXEC);
		if (fcntl(fd, F_SETFD, newFlags) != 0)
			return DE_FALSE;
#endif
	}

	return DE_TRUE;
}

deBool deSocket_listen (deSocket* sock, const deSocketAddress* address)
{
	const int			backlogSize	= 4;
	deUint8				bsdAddrBuf[sizeof(struct sockaddr_in6)];
	struct sockaddr*	bsdAddr		= (struct sockaddr*)&bsdAddrBuf[0];
	NativeSocklen		bsdAddrLen;

	if (sock->state != DE_SOCKETSTATE_CLOSED)
		return DE_FALSE;

	/* Resolve address. */
	if (!deSocketAddressToBsdAddress(address, sizeof(bsdAddrBuf), bsdAddr, &bsdAddrLen))
		return DE_FALSE;

	/* Create socket. */
	sock->handle = socket(bsdAddr->sa_family, deSocketTypeToBsdType(address->type), deSocketProtocolToBsdProtocol(address->protocol));
	if (!deSocketHandleIsValid(sock->handle))
		return DE_FALSE;

	sock->state = DE_SOCKETSTATE_DISCONNECTED;

	/* Allow re-using address. */
	{
		int reuseVal = 1;
		setsockopt(sock->handle, SOL_SOCKET, SO_REUSEADDR, (const char*)&reuseVal, (int)sizeof(reuseVal));
	}

	/* Bind to address. */
	if (bind(sock->handle, bsdAddr, (NativeSocklen)bsdAddrLen) != 0)
	{
		deSocket_close(sock);
		return DE_FALSE;
	}

	/* Start listening. */
	if (listen(sock->handle, backlogSize) != 0)
	{
		deSocket_close(sock);
		return DE_FALSE;
	}

	sock->state = DE_SOCKETSTATE_LISTENING;

	return DE_TRUE;
}

deSocket* deSocket_accept (deSocket* sock, deSocketAddress* clientAddress)
{
	deSocketHandle		newFd		= DE_INVALID_SOCKET_HANDLE;
	deSocket*			newSock		= DE_NULL;
	deUint8				bsdAddrBuf[sizeof(struct sockaddr_in6)];
	struct sockaddr*	bsdAddr		= (struct sockaddr*)&bsdAddrBuf[0];
	NativeSocklen		bsdAddrLen	= (NativeSocklen)sizeof(bsdAddrBuf);

	deMemset(bsdAddr, 0, (size_t)bsdAddrLen);

	newFd = accept(sock->handle, bsdAddr, &bsdAddrLen);
	if (!deSocketHandleIsValid(newFd))
		return DE_NULL;

	newSock = (deSocket*)deCalloc(sizeof(deSocket));
	if (!newSock)
	{
#if defined(DE_USE_WINSOCK)
		closesocket(newFd);
#else
		close(newFd);
#endif
		return DE_NULL;
	}

	newSock->stateLock		= deMutex_create(0);
	newSock->handle			= newFd;
	newSock->state			= DE_SOCKETSTATE_CONNECTED;
	newSock->openChannels	= DE_SOCKETCHANNEL_BOTH;

	if (clientAddress)
		deBsdAddressToSocketAddress(clientAddress, bsdAddr, (int)bsdAddrLen);

	return newSock;
}

deBool deSocket_connect (deSocket* sock, const deSocketAddress* address)
{
	deUint8				bsdAddrBuf[sizeof(struct sockaddr_in6)];
	struct sockaddr*	bsdAddr		= (struct sockaddr*)&bsdAddrBuf[0];
	NativeSocklen		bsdAddrLen;

	/* Resolve address. */
	if (!deSocketAddressToBsdAddress(address, sizeof(bsdAddrBuf), bsdAddr, &bsdAddrLen))
		return DE_FALSE;

	/* Create socket. */
	sock->handle = socket(bsdAddr->sa_family, deSocketTypeToBsdType(address->type), deSocketProtocolToBsdProtocol(address->protocol));
	if (!deSocketHandleIsValid(sock->handle))
		return DE_FALSE;

	/* Connect. */
	if (connect(sock->handle, bsdAddr, bsdAddrLen) != 0)
	{
#if defined(DE_USE_WINSOCK)
		closesocket(sock->handle);
#else
		close(sock->handle);
#endif
		sock->handle = DE_INVALID_SOCKET_HANDLE;
		return DE_FALSE;
	}

	sock->state			= DE_SOCKETSTATE_CONNECTED;
	sock->openChannels	= DE_SOCKETCHANNEL_BOTH;

	return DE_TRUE;
}

deBool deSocket_shutdown (deSocket* sock, deUint32 channels)
{
	deUint32 closedChannels = 0;

	deMutex_lock(sock->stateLock);

	if (sock->state == DE_SOCKETSTATE_DISCONNECTED ||
		sock->state == DE_SOCKETSTATE_CLOSED)
	{
		deMutex_unlock(sock->stateLock);
		return DE_FALSE;
	}

	DE_ASSERT(channels != 0 && (channels & ~(deUint32)DE_SOCKETCHANNEL_BOTH) == 0);

	/* Don't attempt to close already closed channels on partially open socket. */
	channels &= sock->openChannels;

	if (channels == 0)
	{
		deMutex_unlock(sock->stateLock);
		return DE_FALSE;
	}

#if defined(DE_USE_WINSOCK)
	{
		int how = 0;

		if ((channels & DE_SOCKETCHANNEL_BOTH) == DE_SOCKETCHANNEL_BOTH)
			how = SD_BOTH;
		else if (channels & DE_SOCKETCHANNEL_SEND)
			how = SD_SEND;
		else if (channels & DE_SOCKETCHANNEL_RECEIVE)
			how = SD_RECEIVE;

		if (shutdown(sock->handle, how) == 0)
			closedChannels = channels;
		else
		{
			int err = WSAGetLastError();

			/* \note Due to asynchronous behavior certain errors are perfectly ok. */
			if (err == WSAECONNABORTED || err == WSAECONNRESET || err == WSAENOTCONN)
				closedChannels = DE_SOCKETCHANNEL_BOTH;
			else
			{
				deMutex_unlock(sock->stateLock);
				return DE_FALSE;
			}
		}
	}
#else
	{
		int how = 0;

		if ((channels & DE_SOCKETCHANNEL_BOTH) == DE_SOCKETCHANNEL_BOTH)
			how = SHUT_RDWR;
		else if (channels & DE_SOCKETCHANNEL_SEND)
			how = SHUT_WR;
		else if (channels & DE_SOCKETCHANNEL_RECEIVE)
			how = SHUT_RD;

		if (shutdown(sock->handle, how) == 0)
			closedChannels = channels;
		else
		{
			if (errno == ENOTCONN)
				closedChannels = DE_SOCKETCHANNEL_BOTH;
			else
			{
				deMutex_unlock(sock->stateLock);
				return DE_FALSE;
			}
		}
	}
#endif

	sock->openChannels &= ~closedChannels;
	if (sock->openChannels == 0)
		sock->state = DE_SOCKETSTATE_DISCONNECTED;

	deMutex_unlock(sock->stateLock);
	return DE_TRUE;
}

deBool deSocket_close (deSocket* sock)
{
	deMutex_lock(sock->stateLock);

	if (sock->state == DE_SOCKETSTATE_CLOSED)
	{
		deMutex_unlock(sock->stateLock);
		return DE_FALSE;
	}

#if !defined(DE_USE_WINSOCK)
	if (sock->state == DE_SOCKETSTATE_LISTENING)
	{
		/* There can be a thread blockin in accept(). Release it by calling shutdown. */
		shutdown(sock->handle, SHUT_RDWR);
	}
#endif

#if defined(DE_USE_WINSOCK)
	if (closesocket(sock->handle) != 0)
		return DE_FALSE;
#else
	if (close(sock->handle) != 0)
		return DE_FALSE;
#endif
	sock->state			= DE_SOCKETSTATE_CLOSED;
	sock->handle		= DE_INVALID_SOCKET_HANDLE;
	sock->openChannels	= 0;

	deMutex_unlock(sock->stateLock);
	return DE_TRUE;
}

static deSocketResult mapSendRecvResult (int numBytes)
{
	if (numBytes > 0)
		return DE_SOCKETRESULT_SUCCESS;
	else if (numBytes == 0)
		return DE_SOCKETRESULT_CONNECTION_CLOSED;
	else
	{
		/* Other errors. */
#if defined(DE_USE_WINSOCK)
		int	error = WSAGetLastError();
		switch (error)
		{
			case WSAEWOULDBLOCK:	return DE_SOCKETRESULT_WOULD_BLOCK;
			case WSAENETDOWN:
			case WSAENETRESET:
			case WSAECONNABORTED:
			case WSAECONNRESET:		return DE_SOCKETRESULT_CONNECTION_TERMINATED;
			default:				return DE_SOCKETRESULT_ERROR;
		}
#else
		switch (errno)
		{
			case EAGAIN:		return DE_SOCKETRESULT_WOULD_BLOCK;
			case ECONNABORTED:
			case ECONNRESET:	return DE_SOCKETRESULT_CONNECTION_TERMINATED;
			default:			return DE_SOCKETRESULT_ERROR;
		}
#endif
	}
}

DE_INLINE void deSocket_setChannelsClosed (deSocket* sock, deUint32 channels)
{
	deMutex_lock(sock->stateLock);

	sock->openChannels &= ~channels;
	if (sock->openChannels == 0)
		sock->state = DE_SOCKETSTATE_DISCONNECTED;

	deMutex_unlock(sock->stateLock);
}

deSocketResult deSocket_send (deSocket* sock, const void* buf, size_t bufSize, size_t* numSentPtr)
{
	int				numSent	= (int)send(sock->handle, (const char*)buf, (NativeSize)bufSize, 0);
	deSocketResult	result	= mapSendRecvResult(numSent);

	if (numSentPtr)
		*numSentPtr = (numSent > 0) ? ((size_t)numSent) : (0);

	/* Update state. */
	if (result == DE_SOCKETRESULT_CONNECTION_CLOSED)
		deSocket_setChannelsClosed(sock, DE_SOCKETCHANNEL_SEND);
	else if (result == DE_SOCKETRESULT_CONNECTION_TERMINATED)
		deSocket_setChannelsClosed(sock, DE_SOCKETCHANNEL_BOTH);

	return result;
}

deSocketResult deSocket_receive (deSocket* sock, void* buf, size_t bufSize, size_t* numReceivedPtr)
{
	int				numRecv	= (int)recv(sock->handle, (char*)buf, (NativeSize)bufSize, 0);
	deSocketResult	result	= mapSendRecvResult(numRecv);

	if (numReceivedPtr)
		*numReceivedPtr = (numRecv > 0) ? ((size_t)numRecv) : (0);

	/* Update state. */
	if (result == DE_SOCKETRESULT_CONNECTION_CLOSED)
		deSocket_setChannelsClosed(sock, DE_SOCKETCHANNEL_RECEIVE);
	else if (result == DE_SOCKETRESULT_CONNECTION_TERMINATED)
		deSocket_setChannelsClosed(sock, DE_SOCKETCHANNEL_BOTH);

	return result;
}

#endif
