Add a lot of missing annotations
[platform/upstream/glib.git] / gio / ginetsocketaddress.c
1 /* GIO - GLib Input, Output and Streaming Library
2  *
3  * Copyright (C) 2008 Christian Kellner, Samuel Cormier-Iijima
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library 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 GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General
16  * Public License along with this library; if not, write to the
17  * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
18  * Boston, MA 02111-1307, USA.
19  *
20  * Authors: Christian Kellner <gicmo@gnome.org>
21  *          Samuel Cormier-Iijima <sciyoshi@gmail.com>
22  */
23
24 #include <config.h>
25 #include <glib.h>
26 #include <string.h>
27
28 #include "ginetsocketaddress.h"
29 #include "ginetaddress.h"
30 #include "gnetworkingprivate.h"
31 #include "gioerror.h"
32 #include "glibintl.h"
33
34
35 /**
36  * SECTION:ginetsocketaddress
37  * @short_description: Internet GSocketAddress
38  *
39  * An IPv4 or IPv6 socket address; that is, the combination of a
40  * #GInetAddress and a port number.
41  */
42
43 /**
44  * GInetSocketAddress:
45  *
46  * An IPv4 or IPv6 socket address, corresponding to a <type>struct
47  * sockaddr_in</type> or <type>struct sockaddr_in6</type>.
48  */
49 G_DEFINE_TYPE (GInetSocketAddress, g_inet_socket_address, G_TYPE_SOCKET_ADDRESS);
50
51 enum {
52   PROP_0,
53   PROP_ADDRESS,
54   PROP_PORT
55 };
56
57 struct _GInetSocketAddressPrivate
58 {
59   GInetAddress *address;
60   guint16       port;
61 };
62
63 static void
64 g_inet_socket_address_finalize (GObject *object)
65 {
66   GInetSocketAddress *address G_GNUC_UNUSED = G_INET_SOCKET_ADDRESS (object);
67
68   if (G_OBJECT_CLASS (g_inet_socket_address_parent_class)->finalize)
69     (*G_OBJECT_CLASS (g_inet_socket_address_parent_class)->finalize) (object);
70 }
71
72 static void
73 g_inet_socket_address_dispose (GObject *object)
74 {
75   GInetSocketAddress *address G_GNUC_UNUSED = G_INET_SOCKET_ADDRESS (object);
76
77   g_object_unref (address->priv->address);
78
79   if (G_OBJECT_CLASS (g_inet_socket_address_parent_class)->dispose)
80     (*G_OBJECT_CLASS (g_inet_socket_address_parent_class)->dispose) (object);
81 }
82
83 static void
84 g_inet_socket_address_get_property (GObject    *object,
85                                     guint       prop_id,
86                                     GValue     *value,
87                                     GParamSpec *pspec)
88 {
89   GInetSocketAddress *address = G_INET_SOCKET_ADDRESS (object);
90
91   switch (prop_id)
92     {
93       case PROP_ADDRESS:
94         g_value_set_object (value, address->priv->address);
95         break;
96
97       case PROP_PORT:
98         g_value_set_uint (value, address->priv->port);
99         break;
100
101       default:
102         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
103     }
104 }
105
106 static void
107 g_inet_socket_address_set_property (GObject      *object,
108                                     guint         prop_id,
109                                     const GValue *value,
110                                     GParamSpec   *pspec)
111 {
112   GInetSocketAddress *address = G_INET_SOCKET_ADDRESS (object);
113
114   switch (prop_id)
115     {
116       case PROP_ADDRESS:
117         address->priv->address = g_object_ref (g_value_get_object (value));
118         break;
119
120       case PROP_PORT:
121         address->priv->port = (guint16) g_value_get_uint (value);
122         break;
123
124       default:
125         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
126     }
127 }
128
129 static GSocketFamily
130 g_inet_socket_address_get_family (GSocketAddress *address)
131 {
132   GInetSocketAddress *addr;
133
134   g_return_val_if_fail (G_IS_INET_SOCKET_ADDRESS (address), 0);
135
136   addr = G_INET_SOCKET_ADDRESS (address);
137
138   return g_inet_address_get_family (addr->priv->address);
139 }
140
141 static gssize
142 g_inet_socket_address_get_native_size (GSocketAddress *address)
143 {
144   GInetSocketAddress *addr;
145   GSocketFamily family;
146
147   g_return_val_if_fail (G_IS_INET_SOCKET_ADDRESS (address), 0);
148
149   addr = G_INET_SOCKET_ADDRESS (address);
150   family = g_inet_address_get_family (addr->priv->address);
151
152   if (family == AF_INET)
153     return sizeof (struct sockaddr_in);
154   else if (family == AF_INET6)
155     return sizeof (struct sockaddr_in6);
156   else
157     return -1;
158 }
159
160 static gboolean
161 g_inet_socket_address_to_native (GSocketAddress  *address,
162                                  gpointer         dest,
163                                  gsize            destlen,
164                                  GError         **error)
165 {
166   GInetSocketAddress *addr;
167   GSocketFamily family;
168
169   g_return_val_if_fail (G_IS_INET_SOCKET_ADDRESS (address), FALSE);
170
171   addr = G_INET_SOCKET_ADDRESS (address);
172   family = g_inet_address_get_family (addr->priv->address);
173
174   if (family == AF_INET)
175     {
176       struct sockaddr_in *sock = (struct sockaddr_in *) dest;
177
178       if (destlen < sizeof (*sock))
179         {
180           g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NO_SPACE,
181                                _("Not enough space for socket address"));
182           return FALSE;
183         }
184
185       sock->sin_family = AF_INET;
186       sock->sin_port = g_htons (addr->priv->port);
187       memcpy (&(sock->sin_addr.s_addr), g_inet_address_to_bytes (addr->priv->address), sizeof (sock->sin_addr));
188       memset (sock->sin_zero, 0, sizeof (sock->sin_zero));
189       return TRUE;
190     }
191   else if (family == AF_INET6)
192     {
193       struct sockaddr_in6 *sock = (struct sockaddr_in6 *) dest;
194
195       if (destlen < sizeof (*sock))
196         {
197           g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NO_SPACE,
198                                _("Not enough space for socket address"));
199           return FALSE;
200         }
201
202       memset (sock, 0, sizeof (*sock));
203       sock->sin6_family = AF_INET6;
204       sock->sin6_port = g_htons (addr->priv->port);
205       memcpy (&(sock->sin6_addr.s6_addr), g_inet_address_to_bytes (addr->priv->address), sizeof (sock->sin6_addr));
206       return TRUE;
207     }
208   else
209     {
210       g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
211                            _("Unsupported socket address"));
212       return FALSE;
213     }
214 }
215
216 static void
217 g_inet_socket_address_class_init (GInetSocketAddressClass *klass)
218 {
219   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
220   GSocketAddressClass *gsocketaddress_class = G_SOCKET_ADDRESS_CLASS (klass);
221
222   g_type_class_add_private (klass, sizeof (GInetSocketAddressPrivate));
223
224   gobject_class->finalize = g_inet_socket_address_finalize;
225   gobject_class->dispose = g_inet_socket_address_dispose;
226   gobject_class->set_property = g_inet_socket_address_set_property;
227   gobject_class->get_property = g_inet_socket_address_get_property;
228
229   gsocketaddress_class->get_family = g_inet_socket_address_get_family;
230   gsocketaddress_class->to_native = g_inet_socket_address_to_native;
231   gsocketaddress_class->get_native_size = g_inet_socket_address_get_native_size;
232
233   g_object_class_install_property (gobject_class, PROP_ADDRESS,
234                                    g_param_spec_object ("address",
235                                                         P_("Address"),
236                                                         P_("The address"),
237                                                         G_TYPE_INET_ADDRESS,
238                                                         G_PARAM_CONSTRUCT_ONLY |
239                                                         G_PARAM_READWRITE |
240                                                         G_PARAM_STATIC_STRINGS));
241
242   g_object_class_install_property (gobject_class, PROP_PORT,
243                                    g_param_spec_uint ("port",
244                                                       P_("Port"),
245                                                       P_("The port"),
246                                                       0,
247                                                       65535,
248                                                       0,
249                                                       G_PARAM_CONSTRUCT_ONLY |
250                                                       G_PARAM_READWRITE |
251                                                       G_PARAM_STATIC_STRINGS));
252 }
253
254 static void
255 g_inet_socket_address_init (GInetSocketAddress *address)
256 {
257   address->priv = G_TYPE_INSTANCE_GET_PRIVATE (address,
258                                                G_TYPE_INET_SOCKET_ADDRESS,
259                                                GInetSocketAddressPrivate);
260
261   address->priv->address = NULL;
262   address->priv->port = 0;
263 }
264
265 /**
266  * g_inet_socket_address_new:
267  * @address: a #GInetAddress
268  * @port: a port number
269  *
270  * Creates a new #GInetSocketAddress for @address and @port.
271  *
272  * Returns: a new #GInetSocketAddress
273  *
274  * Since: 2.22
275  */
276 GSocketAddress *
277 g_inet_socket_address_new (GInetAddress *address,
278                            guint16       port)
279 {
280   return g_object_new (G_TYPE_INET_SOCKET_ADDRESS,
281                        "address", address,
282                        "port", port,
283                        NULL);
284 }
285
286 /**
287  * g_inet_socket_address_get_address:
288  * @address: a #GInetSocketAddress
289  *
290  * Gets @address's #GInetAddress.
291  *
292  * Returns: (transfer full): the #GInetAddress for @address, which must be
293  * g_object_ref()'d if it will be stored
294  *
295  * Since: 2.22
296  */
297 GInetAddress *
298 g_inet_socket_address_get_address (GInetSocketAddress *address)
299 {
300   g_return_val_if_fail (G_IS_INET_SOCKET_ADDRESS (address), NULL);
301
302   return address->priv->address;
303 }
304
305 /**
306  * g_inet_socket_address_get_port:
307  * @address: a #GInetSocketAddress
308  *
309  * Gets @address's port.
310  *
311  * Returns: the port for @address
312  *
313  * Since: 2.22
314  */
315 guint16
316 g_inet_socket_address_get_port (GInetSocketAddress *address)
317 {
318   g_return_val_if_fail (G_IS_INET_SOCKET_ADDRESS (address), 0);
319
320   return address->priv->port;
321 }