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.1 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, see <http://www.gnu.org/licenses/>. |
17 | * |
18 | * Authors: Christian Kellner <gicmo@gnome.org> |
19 | * Samuel Cormier-Iijima <sciyoshi@gmail.com> |
20 | */ |
21 | |
22 | #include <config.h> |
23 | #include <glib.h> |
24 | #include <string.h> |
25 | |
26 | #include "gnativesocketaddress.h" |
27 | #include "gnetworkingprivate.h" |
28 | #include "gioerror.h" |
29 | #include "glibintl.h" |
30 | |
31 | |
32 | /** |
33 | * SECTION:gnativesocketaddress |
34 | * @short_description: Native GSocketAddress |
35 | * @include: gio/gio.h |
36 | * |
37 | * A socket address of some unknown native type. |
38 | */ |
39 | |
40 | /** |
41 | * GNativeSocketAddress: |
42 | * |
43 | * A socket address, corresponding to a general struct |
44 | * sockadd address of a type not otherwise handled by glib. |
45 | */ |
46 | |
47 | struct _GNativeSocketAddressPrivate |
48 | { |
49 | struct sockaddr *sockaddr; |
50 | union { |
51 | struct sockaddr_storage storage; |
52 | struct sockaddr sa; |
53 | } storage; |
54 | gsize sockaddr_len; |
55 | }; |
56 | |
57 | G_DEFINE_TYPE_WITH_PRIVATE (GNativeSocketAddress, g_native_socket_address, G_TYPE_SOCKET_ADDRESS) |
58 | |
59 | static void |
60 | g_native_socket_address_dispose (GObject *object) |
61 | { |
62 | GNativeSocketAddress *address = G_NATIVE_SOCKET_ADDRESS (object); |
63 | |
64 | if (address->priv->sockaddr != &address->priv->storage.sa) |
65 | g_free (mem: address->priv->sockaddr); |
66 | |
67 | G_OBJECT_CLASS (g_native_socket_address_parent_class)->dispose (object); |
68 | } |
69 | |
70 | static GSocketFamily |
71 | g_native_socket_address_get_family (GSocketAddress *address) |
72 | { |
73 | GNativeSocketAddress *addr; |
74 | |
75 | g_return_val_if_fail (G_IS_NATIVE_SOCKET_ADDRESS (address), 0); |
76 | |
77 | addr = G_NATIVE_SOCKET_ADDRESS (address); |
78 | |
79 | return addr->priv->sockaddr->sa_family; |
80 | } |
81 | |
82 | static gssize |
83 | g_native_socket_address_get_native_size (GSocketAddress *address) |
84 | { |
85 | GNativeSocketAddress *addr; |
86 | |
87 | g_return_val_if_fail (G_IS_NATIVE_SOCKET_ADDRESS (address), 0); |
88 | |
89 | addr = G_NATIVE_SOCKET_ADDRESS (address); |
90 | |
91 | return addr->priv->sockaddr_len; |
92 | } |
93 | |
94 | static gboolean |
95 | g_native_socket_address_to_native (GSocketAddress *address, |
96 | gpointer dest, |
97 | gsize destlen, |
98 | GError **error) |
99 | { |
100 | GNativeSocketAddress *addr; |
101 | |
102 | g_return_val_if_fail (G_IS_NATIVE_SOCKET_ADDRESS (address), FALSE); |
103 | |
104 | addr = G_NATIVE_SOCKET_ADDRESS (address); |
105 | |
106 | if (destlen < addr->priv->sockaddr_len) |
107 | { |
108 | g_set_error_literal (err: error, G_IO_ERROR, code: G_IO_ERROR_NO_SPACE, |
109 | _("Not enough space for socket address" )); |
110 | return FALSE; |
111 | } |
112 | |
113 | memcpy (dest: dest, src: addr->priv->sockaddr, n: addr->priv->sockaddr_len); |
114 | return TRUE; |
115 | } |
116 | |
117 | static void |
118 | g_native_socket_address_class_init (GNativeSocketAddressClass *klass) |
119 | { |
120 | GObjectClass *gobject_class = G_OBJECT_CLASS (klass); |
121 | GSocketAddressClass *gsocketaddress_class = G_SOCKET_ADDRESS_CLASS (klass); |
122 | |
123 | gobject_class->dispose = g_native_socket_address_dispose; |
124 | |
125 | gsocketaddress_class->get_family = g_native_socket_address_get_family; |
126 | gsocketaddress_class->to_native = g_native_socket_address_to_native; |
127 | gsocketaddress_class->get_native_size = g_native_socket_address_get_native_size; |
128 | } |
129 | |
130 | static void |
131 | g_native_socket_address_init (GNativeSocketAddress *address) |
132 | { |
133 | address->priv = g_native_socket_address_get_instance_private (self: address); |
134 | } |
135 | |
136 | /** |
137 | * g_native_socket_address_new: |
138 | * @native: a native address object |
139 | * @len: the length of @native, in bytes |
140 | * |
141 | * Creates a new #GNativeSocketAddress for @native and @len. |
142 | * |
143 | * Returns: a new #GNativeSocketAddress |
144 | * |
145 | * Since: 2.46 |
146 | */ |
147 | GSocketAddress * |
148 | g_native_socket_address_new (gpointer native, |
149 | gsize len) |
150 | { |
151 | GNativeSocketAddress *addr; |
152 | |
153 | addr = g_object_new (G_TYPE_NATIVE_SOCKET_ADDRESS, NULL); |
154 | |
155 | if (len <= sizeof(addr->priv->storage)) |
156 | addr->priv->sockaddr = &addr->priv->storage.sa; |
157 | else |
158 | addr->priv->sockaddr = g_malloc (n_bytes: len); |
159 | |
160 | memcpy (dest: addr->priv->sockaddr, src: native, n: len); |
161 | addr->priv->sockaddr_len = len; |
162 | return G_SOCKET_ADDRESS (addr); |
163 | } |
164 | |