aboutsummaryrefslogtreecommitdiff
path: root/src/compat/win32.h
blob: 02eb2dd28d4fd84f86df47295f26085ba805a81b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
/*
 * Copyright (C) 2007-2023 Xagasoft, All rights reserved.
 *
 * This file is part of the libbu++ library and is released under the
 * terms of the license contained in the file LICENSE.
 */

#ifndef WIN32_COMPATIBILITY__H
#define WIN32_COMPATIBILITY__H

#ifdef WIN32

#ifdef __cplusplus
extern "C" 
{
#define FD_SETSIZE (4096*2)
#include <Winsock2.h>
#include <ws2tcpip.h>
}
#endif

#include "bu/string.h"
#include "bu/singleton.h"

#ifndef TEMP_FAILURE_RETRY
#define TEMP_FAILURE_RETRY(expression)            \
  (__extension__                                  \
    ({ long int __result;                         \
      do __result = (long int) (expression);      \
      while (__result == -1L && errno == EINTR);  \
      __result; }))
#endif

#define decltype( ret, name, ... ) \
    typedef ret (__cdecl *FNDEF_DYN_ ##name)( __VA_ARGS__ ); \
    static FNDEF_DYN_ ##name _fnptr_ ##name; \
    static ret name( __VA_ARGS__ )

__extension__ typedef int socklen_t;

#ifdef gai_strerror
#undef gai_strerror
#endif

namespace Bu
{
    class Winsock2 : public Bu::Singleton<Winsock2>
    {
    friend class Bu::Singleton<Winsock2>;
    private:
        Winsock2();
        virtual ~Winsock2();

        WSADATA wsaData;
        HINSTANCE Ws2_32;

    public:
        // decltype( return type, function name<, optional parameters> )
        decltype( int, WSAStartup, WORD, LPWSADATA );
        decltype( int, WSACleanup );
        decltype( int, WSAGetLastError );
        decltype( char *, inet_ntoa, struct in_addr );
        decltype( unsigned long, inet_addr, const char *s_in );
        decltype( int, select, int nfds, fd_set *readfds, fd_set *writefds, 
                fd_set *exceptfds, const struct timeval *timeout );
        decltype( SOCKET, socket, int domain, int type, int protocol );
        decltype( int, shutdown, SOCKET s, int how );
        decltype( int, ioctlsocket, SOCKET s, long cmd, u_long *argp );
        decltype( u_short, htons, u_short in );
        decltype( u_long, htonl, u_long in );
        decltype( struct hostent *, gethostbyname, const char *name );
        decltype( void, freeaddrinfo, struct addrinfo *ai );
        decltype( int, getaddrinfo, const char *nodename, const char *servname,
                const struct addrinfo *hints, struct addrinfo **res );
        decltype( int, connect, SOCKET s, const struct sockaddr *serv_addr,
                int addrlen );
        decltype( int, getpeername, SOCKET s, struct sockaddr *name,
                int *namelen );
        decltype( int, setsockopt, SOCKET s, int level, int optname,
                const char *optval, int optlen );
        decltype( int, bind, SOCKET s, const struct sockaddr *my_addr,
                int addrlen );
        decltype( int, listen, SOCKET s, int backlog );
        decltype( SOCKET, accept, SOCKET s, struct sockaddr *addr,
                int *addrlen);  
        decltype( int, recv, SOCKET s, char *buf, int len, int flags );
        decltype( int, send, SOCKET s, const char *buf, int len, int flags );
        decltype( int, __WSAFDIsSet, SOCKET s, fd_set *set );
    
        static char scode[32];
        static char *gai_strerror( int iCode );
    };

    Bu::String getLastWinError();
};

#ifdef FD_ISSET
#undef FD_ISSET
#endif

#define bu_WSAStartup (*Bu::Winsock2::WSAStartup)
#define bu_WSACleanup (*Bu::Winsock2::WSACleanup)
#define bu_WSAGetLastError (*Bu::Winsock2::WSAGetLastError)
#define bu_inet_ntoa (*Bu::Winsock2::inet_ntoa)
#define bu_inet_addr (*Bu::Winsock2::inet_addr)
#define bu_select (*Bu::Winsock2::select)
#define bu_socket (*Bu::Winsock2::socket)
#define bu_shutdown (*Bu::Winsock2::shutdown)
#define bu_ioctlsocket (*Bu::Winsock2::ioctlsocket)
#define bu_htons (*Bu::Winsock2::htons)
#define bu_htonl (*Bu::Winsock2::htonl)
#define bu_gethostbyname (*Bu::Winsock2::gethostbyname)
#define bu_freeaddrinfo (*Bu::Winsock2::freeaddrinfo)
#define bu_getaddrinfo (*Bu::Winsock2::getaddrinfo)
#define bu_connect (*Bu::Winsock2::connect)
#define bu_getpeername (*Bu::Winsock2::getpeername)
#define bu_setsockopt (*Bu::Winsock2::setsockopt)
#define bu_bind (*Bu::Winsock2::bind)
#define bu_listen (*Bu::Winsock2::listen)
#define bu_accept (*Bu::Winsock2::accept)   
#define bu_recv (*Bu::Winsock2::recv)
#define bu_send (*Bu::Winsock2::send)
#define bu___WSAFDIsSet (*Bu::Winsock2::__WSAFDIsSet)

#define FD_ISSET (*Bu::Winsock2::__WSAFDIsSet)
#define bu_gai_strerror Bu::Winsock2::gai_strerror

#undef decltype

#undef USE_64BIT_IO

// Windows has no autoconfig, and no endian.h, but only works on little endian
// as far as I know.
#define LITTLE_ENDIAN 0
#define BIG_ENDIAN 1
#define BYTE_ORDER 0

#endif /* WIN32 */
#endif