Starting on TcpClient, some formatting fixes
authorSamuel Cormier-Iijima <sciyoshi@gmail.com>
Fri, 29 Feb 2008 10:04:24 +0000 (05:04 -0500)
committerSamuel Cormier-Iijima <sciyoshi@gmail.com>
Fri, 29 Feb 2008 10:04:24 +0000 (05:04 -0500)
gnio/ginetaddress.c
gnio/ginetsocketaddress.c
gnio/ginetsocketaddress.h
gnio/gresolver.c
gnio/gsocket.c
gnio/gtcpclient.c
gnio/gtcpclient.h

index fbf8c67..3890727 100644 (file)
@@ -52,7 +52,10 @@ enum
 };
 
 static void
-g_inet_address_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
+g_inet_address_get_property (GObject    *object,
+                             guint       prop_id,
+                             GValue     *value,
+                             GParamSpec *pspec)
 {
   GInetAddress *address = G_INET_ADDRESS (object);
 
@@ -76,7 +79,10 @@ g_inet_address_get_property (GObject *object, guint prop_id, GValue *value, GPar
 }
 
 static void
-g_inet_address_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
+g_inet_address_set_property (GObject      *object,
+                             guint         prop_id,
+                             const GValue *value,
+                             GParamSpec   *pspec)
 {
   GInetAddress *address G_GNUC_UNUSED = G_INET_ADDRESS (object);
 
index f636162..040064a 100644 (file)
@@ -67,7 +67,10 @@ g_inet_socket_address_dispose (GObject *object)
 }
 
 static void
-g_inet_socket_address_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
+g_inet_socket_address_get_property (GObject    *object,
+                                    guint       prop_id,
+                                    GValue     *value,
+                                    GParamSpec *pspec)
 {
   GInetSocketAddress *address = G_INET_SOCKET_ADDRESS (object);
 
@@ -87,7 +90,10 @@ g_inet_socket_address_get_property (GObject *object, guint prop_id, GValue *valu
 }
 
 static void
-g_inet_socket_address_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
+g_inet_socket_address_set_property (GObject      *object,
+                                    guint         prop_id,
+                                    const GValue *value,
+                                    GParamSpec   *pspec)
 {
   GInetSocketAddress *address = G_INET_SOCKET_ADDRESS (object);
 
@@ -124,7 +130,8 @@ g_inet_socket_address_native_size (GSocketAddress *address)
 }
 
 static gboolean
-g_inet_socket_address_to_native (GSocketAddress *address, gpointer dest)
+g_inet_socket_address_to_native (GSocketAddress *address,
+                                 gpointer        dest)
 {
   GInetSocketAddress *addr;
 
@@ -196,7 +203,8 @@ g_inet_socket_address_init (GInetSocketAddress *address)
 
 
 GInetSocketAddress *
-g_inet_socket_address_new (GInetAddress *address, guint16 port)
+g_inet_socket_address_new (GInetAddress *address,
+                           guint16       port)
 {
   return G_INET_SOCKET_ADDRESS (g_object_new (G_TYPE_INET_SOCKET_ADDRESS, "address", address, "port", port, NULL));
 }
index 5982e55..fc44062 100644 (file)
@@ -55,7 +55,8 @@ struct _GInetSocketAddressClass
 
 GType                g_inet_socket_address_get_type    (void) G_GNUC_CONST;
 
-GInetSocketAddress * g_inet_socket_address_new         (GInetAddress *address, guint16 port);
+GInetSocketAddress * g_inet_socket_address_new         (GInetAddress *address,
+                                                        guint16       port);
 
 GInetAddress *       g_inet_socket_address_get_address (GInetSocketAddress *sockaddr);
 
index 8f76633..5a74b7c 100644 (file)
@@ -56,7 +56,7 @@ G_LOCK_DEFINE (dnslock);
 
 #ifdef G_OS_WIN32
 /* This is copied straight from giowin32.c, but its static there... */
-/* Is there another way to get this functionality? */
+/* TODO: is there another way to get this functionality? or maybe make this public? */
 static char *
 winsock_error_message (int number)
 {
@@ -406,7 +406,7 @@ g_resolver_init (GResolver *address)
 }
 
 typedef struct {
-  GList *list;
+  GList       *list;
   const gchar *host;
 } ResolveListData;
 
index 69a1b5c..605f92b 100644 (file)
@@ -70,7 +70,10 @@ struct _GSocketPrivate
 };
 
 static void
-g_socket_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
+g_socket_get_property (GObject    *object,
+                       guint       prop_id,
+                       GValue     *value,
+                       GParamSpec *pspec)
 {
   GSocket *socket = G_SOCKET (object);
 
@@ -106,7 +109,10 @@ g_socket_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec
 }
 
 static void
-g_socket_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
+g_socket_set_property (GObject      *object,
+                       guint         prop_id,
+                       const GValue *value,
+                       GParamSpec   *pspec)
 {
   GSocket *socket = G_SOCKET (object);
 
index 599358e..ae8de6d 100644 (file)
@@ -41,12 +41,13 @@ G_DEFINE_TYPE (GTcpClient, g_tcp_client, G_TYPE_OBJECT);
 
 enum
 {
-  PROP_0
+  PROP_0,
+  PROP_ADDRESS
 };
 
 struct _GTcpClientPrivate
 {
-
+  GSocketAddress *address;
 };
 
 static void
@@ -56,6 +57,10 @@ g_tcp_client_get_property (GObject *object, guint prop_id, GValue *value, GParam
 
   switch (prop_id)
     {
+      case PROP_ADDRESS:
+        g_value_set_object (value, client->priv->address);
+        break;
+
       default:
         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
     }
@@ -102,6 +107,13 @@ g_tcp_client_class_init (GTcpClientClass *klass)
   gobject_class->dispose = g_tcp_client_dispose;
   gobject_class->set_property = g_tcp_client_set_property;
   gobject_class->get_property = g_tcp_client_get_property;
+
+  g_object_class_install_property (gobject_class, PROP_ADDRESS,
+                                   g_param_spec_object ("address",
+                                                        "address",
+                                                        "the remote address the socket will connect to",
+                                                        G_TYPE_SOCKET_ADDRESS,
+                                                        G_TYPE_CONSTRUCT_ONLY | G_PARAM_READABLE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_BLURB | G_PARAM_STATIC_NICK));
 }
 
 static void
@@ -117,6 +129,131 @@ g_tcp_client_new (GInetSocketAddress *address,
   return NULL;
 }
 
+gboolean
+g_tcp_client_connect (GTcpClient *client,
+                      GError **error)
+{
+  return FALSE;
+}
+
+typedef struct {
+  GAsyncReadyCallback  callback;
+  GCancellable        *cancellable;
+  gpointer             user_data;
+  GSocket             *socket;
+  gchar                address_buffer[256];
+  gsize                address_length;
+} ConnectData;
+
+static gboolean
+connect_callback (ConnectData *data,
+                  GIOCondition condition,
+                  gint fd)
+{
+  GSocket *socket;
+  GSimpleAsyncResult *result = NULL;
+  gint sockerr = 0;
+  gsize sockerr_size = 1;
+
+  socket = data->socket;
+
+  if (condition & G_IO_OUT)
+    {
+      result = g_simple_async_result_new (G_OBJECT (socket), data->callback, data->user_data, g_socket_connect_async);
+    }
+  else if (condition & G_IO_ERR)
+    {
+      if (getsockopt (fd, SOL_SOCKET, SO_ERROR, (gpointer) &sockerr, &sockerr_size) < 0)
+        g_warning ("getsockopt: %s", g_strerror (errno));
+
+      if (sockerr != 0)
+        result = g_simple_async_result_new_error (G_OBJECT (socket), data->callback, data->user_data, G_IO_ERROR, g_io_error_from_errno (sockerr), "error connecting: %s", g_strerror (sockerr));
+      else
+        g_warning ("getsockopt SO_ERROR returned no error, with sockerr = %d", sockerr);
+    }
+
+  g_simple_async_result_complete (result);
+
+  g_object_unref (result);
+
+  return FALSE;
+}
+
+void
+g_socket_connect_async (GTcpClient          *client,
+                        GCancellable        *cancellable,
+                        GAsyncReadyCallback  callback,
+                        gpointer             user_data)
+{
+  GSource *source;
+  GSimpleAsyncResult *result;
+  ConnectData *data;
+  gint ret;
+  gchar buffer[256];
+  gsize len;
+
+  g_return_if_fail (G_IS_SOCKET (socket) && G_IS_SOCKET_ADDRESS (address));
+
+  if (g_socket_get_blocking (socket))
+    g_socket_set_blocking (socket, FALSE);
+
+  g_socket_address_to_native (address, buffer);
+
+  len = g_socket_address_native_size (address);
+
+  if ((ret = connect (socket->priv->fd, (struct sockaddr *) buffer, len)) < 0)
+    {
+      if (errno == EINPROGRESS)
+        {
+          source = _g_fd_source_new (socket->priv->fd, G_IO_OUT | G_IO_ERR, cancellable);
+
+          data = g_new (ConnectData, 1);
+
+          data->socket = socket;
+          data->callback = callback;
+          data->cancellable = cancellable;
+          data->user_data = user_data;
+          data->address_length = len;
+          memcpy (data->address_buffer, buffer, len);
+
+          g_source_set_callback (source, (GSourceFunc) connect_callback, data, g_free);
+
+          g_source_attach (source, NULL);
+        }
+      else
+        {
+          g_simple_async_report_error_in_idle (G_OBJECT (socket), callback, user_data, G_IO_ERROR, g_io_error_from_errno (errno), "error connecting: %s", g_strerror (errno));
+        }
+    }
+  else
+    {
+      result = g_simple_async_result_new (G_OBJECT (socket), callback, user_data, g_socket_connect_async);
+
+      g_simple_async_result_complete_in_idle (result);
+
+      g_object_unref (result);
+    }
+}
+
+gboolean
+g_socket_connect_finish (GSocket       *socket,
+                         GAsyncResult  *result,
+                         GError       **error)
+{
+  GSimpleAsyncResult *simple;
+
+  g_return_val_if_fail (G_IS_SOCKET (socket), FALSE);
+
+  simple = G_SIMPLE_ASYNC_RESULT (result);
+
+  if (g_simple_async_result_propagate_error (simple, error))
+    return FALSE;
+
+  g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_socket_connect_async);
+
+  return TRUE;
+}
+
 void
 g_tcp_client_close (GTcpClient *tcp_client)
 {
index f461221..8a1bf7f 100644 (file)
@@ -56,12 +56,27 @@ struct _GTcpClientClass
   GObjectClass parent_class;
 };
 
-GType               g_tcp_client_get_type      (void) G_GNUC_CONST;
+GType            g_tcp_client_get_type         (void) G_GNUC_CONST;
 
-GTcpClient *        g_tcp_client_new           (GInetSocketAddress  *address,
-                                                GError             **error);
+GTcpClient *     g_tcp_client_new              (const gchar *hostname,
+                                                gushort      port);
 
-void                g_tcp_client_close         (GTcpClient    *client);
+GTcpClient *     g_tcp_client_new_from_address (GInetSocketAddress *address);
+
+gboolean         g_tcp_client_connect          (GTcpClient      *clientt,
+                                                GCancellable    *cancellable,
+                                                GError         **error);
+
+void             g_tcp_client_connect_async    (GTcpClient          *client,
+                                                GCancellable        *cancellable,
+                                                GAsyncReadyCallback  callback,
+                                                gpointer             user_data);
+
+gboolean         g_tcp_client_connect_finish   (GTcpClient    *client,
+                                                GAsyncResult  *result,
+                                                GError       **error);
+
+void             g_tcp_client_close            (GTcpClient    *client);
 
 G_END_DECLS