(root)/
glib-2.79.0/
gio/
gsocketconnectable.c
       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 "gsocketconnectable.h"
      23  #include "glibintl.h"
      24  
      25  
      26  /**
      27   * GSocketConnectable:
      28   *
      29   * Objects that describe one or more potential socket endpoints
      30   * implement `GSocketConnectable`. Callers can then use
      31   * [method@Gio.SocketConnectable.enumerate] to get a
      32   * [class@Gio.SocketAddressEnumerator] to try out each socket address in turn
      33   * until one succeeds, as shown in the sample code below.
      34   *
      35   * ```c
      36   * MyConnectionType *
      37   * connect_to_host (const char    *hostname,
      38   *                  guint16        port,
      39   *                  GCancellable  *cancellable,
      40   *                  GError       **error)
      41   * {
      42   *   MyConnection *conn = NULL;
      43   *   GSocketConnectable *addr;
      44   *   GSocketAddressEnumerator *enumerator;
      45   *   GSocketAddress *sockaddr;
      46   *   GError *conn_error = NULL;
      47   *
      48   *   addr = g_network_address_new (hostname, port);
      49   *   enumerator = g_socket_connectable_enumerate (addr);
      50   *   g_object_unref (addr);
      51   *
      52   *   // Try each sockaddr until we succeed. Record the first connection error,
      53   *   // but not any further ones (since they'll probably be basically the same
      54   *   // as the first).
      55   *   while (!conn && (sockaddr = g_socket_address_enumerator_next (enumerator, cancellable, error))
      56   *     {
      57   *       conn = connect_to_sockaddr (sockaddr, conn_error ? NULL : &conn_error);
      58   *       g_object_unref (sockaddr);
      59   *     }
      60   *   g_object_unref (enumerator);
      61   *
      62   *   if (conn)
      63   *     {
      64   *       if (conn_error)
      65   *         {
      66   *           // We couldn't connect to the first address, but we succeeded
      67   *           // in connecting to a later address.
      68   *           g_error_free (conn_error);
      69   *         }
      70   *       return conn;
      71   *     }
      72   *   else if (error)
      73   *     {
      74   *       /// Either initial lookup failed, or else the caller cancelled us.
      75   *       if (conn_error)
      76   *         g_error_free (conn_error);
      77   *       return NULL;
      78   *     }
      79   *   else
      80   *     {
      81   *       g_error_propagate (error, conn_error);
      82   *       return NULL;
      83   *     }
      84   * }
      85   * ```
      86   */
      87  
      88  
      89  typedef GSocketConnectableIface GSocketConnectableInterface;
      90  G_DEFINE_INTERFACE (GSocketConnectable, g_socket_connectable, G_TYPE_OBJECT)
      91  
      92  static void
      93  g_socket_connectable_default_init (GSocketConnectableInterface *iface)
      94  {
      95  }
      96  
      97  /**
      98   * g_socket_connectable_enumerate:
      99   * @connectable: a #GSocketConnectable
     100   *
     101   * Creates a #GSocketAddressEnumerator for @connectable.
     102   *
     103   * Returns: (transfer full): a new #GSocketAddressEnumerator.
     104   *
     105   * Since: 2.22
     106   */
     107  GSocketAddressEnumerator *
     108  g_socket_connectable_enumerate (GSocketConnectable *connectable)
     109  {
     110    GSocketConnectableIface *iface;
     111  
     112    g_return_val_if_fail (G_IS_SOCKET_CONNECTABLE (connectable), NULL);
     113  
     114    iface = G_SOCKET_CONNECTABLE_GET_IFACE (connectable);
     115  
     116    return (* iface->enumerate) (connectable);
     117  }
     118  
     119  /**
     120   * g_socket_connectable_proxy_enumerate:
     121   * @connectable: a #GSocketConnectable
     122   *
     123   * Creates a #GSocketAddressEnumerator for @connectable that will
     124   * return a #GProxyAddress for each of its addresses that you must connect
     125   * to via a proxy.
     126   *
     127   * If @connectable does not implement
     128   * g_socket_connectable_proxy_enumerate(), this will fall back to
     129   * calling g_socket_connectable_enumerate().
     130   *
     131   * Returns: (transfer full): a new #GSocketAddressEnumerator.
     132   *
     133   * Since: 2.26
     134   */
     135  GSocketAddressEnumerator *
     136  g_socket_connectable_proxy_enumerate (GSocketConnectable *connectable)
     137  {
     138    GSocketConnectableIface *iface;
     139  
     140    g_return_val_if_fail (G_IS_SOCKET_CONNECTABLE (connectable), NULL);
     141  
     142    iface = G_SOCKET_CONNECTABLE_GET_IFACE (connectable);
     143  
     144    if (iface->proxy_enumerate)
     145      return (* iface->proxy_enumerate) (connectable);
     146    else
     147      return (* iface->enumerate) (connectable);
     148  }
     149  
     150  /**
     151   * g_socket_connectable_to_string:
     152   * @connectable: a #GSocketConnectable
     153   *
     154   * Format a #GSocketConnectable as a string. This is a human-readable format for
     155   * use in debugging output, and is not a stable serialization format. It is not
     156   * suitable for use in user interfaces as it exposes too much information for a
     157   * user.
     158   *
     159   * If the #GSocketConnectable implementation does not support string formatting,
     160   * the implementation’s type name will be returned as a fallback.
     161   *
     162   * Returns: (transfer full): the formatted string
     163   *
     164   * Since: 2.48
     165   */
     166  gchar *
     167  g_socket_connectable_to_string (GSocketConnectable *connectable)
     168  {
     169    GSocketConnectableIface *iface;
     170  
     171    g_return_val_if_fail (G_IS_SOCKET_CONNECTABLE (connectable), NULL);
     172  
     173    iface = G_SOCKET_CONNECTABLE_GET_IFACE (connectable);
     174  
     175    if (iface->to_string != NULL)
     176      return iface->to_string (connectable);
     177    else
     178      return g_strdup (G_OBJECT_TYPE_NAME (connectable));
     179  }