]> git.saurik.com Git - wxWidgets.git/blob - include/wx/gsocket.h
trying to resolve GSocketManager API mess: the meaning of Install/Uninstall_Callback...
[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 class WXDLLIMPEXP_FWD_NET wxSocketBase;
24
25 #include <stddef.h>
26
27 /*
28 Including sys/types.h under Cygwin results in the warnings about "fd_set
29 having been defined in sys/types.h" when winsock.h is included later and
30 doesn't seem to be necessary anyhow. It's not needed under Mac neither.
31 */
32 #if !defined(__WXMAC__) && !defined(__CYGWIN__) && !defined(__WXWINCE__)
33 #include <sys/types.h>
34 #endif
35
36 #ifdef __WXWINCE__
37 #include <stdlib.h>
38 #endif
39
40 // include the header defining timeval: under Windows this struct is used only
41 // with sockets so we need to include winsock.h which we do via windows.h
42 #ifdef __WXMSW__
43 #include "wx/msw/wrapwin.h"
44 #else
45 #include <sys/time.h> // for timeval
46 #endif
47
48 enum GAddressType
49 {
50 GSOCK_NOFAMILY = 0,
51 GSOCK_INET,
52 GSOCK_INET6,
53 GSOCK_UNIX
54 };
55
56 enum GSocketStream
57 {
58 GSOCK_STREAMED,
59 GSOCK_UNSTREAMED
60 };
61
62 enum GSocketError
63 {
64 GSOCK_NOERROR = 0,
65 GSOCK_INVOP,
66 GSOCK_IOERR,
67 GSOCK_INVADDR,
68 GSOCK_INVSOCK,
69 GSOCK_NOHOST,
70 GSOCK_INVPORT,
71 GSOCK_WOULDBLOCK,
72 GSOCK_TIMEDOUT,
73 GSOCK_MEMERR,
74 GSOCK_OPTERR
75 };
76
77 /* See below for an explanation on how events work.
78 */
79 enum GSocketEvent
80 {
81 GSOCK_INPUT = 0,
82 GSOCK_OUTPUT = 1,
83 GSOCK_CONNECTION = 2,
84 GSOCK_LOST = 3,
85 GSOCK_MAX_EVENT = 4
86 };
87
88 enum
89 {
90 GSOCK_INPUT_FLAG = 1 << GSOCK_INPUT,
91 GSOCK_OUTPUT_FLAG = 1 << GSOCK_OUTPUT,
92 GSOCK_CONNECTION_FLAG = 1 << GSOCK_CONNECTION,
93 GSOCK_LOST_FLAG = 1 << GSOCK_LOST
94 };
95
96 typedef int GSocketEventFlags;
97
98 struct GAddress;
99 class GSocket;
100
101 typedef void (*GSocketCallback)(GSocket *socket, GSocketEvent event,
102 char *cdata);
103
104 /*
105 Class providing hooks abstracting the differences between console and GUI
106 applications for socket code.
107
108 We also have different implementations of this class for different platforms
109 allowing us to keep more things in the common code but the main reason for
110 its existence is that we want the same socket code work differently
111 depending on whether it's used from a console or a GUI program. This is
112 achieved by implementing the virtual methods of this class differently in
113 the objects returned by wxConsoleAppTraits::GetSocketFunctionsTable() and
114 the same method in wxGUIAppTraits.
115 */
116 class GSocketManager
117 {
118 public:
119 // set the manager to use, we don't take ownership of it
120 //
121 // this should be called before GSocket_Init(), i.e. before the first
122 // wxSocket object is created, otherwise the manager returned by
123 // wxAppTraits::GetSocketManager() will be used
124 static void Set(GSocketManager *manager);
125
126 // return the manager to use
127 //
128 // this initializes the manager at first use
129 static GSocketManager *Get()
130 {
131 if ( !ms_manager )
132 Init();
133
134 return ms_manager;
135 }
136
137 // called before the first wxSocket is created and should do the
138 // initializations needed in order to use the network
139 //
140 // return true if initialized successfully
141 virtual bool OnInit() = 0;
142
143 // undo the initializations of OnInit()
144 virtual void OnExit() = 0;
145
146
147 // do manager-specific socket initializations: called in the beginning of
148 // the socket initialization
149 virtual bool Init_Socket(GSocket *socket) = 0;
150
151 // called when the socket is being closed
152 //
153 // TODO: merge this with Destroy_Socket(), currently 2 separate functions
154 // are needed because Init_Socket() always allocates manager-specific
155 // resources in GSocket and Destroy_Socket() must be called even if
156 // the socket has never been opened, but if the allocation were done
157 // on demand, then Destroy_Socket() could be called from
158 // GSocket::Close() and we wouldn't need Close_Socket() at all
159 virtual void Close_Socket(GSocket *socket) = 0;
160
161 // undo Init_Socket(): called from GSocket dtor
162 virtual void Destroy_Socket(GSocket *socket) = 0;
163
164
165 // these functions enable or disable monitoring of the given socket for the
166 // specified events inside the currently running event loop (but notice
167 // that both BSD and Winsock implementations actually use socket->m_server
168 // value to determine what exactly should be monitored so it needs to be
169 // set before calling these functions)
170 virtual void Install_Callback(GSocket *socket,
171 GSocketEvent event = GSOCK_MAX_EVENT) = 0;
172 virtual void Uninstall_Callback(GSocket *socket,
173 GSocketEvent event = GSOCK_MAX_EVENT) = 0;
174
175 virtual ~GSocketManager() { }
176
177 private:
178 // get the manager to use if we don't have it yet
179 static void Init();
180
181 static GSocketManager *ms_manager;
182 };
183
184 /*
185 Base class providing functionality common to BSD and Winsock sockets.
186
187 TODO: merge this in wxSocket itself, there is no reason to maintain the
188 separation between wxSocket and GSocket.
189 */
190 class GSocketBase
191 {
192 public:
193 // static factory function: creates the low-level socket associated with
194 // the given wxSocket (and inherits its attributes such as timeout)
195 static GSocket *Create(wxSocketBase& wxsocket);
196
197 virtual ~GSocketBase();
198
199 void SetTimeout(unsigned long millisec);
200
201 GSocketError SetLocal(GAddress *address);
202 GSocketError SetPeer(GAddress *address);
203 GAddress *GetLocal();
204 GAddress *GetPeer();
205
206 GSocketEventFlags Select(GSocketEventFlags flags);
207
208 virtual GSocket *WaitConnection(wxSocketBase& wxsocket) = 0;
209
210 void Close();
211 virtual void Shutdown();
212
213 void SetInitialSocketBuffers(int recv, int send)
214 {
215 m_initialRecvBufferSize = recv;
216 m_initialSendBufferSize = send;
217 }
218
219 // notify m_wxsocket about the given socket event by calling its (inaptly
220 // named) OnRequest() method
221 void NotifyOnStateChange(GSocketEvent event);
222
223 // this is officially SOCKET (unsigned int) under Windows but we don't want
224 // to include winsock.h which defines SOCKET from here so just use int
225 // under all platforms
226 int m_fd;
227
228 int m_initialRecvBufferSize;
229 int m_initialSendBufferSize;
230
231 GAddress *m_local;
232 GAddress *m_peer;
233 GSocketError m_error;
234
235 bool m_non_blocking;
236 bool m_server;
237 bool m_stream;
238 bool m_establishing;
239 bool m_reusable;
240 bool m_broadcast;
241 bool m_dobind;
242
243 struct timeval m_timeout;
244
245 GSocketEventFlags m_detected;
246
247 protected:
248 GSocketBase(wxSocketBase& wxsocket);
249
250 private:
251 // set in ctor and never changed except that it's reset to NULL when the
252 // socket is shut down
253 wxSocketBase *m_wxsocket;
254
255 DECLARE_NO_COPY_CLASS(GSocketBase)
256 };
257
258 #if defined(__WINDOWS__)
259 #include "wx/msw/gsockmsw.h"
260 #else
261 #include "wx/unix/gsockunx.h"
262 #endif
263
264 /* Global initializers */
265
266 /* GSocket_Init() must be called at the beginning (but after calling
267 * GSocketManager::Set() if a custom manager should be used) */
268 bool GSocket_Init();
269
270 /* GSocket_Cleanup() must be called at the end */
271 void GSocket_Cleanup();
272
273
274 /* GAddress */
275
276 // Represents a socket endpoint, i.e. -- in spite of its name -- not an address
277 // but an (address, port) pair
278 struct GAddress
279 {
280 struct sockaddr *m_addr;
281 size_t m_len;
282
283 GAddressType m_family;
284 int m_realfamily;
285
286 GSocketError m_error;
287 };
288
289 GAddress *GAddress_new();
290 GAddress *GAddress_copy(GAddress *address);
291 void GAddress_destroy(GAddress *address);
292
293 void GAddress_SetFamily(GAddress *address, GAddressType type);
294 GAddressType GAddress_GetFamily(GAddress *address);
295
296 /* The use of any of the next functions will set the address family to
297 * the specific one. For example if you use GAddress_INET_SetHostName,
298 * address family will be implicitly set to AF_INET.
299 */
300
301 GSocketError GAddress_INET_SetHostName(GAddress *address, const char *hostname);
302 GSocketError GAddress_INET_SetBroadcastAddress(GAddress *address);
303 GSocketError GAddress_INET_SetAnyAddress(GAddress *address);
304 GSocketError GAddress_INET_SetHostAddress(GAddress *address,
305 unsigned long hostaddr);
306 GSocketError GAddress_INET_SetPortName(GAddress *address, const char *port,
307 const char *protocol);
308 GSocketError GAddress_INET_SetPort(GAddress *address, unsigned short port);
309
310 GSocketError GAddress_INET_GetHostName(GAddress *address, char *hostname,
311 size_t sbuf);
312 unsigned long GAddress_INET_GetHostAddress(GAddress *address);
313 unsigned short GAddress_INET_GetPort(GAddress *address);
314
315 GSocketError _GAddress_translate_from(GAddress *address,
316 struct sockaddr *addr, int len);
317 GSocketError _GAddress_translate_to (GAddress *address,
318 struct sockaddr **addr, int *len);
319 GSocketError _GAddress_Init_INET(GAddress *address);
320
321 #if wxUSE_IPV6
322
323 GSocketError GAddress_INET6_SetHostName(GAddress *address, const char *hostname);
324 GSocketError GAddress_INET6_SetAnyAddress(GAddress *address);
325 GSocketError GAddress_INET6_SetHostAddress(GAddress *address,
326 struct in6_addr hostaddr);
327 GSocketError GAddress_INET6_SetPortName(GAddress *address, const char *port,
328 const char *protocol);
329 GSocketError GAddress_INET6_SetPort(GAddress *address, unsigned short port);
330
331 GSocketError GAddress_INET6_GetHostName(GAddress *address, char *hostname,
332 size_t sbuf);
333 GSocketError GAddress_INET6_GetHostAddress(GAddress *address,struct in6_addr *hostaddr);
334 unsigned short GAddress_INET6_GetPort(GAddress *address);
335
336 #endif // wxUSE_IPV6
337
338 // these functions are available under all platforms but only implemented under
339 // Unix ones, elsewhere they just return GSOCK_INVADDR
340 GSocketError _GAddress_Init_UNIX(GAddress *address);
341 GSocketError GAddress_UNIX_SetPath(GAddress *address, const char *path);
342 GSocketError GAddress_UNIX_GetPath(GAddress *address, char *path, size_t sbuf);
343
344 #endif /* wxUSE_SOCKETS */
345
346 #endif /* _WX_GSOCKET_H_ */