Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/usability/src/external/enet/win32.c @ 10256

Last change on this file since 10256 was 7991, checked in by rgrieder, 14 years ago

Merged revisions 7975-7977 from kicklib to usability in order to fix the build.

  • Property svn:eol-style set to native
File size: 10.9 KB
RevLine 
[7328]1/**
2 @file  win32.c
3 @brief ENet Win32 system specific functions
4*/
5#ifdef WIN32
6
[7438]7#define _WIN32_WINNT 0x0501
8
[7328]9#include <time.h>
10#define ENET_BUILDING_LIB 1
11#include "enet/enet.h"
[7991]12#include <ws2tcpip.h>
[7328]13
14static enet_uint32 timeBase = 0;
15
16int
17enet_initialize (void)
18{
[7394]19    WORD versionRequested = MAKEWORD (2, 2);
[7328]20    WSADATA wsaData;
21   
22    if (WSAStartup (versionRequested, & wsaData))
23       return -1;
24
[7394]25    if (LOBYTE (wsaData.wVersion) != 2||
26        HIBYTE (wsaData.wVersion) != 2)
[7328]27    {
28       WSACleanup ();
29       
30       return -1;
31    }
32
33    timeBeginPeriod (1);
34
35    return 0;
36}
37
38void
39enet_deinitialize (void)
40{
41    timeEndPeriod (1);
42
43    WSACleanup ();
44}
45
46enet_uint32
47enet_time_get (void)
48{
49    return (enet_uint32) timeGetTime () - timeBase;
50}
51
52void
53enet_time_set (enet_uint32 newTimeBase)
54{
55    timeBase = (enet_uint32) timeGetTime () - newTimeBase;
56}
57
[7390]58static enet_uint16
59enet_af (ENetAddressFamily family)
60{
61    if (family == ENET_IPV4)
62        return AF_INET;
63    if (family == ENET_IPV6)
64        return AF_INET6;
65    return 0;
66}
67
68static socklen_t
69enet_sa_size (ENetAddressFamily family)
70{
71    if (family == ENET_IPV4)
[7433]72        return sizeof (struct sockaddr_in);
[7390]73    if (family == ENET_IPV6)
[7433]74        return sizeof (struct sockaddr_in6);
[7390]75    return 0;
76}
77
78static ENetAddressFamily
[7433]79enet_address_set_address (ENetAddress * address, const struct sockaddr * sin)
[7390]80{
81    memset (address, 0, sizeof (ENetAddress));
82    if (sin -> sa_family == AF_INET)
83    {
[7433]84        address -> host = enet_address_map4 ((((struct sockaddr_in *) sin) -> sin_addr.s_addr));
[7392]85        /* address -> scopeID = 0; */
[7433]86        address -> port = ENET_NET_TO_HOST_16 (((struct sockaddr_in *) sin) -> sin_port);
[7390]87        return ENET_IPV4;
88    }
89    if (sin -> sa_family == AF_INET6)
90    {
[7433]91        address -> host = * (ENetHostAddress *) & ((struct sockaddr_in6 *) sin) -> sin6_addr;
92        address -> scopeID = ((struct sockaddr_in6 *) sin) -> sin6_scope_id;
93        address -> port = ENET_NET_TO_HOST_16 (((struct sockaddr_in6 *) sin) -> sin6_port);
[7390]94        return ENET_IPV6;
95    }
96    return ENET_NO_ADDRESS_FAMILY;
97}
98
99static int
[7433]100enet_address_set_sin (struct sockaddr * sin, const ENetAddress * address, ENetAddressFamily family)
[7390]101{
102    memset (sin, 0, enet_sa_size(family));
103    if (family == ENET_IPV4 &&
104      (enet_get_address_family (address) == ENET_IPV4 ||
105      !memcmp (& address -> host, & ENET_HOST_ANY, sizeof(ENetHostAddress))))
106    {
[7433]107        ((struct sockaddr_in *) sin) -> sin_family = AF_INET;
108        ((struct sockaddr_in *) sin) -> sin_addr = * (struct in_addr *) & address -> host.addr[12];
109        ((struct sockaddr_in *) sin) -> sin_port = ENET_HOST_TO_NET_16 (address -> port);
[7390]110        return 0;
111    }
112    else if (family == ENET_IPV6)
113    {
[7433]114        ((struct sockaddr_in6 *) sin) -> sin6_family = AF_INET6;
115        ((struct sockaddr_in6 *) sin) -> sin6_addr = * (struct in6_addr *) & address -> host;
116        ((struct sockaddr_in6 *) sin) -> sin6_scope_id = address -> scopeID;
117        ((struct sockaddr_in6 *) sin) -> sin6_port = ENET_HOST_TO_NET_16 (address -> port);
[7390]118        return 0;
119    }
120    return -1;
121}
122
[7328]123int
124enet_address_set_host (ENetAddress * address, const char * name)
125{
[7390]126    enet_uint16 port = address -> port;
[7433]127    struct addrinfo hints;
128    struct addrinfo * result;
129    struct addrinfo * res;
[7328]130
[7438]131    memset(& hints, 0, sizeof (hints));
132    hints.ai_flags = AI_ADDRCONFIG;
[7390]133    hints.ai_family = AF_UNSPEC;
134
135    if ( getaddrinfo(name, NULL, &hints, &result) )
136        return -1;
137
138    for (res = result; res != NULL; res = res -> ai_next)
[7328]139    {
[7390]140        if ( enet_address_set_address(address, res -> ai_addr) != ENET_NO_ADDRESS_FAMILY )
141            break;
[7328]142    }
143
[7390]144    address -> port = port;
145    freeaddrinfo(result);
146    if (res == NULL) return -1;
[7328]147
148    return 0;
149}
150
[7390]151static int
152enet_address_get_host_x (const ENetAddress * address, char * name, size_t nameLength, int flags)
[7328]153{
[7433]154    struct sockaddr_storage sin;
155    enet_address_set_sin((struct sockaddr *) & sin, address, ENET_IPV6);
[7390]156
[7433]157    if ( getnameinfo((struct sockaddr *) & sin, enet_sa_size (ENET_IPV6), name, nameLength, NULL, 0, flags))
[7328]158        return -1;
[7390]159
[7328]160    return 0;
161}
162
163int
[7390]164enet_address_get_host_ip (const ENetAddress * address, char * name, size_t nameLength)
165{
166    return enet_address_get_host_x(address, name, nameLength, NI_NUMERICHOST);
167}
168
169int
[7328]170enet_address_get_host (const ENetAddress * address, char * name, size_t nameLength)
171{
[7390]172    return enet_address_get_host_x(address, name, nameLength, 0);
[7328]173}
174
175int
[7390]176enet_socket_bind (ENetSocket socket, const ENetAddress * address, ENetAddressFamily family)
[7328]177{
[7433]178    struct sockaddr_storage sin;
[7328]179
180    if (address != NULL)
181    {
[7433]182        enet_address_set_sin((struct sockaddr *) & sin, address, family);
[7328]183    }
184    else
185    {
[7397]186        ENetAddress address_ = { ENET_HOST_ANY_INIT, 0, 0 };
[7433]187        enet_address_set_sin((struct sockaddr *) & sin, & address_, family);
[7328]188    }
189
[7433]190    return bind (socket, (struct sockaddr *) & sin, enet_sa_size(family)) == SOCKET_ERROR ? -1 : 0;
[7328]191}
192
193int
194enet_socket_listen (ENetSocket socket, int backlog)
195{
196    return listen (socket, backlog < 0 ? SOMAXCONN : backlog) == SOCKET_ERROR ? -1 : 0;
197}
198
199ENetSocket
[7390]200enet_socket_create (ENetSocketType type, ENetAddressFamily family)
[7328]201{
[7433]202    ENetSocket sock = socket (enet_af (family), type == ENET_SOCKET_TYPE_DATAGRAM ? SOCK_DGRAM : SOCK_STREAM, 0);
203    return sock;
[7328]204}
205
206int
207enet_socket_set_option (ENetSocket socket, ENetSocketOption option, int value)
208{
209    int result = SOCKET_ERROR;
210    switch (option)
211    {
212        case ENET_SOCKOPT_NONBLOCK:
213        {
214            u_long nonBlocking = (u_long) value;
215            result = ioctlsocket (socket, FIONBIO, & nonBlocking);
216            break;
217        }
218
219        case ENET_SOCKOPT_BROADCAST:
220            result = setsockopt (socket, SOL_SOCKET, SO_BROADCAST, (char *) & value, sizeof (int));
221            break;
222
223        case ENET_SOCKOPT_REUSEADDR:
224            result = setsockopt (socket, SOL_SOCKET, SO_REUSEADDR, (char *) & value, sizeof (int));
225            break;
226
227        case ENET_SOCKOPT_RCVBUF:
228            result = setsockopt (socket, SOL_SOCKET, SO_RCVBUF, (char *) & value, sizeof (int));
229            break;
230
231        case ENET_SOCKOPT_SNDBUF:
232            result = setsockopt (socket, SOL_SOCKET, SO_SNDBUF, (char *) & value, sizeof (int));
233            break;
234
235        default:
236            break;
237    }
238    return result == SOCKET_ERROR ? -1 : 0;
239}
240
241int
[7390]242enet_socket_connect (ENetSocket socket, const ENetAddress * address, ENetAddressFamily family)
[7328]243{
[7433]244    struct sockaddr_storage sin;
245    enet_address_set_sin((struct sockaddr *) & sin, address, family);
[7328]246
[7433]247    return connect (socket, (struct sockaddr *) & sin, enet_sa_size (family)) == SOCKET_ERROR ? -1 : 0;
[7328]248}
249
250ENetSocket
[7390]251enet_socket_accept (ENetSocket socket, ENetAddress * address, ENetAddressFamily family)
[7328]252{
253    SOCKET result;
[7433]254    struct sockaddr_storage sin;
255    socklen_t sinLength = enet_sa_size (family);
[7328]256
257    result = accept (socket, 
[7433]258                     address != NULL ? (struct sockaddr *) & sin : NULL,
[7328]259                     address != NULL ? & sinLength : NULL);
260
261    if (result == INVALID_SOCKET)
262      return ENET_SOCKET_NULL;
263
264    if (address != NULL)
265    {
[7433]266        enet_address_set_address(address, (struct sockaddr *) & sin);
[7328]267    }
268
269    return result;
270}
271
272void
273enet_socket_destroy (ENetSocket socket)
274{
275    closesocket (socket);
276}
277
278int
279enet_socket_send (ENetSocket socket,
280                  const ENetAddress * address,
281                  const ENetBuffer * buffers,
[7390]282                  size_t bufferCount,
283                  ENetAddressFamily family)
[7328]284{
[7433]285    struct sockaddr_storage sin;
[7328]286    DWORD sentLength;
287
288    if (address != NULL)
289    {
[7433]290        enet_address_set_sin((struct sockaddr *) & sin, address, family);
[7328]291    }
292
293    if (WSASendTo (socket, 
294                   (LPWSABUF) buffers,
295                   (DWORD) bufferCount,
296                   & sentLength,
297                   0,
[7433]298                   address != NULL ? (struct sockaddr *) & sin : 0,
[7390]299                   address != NULL ? enet_sa_size (family) : 0,
[7328]300                   NULL,
301                   NULL) == SOCKET_ERROR)
302    {
303       if (WSAGetLastError () == WSAEWOULDBLOCK)
304         return 0;
305
306       return -1;
307    }
308
309    return (int) sentLength;
310}
311
312int
313enet_socket_receive (ENetSocket socket,
314                     ENetAddress * address,
315                     ENetBuffer * buffers,
[7390]316                     size_t bufferCount,
317                     ENetAddressFamily family)
[7328]318{
[7390]319    INT sinLength = enet_sa_size (family);
[7328]320    DWORD flags = 0,
321          recvLength;
[7433]322    struct sockaddr_storage sin;
[7328]323
324    if (WSARecvFrom (socket,
325                     (LPWSABUF) buffers,
326                     (DWORD) bufferCount,
327                     & recvLength,
328                     & flags,
[7433]329                     address != NULL ? (struct sockaddr *) & sin : NULL,
[7328]330                     address != NULL ? & sinLength : NULL,
331                     NULL,
332                     NULL) == SOCKET_ERROR)
333    {
334       switch (WSAGetLastError ())
335       {
336       case WSAEWOULDBLOCK:
337       case WSAECONNRESET:
338          return 0;
339       }
340
341       return -1;
342    }
343
344    if (flags & MSG_PARTIAL)
345      return -1;
346
347    if (address != NULL)
348    {
[7433]349        enet_address_set_address(address, (struct sockaddr *) & sin);
[7328]350    }
351
352    return (int) recvLength;
353}
354
355int
356enet_socketset_select (ENetSocket maxSocket, ENetSocketSet * readSet, ENetSocketSet * writeSet, enet_uint32 timeout)
357{
358    struct timeval timeVal;
359
360    timeVal.tv_sec = timeout / 1000;
361    timeVal.tv_usec = (timeout % 1000) * 1000;
362
363    return select (maxSocket + 1, readSet, writeSet, NULL, & timeVal);
364}
365
366int
[7390]367enet_socket_wait (ENetSocket socket4, ENetSocket socket6, enet_uint32 * condition, enet_uint32 timeout)
[7328]368{
369    fd_set readSet, writeSet;
370    struct timeval timeVal;
371    int selectCount;
[7391]372    ENetSocket maxSocket;
[7390]373
[7328]374    timeVal.tv_sec = timeout / 1000;
375    timeVal.tv_usec = (timeout % 1000) * 1000;
[7390]376
[7328]377    FD_ZERO (& readSet);
378    FD_ZERO (& writeSet);
379
380    if (* condition & ENET_SOCKET_WAIT_SEND)
[7390]381    {
382        if (socket4 != ENET_SOCKET_NULL)
383            FD_SET (socket4, & writeSet);
384        if (socket6 != ENET_SOCKET_NULL)
385            FD_SET (socket6, & writeSet);
386    }
[7328]387
388    if (* condition & ENET_SOCKET_WAIT_RECEIVE)
[7390]389    {
390        if (socket4 != ENET_SOCKET_NULL)
391            FD_SET (socket4, & readSet);
392        if (socket6 != ENET_SOCKET_NULL)
393            FD_SET (socket6, & readSet);
394    }
[7328]395
[7391]396    maxSocket = 0;
[7390]397    if (socket4 != ENET_SOCKET_NULL)
398        maxSocket = socket4;
399    if (socket6 != ENET_SOCKET_NULL && socket6 > maxSocket)
400        maxSocket = socket6;
[7328]401
[7390]402    selectCount = select (maxSocket + 1, & readSet, & writeSet, NULL, & timeVal);
403
[7328]404    if (selectCount < 0)
405      return -1;
406
407    * condition = ENET_SOCKET_WAIT_NONE;
408
409    if (selectCount == 0)
410      return 0;
411
[7390]412    if ( (socket4 != ENET_SOCKET_NULL && FD_ISSET (socket4, & writeSet)) ||
413        (socket6 != ENET_SOCKET_NULL && FD_ISSET (socket6, & writeSet)) )
414        * condition |= ENET_SOCKET_WAIT_SEND;
[7328]415
[7390]416    if ( (socket4 != ENET_SOCKET_NULL && FD_ISSET (socket4, & readSet)) ||
417        (socket6 != ENET_SOCKET_NULL && FD_ISSET (socket6, & readSet)) )
418        * condition |= ENET_SOCKET_WAIT_RECEIVE;
419
[7328]420    return 0;
[7390]421}
[7328]422
423#endif
424
Note: See TracBrowser for help on using the repository browser.