1 /*
2  * This file is part of gtkD.
3  *
4  * gtkD is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU Lesser General Public License
6  * as published by the Free Software Foundation; either version 3
7  * of the License, or (at your option) any later version, with
8  * some exceptions, please read the COPYING file.
9  *
10  * gtkD is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public License
16  * along with gtkD; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
18  */
19 
20 // generated automatically - do not change
21 // find conversion definition on APILookup.txt
22 // implement new conversion functionalities on the wrap.utils pakage
23 
24 
25 module gio.SocketListener;
26 
27 private import gio.AsyncResultIF;
28 private import gio.Cancellable;
29 private import gio.Socket;
30 private import gio.SocketAddress;
31 private import gio.SocketConnection;
32 private import glib.ConstructionException;
33 private import glib.ErrorG;
34 private import glib.GException;
35 private import gobject.ObjectG;
36 private import gobject.Signals;
37 private import gtkc.gio;
38 public  import gtkc.giotypes;
39 private import std.algorithm;
40 
41 
42 /**
43  * A #GSocketListener is an object that keeps track of a set
44  * of server sockets and helps you accept sockets from any of the
45  * socket, either sync or async.
46  * 
47  * If you want to implement a network server, also look at #GSocketService
48  * and #GThreadedSocketService which are subclass of #GSocketListener
49  * that makes this even easier.
50  *
51  * Since: 2.22
52  */
53 public class SocketListener : ObjectG
54 {
55 	/** the main Gtk struct */
56 	protected GSocketListener* gSocketListener;
57 
58 	/** Get the main Gtk struct */
59 	public GSocketListener* getSocketListenerStruct(bool transferOwnership = false)
60 	{
61 		if (transferOwnership)
62 			ownedRef = false;
63 		return gSocketListener;
64 	}
65 
66 	/** the main Gtk struct as a void* */
67 	protected override void* getStruct()
68 	{
69 		return cast(void*)gSocketListener;
70 	}
71 
72 	protected override void setStruct(GObject* obj)
73 	{
74 		gSocketListener = cast(GSocketListener*)obj;
75 		super.setStruct(obj);
76 	}
77 
78 	/**
79 	 * Sets our main struct and passes it to the parent class.
80 	 */
81 	public this (GSocketListener* gSocketListener, bool ownedRef = false)
82 	{
83 		this.gSocketListener = gSocketListener;
84 		super(cast(GObject*)gSocketListener, ownedRef);
85 	}
86 
87 
88 	/** */
89 	public static GType getType()
90 	{
91 		return g_socket_listener_get_type();
92 	}
93 
94 	/**
95 	 * Creates a new #GSocketListener with no sockets to listen for.
96 	 * New listeners can be added with e.g. g_socket_listener_add_address()
97 	 * or g_socket_listener_add_inet_port().
98 	 *
99 	 * Returns: a new #GSocketListener.
100 	 *
101 	 * Since: 2.22
102 	 *
103 	 * Throws: ConstructionException GTK+ fails to create the object.
104 	 */
105 	public this()
106 	{
107 		auto p = g_socket_listener_new();
108 		
109 		if(p is null)
110 		{
111 			throw new ConstructionException("null returned by new");
112 		}
113 		
114 		this(cast(GSocketListener*) p, true);
115 	}
116 
117 	/**
118 	 * Blocks waiting for a client to connect to any of the sockets added
119 	 * to the listener. Returns a #GSocketConnection for the socket that was
120 	 * accepted.
121 	 *
122 	 * If @source_object is not %NULL it will be filled out with the source
123 	 * object specified when the corresponding socket or address was added
124 	 * to the listener.
125 	 *
126 	 * If @cancellable is not %NULL, then the operation can be cancelled by
127 	 * triggering the cancellable object from another thread. If the operation
128 	 * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
129 	 *
130 	 * Params:
131 	 *     sourceObject = location where #GObject pointer will be stored, or %NULL
132 	 *     cancellable = optional #GCancellable object, %NULL to ignore.
133 	 *
134 	 * Returns: a #GSocketConnection on success, %NULL on error.
135 	 *
136 	 * Since: 2.22
137 	 *
138 	 * Throws: GException on failure.
139 	 */
140 	public SocketConnection accept(out ObjectG sourceObject, Cancellable cancellable)
141 	{
142 		GObject* outsourceObject = null;
143 		GError* err = null;
144 		
145 		auto p = g_socket_listener_accept(gSocketListener, &outsourceObject, (cancellable is null) ? null : cancellable.getCancellableStruct(), &err);
146 		
147 		if (err !is null)
148 		{
149 			throw new GException( new ErrorG(err) );
150 		}
151 		
152 		sourceObject = ObjectG.getDObject!(ObjectG)(outsourceObject);
153 		
154 		if(p is null)
155 		{
156 			return null;
157 		}
158 		
159 		return ObjectG.getDObject!(SocketConnection)(cast(GSocketConnection*) p, true);
160 	}
161 
162 	/**
163 	 * This is the asynchronous version of g_socket_listener_accept().
164 	 *
165 	 * When the operation is finished @callback will be
166 	 * called. You can then call g_socket_listener_accept_socket()
167 	 * to get the result of the operation.
168 	 *
169 	 * Params:
170 	 *     cancellable = a #GCancellable, or %NULL
171 	 *     callback = a #GAsyncReadyCallback
172 	 *     userData = user data for the callback
173 	 *
174 	 * Since: 2.22
175 	 */
176 	public void acceptAsync(Cancellable cancellable, GAsyncReadyCallback callback, void* userData)
177 	{
178 		g_socket_listener_accept_async(gSocketListener, (cancellable is null) ? null : cancellable.getCancellableStruct(), callback, userData);
179 	}
180 
181 	/**
182 	 * Finishes an async accept operation. See g_socket_listener_accept_async()
183 	 *
184 	 * Params:
185 	 *     result = a #GAsyncResult.
186 	 *     sourceObject = Optional #GObject identifying this source
187 	 *
188 	 * Returns: a #GSocketConnection on success, %NULL on error.
189 	 *
190 	 * Since: 2.22
191 	 *
192 	 * Throws: GException on failure.
193 	 */
194 	public SocketConnection acceptFinish(AsyncResultIF result, out ObjectG sourceObject)
195 	{
196 		GObject* outsourceObject = null;
197 		GError* err = null;
198 		
199 		auto p = g_socket_listener_accept_finish(gSocketListener, (result is null) ? null : result.getAsyncResultStruct(), &outsourceObject, &err);
200 		
201 		if (err !is null)
202 		{
203 			throw new GException( new ErrorG(err) );
204 		}
205 		
206 		sourceObject = ObjectG.getDObject!(ObjectG)(outsourceObject);
207 		
208 		if(p is null)
209 		{
210 			return null;
211 		}
212 		
213 		return ObjectG.getDObject!(SocketConnection)(cast(GSocketConnection*) p, true);
214 	}
215 
216 	/**
217 	 * Blocks waiting for a client to connect to any of the sockets added
218 	 * to the listener. Returns the #GSocket that was accepted.
219 	 *
220 	 * If you want to accept the high-level #GSocketConnection, not a #GSocket,
221 	 * which is often the case, then you should use g_socket_listener_accept()
222 	 * instead.
223 	 *
224 	 * If @source_object is not %NULL it will be filled out with the source
225 	 * object specified when the corresponding socket or address was added
226 	 * to the listener.
227 	 *
228 	 * If @cancellable is not %NULL, then the operation can be cancelled by
229 	 * triggering the cancellable object from another thread. If the operation
230 	 * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
231 	 *
232 	 * Params:
233 	 *     sourceObject = location where #GObject pointer will be stored, or %NULL.
234 	 *     cancellable = optional #GCancellable object, %NULL to ignore.
235 	 *
236 	 * Returns: a #GSocket on success, %NULL on error.
237 	 *
238 	 * Since: 2.22
239 	 *
240 	 * Throws: GException on failure.
241 	 */
242 	public Socket acceptSocket(out ObjectG sourceObject, Cancellable cancellable)
243 	{
244 		GObject* outsourceObject = null;
245 		GError* err = null;
246 		
247 		auto p = g_socket_listener_accept_socket(gSocketListener, &outsourceObject, (cancellable is null) ? null : cancellable.getCancellableStruct(), &err);
248 		
249 		if (err !is null)
250 		{
251 			throw new GException( new ErrorG(err) );
252 		}
253 		
254 		sourceObject = ObjectG.getDObject!(ObjectG)(outsourceObject);
255 		
256 		if(p is null)
257 		{
258 			return null;
259 		}
260 		
261 		return ObjectG.getDObject!(Socket)(cast(GSocket*) p, true);
262 	}
263 
264 	/**
265 	 * This is the asynchronous version of g_socket_listener_accept_socket().
266 	 *
267 	 * When the operation is finished @callback will be
268 	 * called. You can then call g_socket_listener_accept_socket_finish()
269 	 * to get the result of the operation.
270 	 *
271 	 * Params:
272 	 *     cancellable = a #GCancellable, or %NULL
273 	 *     callback = a #GAsyncReadyCallback
274 	 *     userData = user data for the callback
275 	 *
276 	 * Since: 2.22
277 	 */
278 	public void acceptSocketAsync(Cancellable cancellable, GAsyncReadyCallback callback, void* userData)
279 	{
280 		g_socket_listener_accept_socket_async(gSocketListener, (cancellable is null) ? null : cancellable.getCancellableStruct(), callback, userData);
281 	}
282 
283 	/**
284 	 * Finishes an async accept operation. See g_socket_listener_accept_socket_async()
285 	 *
286 	 * Params:
287 	 *     result = a #GAsyncResult.
288 	 *     sourceObject = Optional #GObject identifying this source
289 	 *
290 	 * Returns: a #GSocket on success, %NULL on error.
291 	 *
292 	 * Since: 2.22
293 	 *
294 	 * Throws: GException on failure.
295 	 */
296 	public Socket acceptSocketFinish(AsyncResultIF result, out ObjectG sourceObject)
297 	{
298 		GObject* outsourceObject = null;
299 		GError* err = null;
300 		
301 		auto p = g_socket_listener_accept_socket_finish(gSocketListener, (result is null) ? null : result.getAsyncResultStruct(), &outsourceObject, &err);
302 		
303 		if (err !is null)
304 		{
305 			throw new GException( new ErrorG(err) );
306 		}
307 		
308 		sourceObject = ObjectG.getDObject!(ObjectG)(outsourceObject);
309 		
310 		if(p is null)
311 		{
312 			return null;
313 		}
314 		
315 		return ObjectG.getDObject!(Socket)(cast(GSocket*) p, true);
316 	}
317 
318 	/**
319 	 * Creates a socket of type @type and protocol @protocol, binds
320 	 * it to @address and adds it to the set of sockets we're accepting
321 	 * sockets from.
322 	 *
323 	 * Note that adding an IPv6 address, depending on the platform,
324 	 * may or may not result in a listener that also accepts IPv4
325 	 * connections.  For more deterministic behavior, see
326 	 * g_socket_listener_add_inet_port().
327 	 *
328 	 * @source_object will be passed out in the various calls
329 	 * to accept to identify this particular source, which is
330 	 * useful if you're listening on multiple addresses and do
331 	 * different things depending on what address is connected to.
332 	 *
333 	 * If successful and @effective_address is non-%NULL then it will
334 	 * be set to the address that the binding actually occurred at.  This
335 	 * is helpful for determining the port number that was used for when
336 	 * requesting a binding to port 0 (ie: "any port").  This address, if
337 	 * requested, belongs to the caller and must be freed.
338 	 *
339 	 * Params:
340 	 *     address = a #GSocketAddress
341 	 *     type = a #GSocketType
342 	 *     protocol = a #GSocketProtocol
343 	 *     sourceObject = Optional #GObject identifying this source
344 	 *     effectiveAddress = location to store the address that was bound to, or %NULL.
345 	 *
346 	 * Returns: %TRUE on success, %FALSE on error.
347 	 *
348 	 * Since: 2.22
349 	 *
350 	 * Throws: GException on failure.
351 	 */
352 	public bool addAddress(SocketAddress address, GSocketType type, GSocketProtocol protocol, ObjectG sourceObject, out SocketAddress effectiveAddress)
353 	{
354 		GSocketAddress* outeffectiveAddress = null;
355 		GError* err = null;
356 		
357 		auto p = g_socket_listener_add_address(gSocketListener, (address is null) ? null : address.getSocketAddressStruct(), type, protocol, (sourceObject is null) ? null : sourceObject.getObjectGStruct(), &outeffectiveAddress, &err) != 0;
358 		
359 		if (err !is null)
360 		{
361 			throw new GException( new ErrorG(err) );
362 		}
363 		
364 		effectiveAddress = ObjectG.getDObject!(SocketAddress)(outeffectiveAddress);
365 		
366 		return p;
367 	}
368 
369 	/**
370 	 * Listens for TCP connections on any available port number for both
371 	 * IPv6 and IPv4 (if each is available).
372 	 *
373 	 * This is useful if you need to have a socket for incoming connections
374 	 * but don't care about the specific port number.
375 	 *
376 	 * @source_object will be passed out in the various calls
377 	 * to accept to identify this particular source, which is
378 	 * useful if you're listening on multiple addresses and do
379 	 * different things depending on what address is connected to.
380 	 *
381 	 * Params:
382 	 *     sourceObject = Optional #GObject identifying this source
383 	 *
384 	 * Returns: the port number, or 0 in case of failure.
385 	 *
386 	 * Since: 2.24
387 	 *
388 	 * Throws: GException on failure.
389 	 */
390 	public ushort addAnyInetPort(ObjectG sourceObject)
391 	{
392 		GError* err = null;
393 		
394 		auto p = g_socket_listener_add_any_inet_port(gSocketListener, (sourceObject is null) ? null : sourceObject.getObjectGStruct(), &err);
395 		
396 		if (err !is null)
397 		{
398 			throw new GException( new ErrorG(err) );
399 		}
400 		
401 		return p;
402 	}
403 
404 	/**
405 	 * Helper function for g_socket_listener_add_address() that
406 	 * creates a TCP/IP socket listening on IPv4 and IPv6 (if
407 	 * supported) on the specified port on all interfaces.
408 	 *
409 	 * @source_object will be passed out in the various calls
410 	 * to accept to identify this particular source, which is
411 	 * useful if you're listening on multiple addresses and do
412 	 * different things depending on what address is connected to.
413 	 *
414 	 * Params:
415 	 *     port = an IP port number (non-zero)
416 	 *     sourceObject = Optional #GObject identifying this source
417 	 *
418 	 * Returns: %TRUE on success, %FALSE on error.
419 	 *
420 	 * Since: 2.22
421 	 *
422 	 * Throws: GException on failure.
423 	 */
424 	public bool addInetPort(ushort port, ObjectG sourceObject)
425 	{
426 		GError* err = null;
427 		
428 		auto p = g_socket_listener_add_inet_port(gSocketListener, port, (sourceObject is null) ? null : sourceObject.getObjectGStruct(), &err) != 0;
429 		
430 		if (err !is null)
431 		{
432 			throw new GException( new ErrorG(err) );
433 		}
434 		
435 		return p;
436 	}
437 
438 	/**
439 	 * Adds @socket to the set of sockets that we try to accept
440 	 * new clients from. The socket must be bound to a local
441 	 * address and listened to.
442 	 *
443 	 * @source_object will be passed out in the various calls
444 	 * to accept to identify this particular source, which is
445 	 * useful if you're listening on multiple addresses and do
446 	 * different things depending on what address is connected to.
447 	 *
448 	 * The @socket will not be automatically closed when the @listener is finalized
449 	 * unless the listener held the final reference to the socket. Before GLib 2.42,
450 	 * the @socket was automatically closed on finalization of the @listener, even
451 	 * if references to it were held elsewhere.
452 	 *
453 	 * Params:
454 	 *     socket = a listening #GSocket
455 	 *     sourceObject = Optional #GObject identifying this source
456 	 *
457 	 * Returns: %TRUE on success, %FALSE on error.
458 	 *
459 	 * Since: 2.22
460 	 *
461 	 * Throws: GException on failure.
462 	 */
463 	public bool addSocket(Socket socket, ObjectG sourceObject)
464 	{
465 		GError* err = null;
466 		
467 		auto p = g_socket_listener_add_socket(gSocketListener, (socket is null) ? null : socket.getSocketStruct(), (sourceObject is null) ? null : sourceObject.getObjectGStruct(), &err) != 0;
468 		
469 		if (err !is null)
470 		{
471 			throw new GException( new ErrorG(err) );
472 		}
473 		
474 		return p;
475 	}
476 
477 	/**
478 	 * Closes all the sockets in the listener.
479 	 *
480 	 * Since: 2.22
481 	 */
482 	public void close()
483 	{
484 		g_socket_listener_close(gSocketListener);
485 	}
486 
487 	/**
488 	 * Sets the listen backlog on the sockets in the listener.
489 	 *
490 	 * See g_socket_set_listen_backlog() for details
491 	 *
492 	 * Params:
493 	 *     listenBacklog = an integer
494 	 *
495 	 * Since: 2.22
496 	 */
497 	public void setBacklog(int listenBacklog)
498 	{
499 		g_socket_listener_set_backlog(gSocketListener, listenBacklog);
500 	}
501 
502 	protected class OnDelegateWrapper
503 	{
504 		void delegate(GSocketListenerEvent, Socket, SocketListener) dlg;
505 		gulong handlerId;
506 		
507 		this(void delegate(GSocketListenerEvent, Socket, SocketListener) dlg)
508 		{
509 			this.dlg = dlg;
510 			onListeners ~= this;
511 		}
512 		
513 		void remove(OnDelegateWrapper source)
514 		{
515 			foreach(index, wrapper; onListeners)
516 			{
517 				if (wrapper.handlerId == source.handlerId)
518 				{
519 					onListeners[index] = null;
520 					onListeners = std.algorithm.remove(onListeners, index);
521 					break;
522 				}
523 			}
524 		}
525 	}
526 	OnDelegateWrapper[] onListeners;
527 
528 	/**
529 	 * Emitted when @listener's activity on @socket changes state.
530 	 * Note that when @listener is used to listen on both IPv4 and
531 	 * IPv6, a separate set of signals will be emitted for each, and
532 	 * the order they happen in is undefined.
533 	 *
534 	 * Params:
535 	 *     event = the event that is occurring
536 	 *     socket = the #GSocket the event is occurring on
537 	 *
538 	 * Since: 2.46
539 	 */
540 	gulong addOn(void delegate(GSocketListenerEvent, Socket, SocketListener) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
541 	{
542 		auto wrapper = new OnDelegateWrapper(dlg);
543 		wrapper.handlerId = Signals.connectData(
544 			this,
545 			"event",
546 			cast(GCallback)&callBack,
547 			cast(void*)wrapper,
548 			cast(GClosureNotify)&callBackDestroy,
549 			connectFlags);
550 		return wrapper.handlerId;
551 	}
552 	
553 	extern(C) static void callBack(GSocketListener* socketlistenerStruct, GSocketListenerEvent event, GSocket* socket, OnDelegateWrapper wrapper)
554 	{
555 		wrapper.dlg(event, ObjectG.getDObject!(Socket)(socket), wrapper.outer);
556 	}
557 	
558 	extern(C) static void callBackDestroy(OnDelegateWrapper wrapper, GClosure* closure)
559 	{
560 		wrapper.remove(wrapper);
561 	}
562 }