It compiles!
[cascardo/gnio.git] / gnio / gtcpclient.c
index c46108c..c732a59 100644 (file)
@@ -246,7 +246,7 @@ g_tcp_client_connect (GTcpClient    *client,
     }
   else
     {
-     address = g_inet_socket_address_get_address (client->priv->address);
+      address = g_inet_socket_address_get_address (client->priv->address);
     }
 
   if (G_IS_INET4_ADDRESS (address))
@@ -276,19 +276,37 @@ typedef struct {
   GCancellable        *cancellable;
   gpointer             user_data;
   GTcpClient          *client;
-  gchar                address_buffer[256];
-  gsize                address_length;
 } ConnectData;
 
-/*
 static gboolean
 connect_callback (ConnectData *data,
                   GIOCondition condition,
                   gint fd)
 {
+  GTcpClient *client;
+  GSimpleAsyncResult *result;
+  GError *error = NULL;
+
+  client = data->client;
+
+  if (condition & G_IO_OUT)
+    {
+      result = g_simple_async_result_new (G_OBJECT (client), data->callback, data->user_data, g_tcp_client_connect_async);
+    }
+  else if (condition & G_IO_ERR)
+    {
+      if (!g_socket_has_socket_error (client->priv->socket, &error))
+        g_warning ("got G_IO_ERR but socket does not have error");
+
+      result = g_simple_async_result_new_from_error (G_OBJECT (client), data->callback, data->user_data, error);
+    }
+
+  g_simple_async_result_complete (result);
+
+  g_object_unref (result);
+
   return FALSE;
 }
-*/
 
 void
 g_tcp_client_connect_async (GTcpClient          *client,
@@ -296,7 +314,73 @@ g_tcp_client_connect_async (GTcpClient          *client,
                             GAsyncReadyCallback  callback,
                             gpointer             user_data)
 {
+  GInetAddress *address;
+  GSimpleAsyncResult *result;
+  GSource *source;
+  ConnectData *data;
+  GError *error = NULL;
+
+  g_return_if_fail (G_IS_TCP_CLIENT (client));
+
+  if (!client->priv->address)
+    {
+      // we've been constructed with just hostname+port, resolve
+      // GResolver *resolver = g_resolver_new ();
+      return;
+    }
 
+  address = g_inet_socket_address_get_address (client->priv->address);
+
+  if (G_IS_INET4_ADDRESS (address))
+    client->priv->socket = g_socket_new (G_SOCKET_DOMAIN_INET, G_SOCKET_TYPE_STREAM, NULL, &error);
+  else if (G_IS_INET6_ADDRESS (address))
+    client->priv->socket = g_socket_new (G_SOCKET_DOMAIN_INET6, G_SOCKET_TYPE_STREAM, NULL, &error);
+  else
+    {
+      g_simple_async_report_error_in_idle (G_OBJECT (client), callback, user_data, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, "unsupported address domain");
+      return;
+    }
+
+  if (!client->priv->socket)
+    {
+      g_simple_async_report_gerror_in_idle (G_OBJECT (client), callback, user_data, error);
+      return;
+    }
+
+  g_socket_set_blocking (client->priv->socket, FALSE);
+
+  if (!g_socket_connect (client->priv->socket, G_SOCKET_ADDRESS (client->priv->address), &error))
+    {
+      if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_PENDING))
+        {
+          // the connection is in progress
+          source = g_socket_create_source (client->priv->socket, G_IO_OUT | G_IO_ERR, cancellable);
+
+          data = g_new (ConnectData, 1);
+
+          data->client = client;
+          data->callback = callback;
+          data->cancellable = cancellable;
+          data->user_data = user_data;
+
+          g_source_set_callback (source, (GSourceFunc) connect_callback, data, g_free);
+
+          g_source_attach (source, NULL);
+        }
+      else
+        {
+          g_simple_async_report_gerror_in_idle (G_OBJECT (client), callback, user_data, error);
+        }
+    }
+  else
+    {
+      // the connection is already completed
+      result = g_simple_async_result_new (G_OBJECT (client), callback, user_data, g_tcp_client_connect_async);
+
+      g_simple_async_result_complete_in_idle (result);
+
+      g_object_unref (result);
+    }
 }
 
 gboolean