}
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))
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,
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