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