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 [ + + + - : 407 : 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 : 126 : g_native_socket_address_to_native (GSocketAddress *address, 94 : : gpointer dest, 95 : : gsize destlen, 96 : : GError **error) 97 : : { 98 : : GNativeSocketAddress *addr; 99 : : 100 : 126 : g_return_val_if_fail (G_IS_NATIVE_SOCKET_ADDRESS (address), FALSE); 101 : : 102 : 126 : addr = G_NATIVE_SOCKET_ADDRESS (address); 103 : : 104 [ - + ]: 126 : 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 : 126 : memcpy (dest, addr->priv->sockaddr, addr->priv->sockaddr_len); 112 : 126 : 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 : : }