Branch data Line data Source code
1 : : /* GIO - GLib Input, Output and Streaming Library
2 : : *
3 : : * Copyright (C) 2008 Red Hat, Inc.
4 : : *
5 : : * SPDX-License-Identifier: LGPL-2.1-or-later
6 : : *
7 : : * This library is free software; you can redistribute it and/or
8 : : * modify it under the terms of the GNU Lesser General Public
9 : : * License as published by the Free Software Foundation; either
10 : : * version 2.1 of the License, or (at your option) any later version.
11 : : *
12 : : * This library is distributed in the hope that it will be useful,
13 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 : : * Lesser General Public License for more details.
16 : : *
17 : : * You should have received a copy of the GNU Lesser General
18 : : * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
19 : : */
20 : :
21 : : #include "config.h"
22 : : #include "gsocketaddressenumerator.h"
23 : : #include "glibintl.h"
24 : :
25 : : #include "gtask.h"
26 : :
27 : : /**
28 : : * GSocketAddressEnumerator:
29 : : *
30 : : * `GSocketAddressEnumerator` is an enumerator type for
31 : : * [class@Gio.SocketAddress] instances. It is returned by enumeration functions
32 : : * such as [method@Gio.SocketConnectable.enumerate], which returns a
33 : : * `GSocketAddressEnumerator` to list each [class@Gio.SocketAddress] which could
34 : : * be used to connect to that [iface@Gio.SocketConnectable].
35 : : *
36 : : * Enumeration is typically a blocking operation, so the asynchronous methods
37 : : * [method@Gio.SocketAddressEnumerator.next_async] and
38 : : * [method@Gio.SocketAddressEnumerator.next_finish] should be used where
39 : : * possible.
40 : : *
41 : : * Each `GSocketAddressEnumerator` can only be enumerated once. Once
42 : : * [method@Gio.SocketAddressEnumerator.next] has returned `NULL`, further
43 : : * enumeration with that `GSocketAddressEnumerator` is not possible, and it can
44 : : * be unreffed.
45 : : */
46 : :
47 : 4871 : G_DEFINE_ABSTRACT_TYPE (GSocketAddressEnumerator, g_socket_address_enumerator, G_TYPE_OBJECT)
48 : :
49 : : static void g_socket_address_enumerator_real_next_async (GSocketAddressEnumerator *enumerator,
50 : : GCancellable *cancellable,
51 : : GAsyncReadyCallback callback,
52 : : gpointer user_data);
53 : : static GSocketAddress *g_socket_address_enumerator_real_next_finish (GSocketAddressEnumerator *enumerator,
54 : : GAsyncResult *result,
55 : : GError **error);
56 : :
57 : : static void
58 : 2592 : g_socket_address_enumerator_init (GSocketAddressEnumerator *enumerator)
59 : : {
60 : 2592 : }
61 : :
62 : : static void
63 : 124 : g_socket_address_enumerator_class_init (GSocketAddressEnumeratorClass *enumerator_class)
64 : : {
65 : 124 : enumerator_class->next_async = g_socket_address_enumerator_real_next_async;
66 : 124 : enumerator_class->next_finish = g_socket_address_enumerator_real_next_finish;
67 : 124 : }
68 : :
69 : : /**
70 : : * g_socket_address_enumerator_next:
71 : : * @enumerator: a #GSocketAddressEnumerator
72 : : * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore.
73 : : * @error: a #GError.
74 : : *
75 : : * Retrieves the next #GSocketAddress from @enumerator. Note that this
76 : : * may block for some amount of time. (Eg, a #GNetworkAddress may need
77 : : * to do a DNS lookup before it can return an address.) Use
78 : : * g_socket_address_enumerator_next_async() if you need to avoid
79 : : * blocking.
80 : : *
81 : : * If @enumerator is expected to yield addresses, but for some reason
82 : : * is unable to (eg, because of a DNS error), then the first call to
83 : : * g_socket_address_enumerator_next() will return an appropriate error
84 : : * in *@error. However, if the first call to
85 : : * g_socket_address_enumerator_next() succeeds, then any further
86 : : * internal errors (other than @cancellable being triggered) will be
87 : : * ignored.
88 : : *
89 : : * Returns: (transfer full) (nullable): a #GSocketAddress (owned by the caller), or %NULL on
90 : : * error (in which case *@error will be set) or if there are no
91 : : * more addresses.
92 : : */
93 : : GSocketAddress *
94 : 2616 : g_socket_address_enumerator_next (GSocketAddressEnumerator *enumerator,
95 : : GCancellable *cancellable,
96 : : GError **error)
97 : : {
98 : : GSocketAddressEnumeratorClass *klass;
99 : :
100 : 2616 : g_return_val_if_fail (G_IS_SOCKET_ADDRESS_ENUMERATOR (enumerator), NULL);
101 : :
102 : 2616 : klass = G_SOCKET_ADDRESS_ENUMERATOR_GET_CLASS (enumerator);
103 : :
104 : 2616 : return (* klass->next) (enumerator, cancellable, error);
105 : : }
106 : :
107 : : /* Default implementation just calls the synchronous method; this can
108 : : * be used if the implementation already knows all of its addresses,
109 : : * and so the synchronous method will never block.
110 : : */
111 : : static void
112 : 291 : g_socket_address_enumerator_real_next_async (GSocketAddressEnumerator *enumerator,
113 : : GCancellable *cancellable,
114 : : GAsyncReadyCallback callback,
115 : : gpointer user_data)
116 : : {
117 : : GTask *task;
118 : : GSocketAddress *address;
119 : 291 : GError *error = NULL;
120 : :
121 : 291 : task = g_task_new (enumerator, NULL, callback, user_data);
122 : 291 : g_task_set_source_tag (task, g_socket_address_enumerator_real_next_async);
123 : :
124 : 291 : address = g_socket_address_enumerator_next (enumerator, cancellable, &error);
125 : 291 : if (error)
126 : 0 : g_task_return_error (task, error);
127 : : else
128 : 291 : g_task_return_pointer (task, address, g_object_unref);
129 : :
130 : 291 : g_object_unref (task);
131 : 291 : }
132 : :
133 : : /**
134 : : * g_socket_address_enumerator_next_async:
135 : : * @enumerator: a #GSocketAddressEnumerator
136 : : * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore.
137 : : * @callback: (scope async) (closure user_data): a #GAsyncReadyCallback to call
138 : : * when the request is satisfied
139 : : * @user_data: the data to pass to callback function
140 : : *
141 : : * Asynchronously retrieves the next #GSocketAddress from @enumerator
142 : : * and then calls @callback, which must call
143 : : * g_socket_address_enumerator_next_finish() to get the result.
144 : : *
145 : : * It is an error to call this multiple times before the previous callback has finished.
146 : : */
147 : : void
148 : 697 : g_socket_address_enumerator_next_async (GSocketAddressEnumerator *enumerator,
149 : : GCancellable *cancellable,
150 : : GAsyncReadyCallback callback,
151 : : gpointer user_data)
152 : : {
153 : : GSocketAddressEnumeratorClass *klass;
154 : :
155 : 697 : g_return_if_fail (G_IS_SOCKET_ADDRESS_ENUMERATOR (enumerator));
156 : :
157 : 697 : klass = G_SOCKET_ADDRESS_ENUMERATOR_GET_CLASS (enumerator);
158 : :
159 : 697 : (* klass->next_async) (enumerator, cancellable, callback, user_data);
160 : : }
161 : :
162 : : static GSocketAddress *
163 : 291 : g_socket_address_enumerator_real_next_finish (GSocketAddressEnumerator *enumerator,
164 : : GAsyncResult *result,
165 : : GError **error)
166 : : {
167 : 291 : g_return_val_if_fail (g_task_is_valid (result, enumerator), NULL);
168 : :
169 : 291 : return g_task_propagate_pointer (G_TASK (result), error);
170 : : }
171 : :
172 : : /**
173 : : * g_socket_address_enumerator_next_finish:
174 : : * @enumerator: a #GSocketAddressEnumerator
175 : : * @result: a #GAsyncResult
176 : : * @error: a #GError
177 : : *
178 : : * Retrieves the result of a completed call to
179 : : * g_socket_address_enumerator_next_async(). See
180 : : * g_socket_address_enumerator_next() for more information about
181 : : * error handling.
182 : : *
183 : : * Returns: (transfer full) (nullable): a #GSocketAddress (owned by the caller), or %NULL on
184 : : * error (in which case *@error will be set) or if there are no
185 : : * more addresses.
186 : : */
187 : : GSocketAddress *
188 : 694 : g_socket_address_enumerator_next_finish (GSocketAddressEnumerator *enumerator,
189 : : GAsyncResult *result,
190 : : GError **error)
191 : : {
192 : : GSocketAddressEnumeratorClass *klass;
193 : :
194 : 694 : g_return_val_if_fail (G_IS_SOCKET_ADDRESS_ENUMERATOR (enumerator), NULL);
195 : :
196 : 694 : klass = G_SOCKET_ADDRESS_ENUMERATOR_GET_CLASS (enumerator);
197 : :
198 : 694 : return (* klass->next_finish) (enumerator, result, error);
199 : : }
|