]> git.saurik.com Git - wxWidgets.git/blob - include/wx/gsocket.h
don't duplicate GSocket creation/destruction and shutdown code in BSD and Winsock...
[wxWidgets.git] / include / wx / gsocket.h
1 /* -------------------------------------------------------------------------
2 * Project: GSocket (Generic Socket)
3 * Name: gsocket.h
4 * Author: Guilhem Lavaux
5 * Guillermo Rodriguez Garcia <guille@iies.es>
6 * Copyright: (c) Guilhem Lavaux
7 * (c) 2007,2008 Vadim Zeitlin <vadim@wxwidgets.org>
8 * Licence: wxWindows Licence
9 * Purpose: GSocket include file (system independent)
10 * CVSID: $Id$
11 * -------------------------------------------------------------------------
12 */
13
14 #ifndef _WX_GSOCKET_H_
15 #define _WX_GSOCKET_H_
16
17 #include "wx/defs.h"
18
19 #if wxUSE_SOCKETS
20
21 #include "wx/dlimpexp.h" /* for WXDLLIMPEXP_NET */
22
23 #include <stddef.h>
24
25 /*
26 Including sys/types.h under Cygwin results in the warnings about "fd_set
27 having been defined in sys/types.h" when winsock.h is included later and
28 doesn't seem to be necessary anyhow. It's not needed under Mac neither.
29 */
30 #if !defined(__WXMAC__) && !defined(__CYGWIN__) && !defined(__WXWINCE__)
31 #include <sys/types.h>
32 #endif
33
34 #ifdef __WXWINCE__
35 #include <stdlib.h>
36 #endif
37
38 enum GAddressType
39 {
40 GSOCK_NOFAMILY = 0,
41 GSOCK_INET,
42 GSOCK_INET6,
43 GSOCK_UNIX
44 };
45
46 enum GSocketStream
47 {
48 GSOCK_STREAMED,
49 GSOCK_UNSTREAMED
50 };
51
52 enum GSocketError
53 {
54 GSOCK_NOERROR = 0,
55 GSOCK_INVOP,
56 GSOCK_IOERR,
57 GSOCK_INVADDR,
58 GSOCK_INVSOCK,
59 GSOCK_NOHOST,
60 GSOCK_INVPORT,
61 GSOCK_WOULDBLOCK,
62 GSOCK_TIMEDOUT,
63 GSOCK_MEMERR,
64 GSOCK_OPTERR
65 };
66
67 /* See below for an explanation on how events work.
68 */
69 enum GSocketEvent
70 {
71 GSOCK_INPUT = 0,
72 GSOCK_OUTPUT = 1,
73 GSOCK_CONNECTION = 2,
74 GSOCK_LOST = 3,
75 GSOCK_MAX_EVENT = 4
76 };
77
78 enum
79 {
80 GSOCK_INPUT_FLAG = 1 << GSOCK_INPUT,
81 GSOCK_OUTPUT_FLAG = 1 << GSOCK_OUTPUT,
82 GSOCK_CONNECTION_FLAG = 1 << GSOCK_CONNECTION,
83 GSOCK_LOST_FLAG = 1 << GSOCK_LOST
84 };
85
86 typedef int GSocketEventFlags;
87
88 struct GAddress;
89 class GSocket;
90
91 typedef void (*GSocketCallback)(GSocket *socket, GSocketEvent event,
92 char *cdata);
93
94 /*
95 Class providing hooks abstracting the differences between console and GUI
96 applications for socket code.
97
98 We also have different implementations of this class for different platforms
99 allowing us to keep more things in the common code but the main reason for
100 its existence is that we want the same socket code work differently
101 depending on whether it's used from a console or a GUI program. This is
102 achieved by implementing the virtual methods of this class differently in
103 the objects returned by wxConsoleAppTraits::GetSocketFunctionsTable() and
104 the same method in wxGUIAppTraits.
105 */
106 class GSocketManager
107 {
108 public:
109 // set the manager to use, we don't take ownership of it
110 //
111 // this should be called before GSocket_Init(), i.e. before the first
112 // wxSocket object is created, otherwise the manager returned by
113 // wxAppTraits::GetSocketManager() will be used
114 static void Set(GSocketManager *manager);
115
116 // return the manager to use
117 //
118 // this initializes the manager at first use
119 static GSocketManager *Get()
120 {
121 if ( !ms_manager )
122 Init();
123
124 return ms_manager;
125 }
126
127 // called before the first wxSocket is created and should do the
128 // initializations needed in order to use the network
129 //
130 // return true if initialized successfully
131 virtual bool OnInit() = 0;
132
133 // undo the initializations of OnInit()
134 virtual void OnExit() = 0;
135
136
137 // do manager-specific socket initializations (and undo it): this is called
138 // in the beginning/end of the socket initialization/destruction
139 virtual bool Init_Socket(GSocket *socket) = 0;
140 virtual void Destroy_Socket(GSocket *socket) = 0;
141
142 virtual void Install_Callback(GSocket *socket, GSocketEvent event) = 0;
143 virtual void Uninstall_Callback(GSocket *socket, GSocketEvent event) = 0;
144
145 virtual void Enable_Events(GSocket *socket) = 0;
146 virtual void Disable_Events(GSocket *socket) = 0;
147
148 virtual ~GSocketManager() { }
149
150 private:
151 // get the manager to use if we don't have it yet
152 static void Init();
153
154 static GSocketManager *ms_manager;
155 };
156
157 /*
158 Base class providing functionality common to BSD and Winsock sockets.
159
160 TODO: merge this in wxSocket itself, there is no reason to maintain the
161 separation between wxSocket and GSocket.
162 */
163 class GSocketBase
164 {
165 public:
166 // static factory function
167 static GSocket *Create();
168
169 virtual ~GSocketBase();
170
171 GSocketEventFlags Select(GSocketEventFlags flags);
172
173 virtual void Close() = 0;
174 virtual void Shutdown();
175
176 #ifdef __WINDOWS__
177 SOCKET m_fd;
178 #else
179 int m_fd;
180 #endif
181
182 int m_initialRecvBufferSize;
183 int m_initialSendBufferSize;
184
185 GAddress *m_local;
186 GAddress *m_peer;
187 GSocketError m_error;
188
189 bool m_non_blocking;
190 bool m_server;
191 bool m_stream;
192 bool m_establishing;
193 bool m_reusable;
194 bool m_broadcast;
195 bool m_dobind;
196
197 #ifdef __WINDOWS__
198 struct timeval m_timeout;
199 #else
200 unsigned long m_timeout;
201 #endif
202
203 GSocketEventFlags m_detected;
204 GSocketCallback m_cbacks[GSOCK_MAX_EVENT];
205 char *m_data[GSOCK_MAX_EVENT];
206
207 protected:
208 GSocketBase();
209 };
210
211 #if defined(__WINDOWS__)
212 #include "wx/msw/gsockmsw.h"
213 #else
214 #include "wx/unix/gsockunx.h"
215 #endif
216
217 /* Global initializers */
218
219 /* GSocket_Init() must be called at the beginning (but after calling
220 * GSocketManager::Set() if a custom manager should be used) */
221 bool GSocket_Init();
222
223 /* GSocket_Cleanup() must be called at the end */
224 void GSocket_Cleanup();
225
226
227 /* GAddress */
228
229 // Represents a socket endpoint, i.e. -- in spite of its name -- not an address
230 // but an (address, port) pair
231 struct GAddress
232 {
233 struct sockaddr *m_addr;
234 size_t m_len;
235
236 GAddressType m_family;
237 int m_realfamily;
238
239 GSocketError m_error;
240 };
241
242 GAddress *GAddress_new();
243 GAddress *GAddress_copy(GAddress *address);
244 void GAddress_destroy(GAddress *address);
245
246 void GAddress_SetFamily(GAddress *address, GAddressType type);
247 GAddressType GAddress_GetFamily(GAddress *address);
248
249 /* The use of any of the next functions will set the address family to
250 * the specific one. For example if you use GAddress_INET_SetHostName,
251 * address family will be implicitly set to AF_INET.
252 */
253
254 GSocketError GAddress_INET_SetHostName(GAddress *address, const char *hostname);
255 GSocketError GAddress_INET_SetBroadcastAddress(GAddress *address);
256 GSocketError GAddress_INET_SetAnyAddress(GAddress *address);
257 GSocketError GAddress_INET_SetHostAddress(GAddress *address,
258 unsigned long hostaddr);
259 GSocketError GAddress_INET_SetPortName(GAddress *address, const char *port,
260 const char *protocol);
261 GSocketError GAddress_INET_SetPort(GAddress *address, unsigned short port);
262
263 GSocketError GAddress_INET_GetHostName(GAddress *address, char *hostname,
264 size_t sbuf);
265 unsigned long GAddress_INET_GetHostAddress(GAddress *address);
266 unsigned short GAddress_INET_GetPort(GAddress *address);
267
268 GSocketError _GAddress_translate_from(GAddress *address,
269 struct sockaddr *addr, int len);
270 GSocketError _GAddress_translate_to (GAddress *address,
271 struct sockaddr **addr, int *len);
272 GSocketError _GAddress_Init_INET(GAddress *address);
273
274 #if wxUSE_IPV6
275
276 GSocketError GAddress_INET6_SetHostName(GAddress *address, const char *hostname);
277 GSocketError GAddress_INET6_SetAnyAddress(GAddress *address);
278 GSocketError GAddress_INET6_SetHostAddress(GAddress *address,
279 struct in6_addr hostaddr);
280 GSocketError GAddress_INET6_SetPortName(GAddress *address, const char *port,
281 const char *protocol);
282 GSocketError GAddress_INET6_SetPort(GAddress *address, unsigned short port);
283
284 GSocketError GAddress_INET6_GetHostName(GAddress *address, char *hostname,
285 size_t sbuf);
286 GSocketError GAddress_INET6_GetHostAddress(GAddress *address,struct in6_addr *hostaddr);
287 unsigned short GAddress_INET6_GetPort(GAddress *address);
288
289 #endif // wxUSE_IPV6
290
291 // these functions are available under all platforms but only implemented under
292 // Unix ones, elsewhere they just return GSOCK_INVADDR
293 GSocketError _GAddress_Init_UNIX(GAddress *address);
294 GSocketError GAddress_UNIX_SetPath(GAddress *address, const char *path);
295 GSocketError GAddress_UNIX_GetPath(GAddress *address, char *path, size_t sbuf);
296
297 // standard linux headers produce many warnings when used with icc
298 #if defined(__INTELC__) && defined(__LINUX__)
299 inline void wxFD_ZERO(fd_set *fds)
300 {
301 #pragma warning(push)
302 #pragma warning(disable:593)
303 FD_ZERO(fds);
304 #pragma warning(pop)
305 }
306
307 inline void wxFD_SET(int fd, fd_set *fds)
308 {
309 #pragma warning(push, 1)
310 #pragma warning(disable:1469)
311 FD_SET(fd, fds);
312 #pragma warning(pop)
313 }
314
315 inline bool wxFD_ISSET(int fd, fd_set *fds)
316 {
317 #pragma warning(push, 1)
318 #pragma warning(disable:1469)
319 return FD_ISSET(fd, fds);
320 #pragma warning(pop)
321 }
322 inline bool wxFD_CLR(int fd, fd_set *fds)
323 {
324 #pragma warning(push, 1)
325 #pragma warning(disable:1469)
326 return FD_CLR(fd, fds);
327 #pragma warning(pop)
328 }
329 #else // !__INTELC__
330 #define wxFD_ZERO(fds) FD_ZERO(fds)
331 #define wxFD_SET(fd, fds) FD_SET(fd, fds)
332 #define wxFD_ISSET(fd, fds) FD_ISSET(fd, fds)
333 #define wxFD_CLR(fd, fds) FD_CLR(fd, fds)
334 #endif // __INTELC__/!__INTELC__
335
336 // this is for Windows where configure doesn't define this
337 #ifndef SOCKOPTLEN_T
338 #define SOCKOPTLEN_T int
339 #endif
340
341 /*
342 * MSW defines this, Unices don't.
343 */
344 #ifndef INVALID_SOCKET
345 #define INVALID_SOCKET (-1)
346 #endif
347
348 #endif /* wxUSE_SOCKETS */
349
350 #endif /* _WX_GSOCKET_H_ */