Converting InetAddresses to native struct in*_addr and SocketAddresses to struct...
[cascardo/gnio.git] / gnio / ginetsocketaddress.c
index 6b2d7b1..5913aee 100644 (file)
 
 #include <config.h>
 #include <glib.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
 
 #include "ginetsocketaddress.h"
+#include "ginetaddress.h"
+#include "ginet4address.h"
+#include "ginet6address.h"
 
 G_DEFINE_TYPE (GInetSocketAddress, g_inet_socket_address, G_TYPE_SOCKET_ADDRESS);
 
@@ -94,10 +100,55 @@ g_inet_socket_address_set_property (GObject *object, guint prop_id, const GValue
     }
 }
 
+static gssize
+g_inet_socket_address_native_size (GSocketAddress *address)
+{
+  GInetSocketAddress *addr;
+
+  g_return_val_if_fail (G_IS_INET_SOCKET_ADDRESS (address), 0);
+
+  addr = G_INET_SOCKET_ADDRESS (address);
+
+  if (G_IS_INET4_ADDRESS (addr->priv->address))
+    return sizeof (struct sockaddr_in);
+  else if (G_IS_INET6_ADDRESS (addr->priv->address))
+    return sizeof (struct sockaddr_in6);
+  else
+    return -1;
+}
+
+static gboolean
+g_inet_socket_address_to_native (GSocketAddress *address, gpointer dest)
+{
+  GInetSocketAddress *addr;
+
+  g_return_val_if_fail (G_IS_INET_SOCKET_ADDRESS (address), 0);
+
+  addr = G_INET_SOCKET_ADDRESS (address);
+
+  if (G_IS_INET4_ADDRESS (addr->priv->address))
+    {
+      struct sockaddr_in *sock = (struct sockaddr_in *) dest;
+
+      sock->sin_family = AF_INET;
+      sock->sin_port = addr->priv->port;
+      memcpy (&(sock->sin_addr.s_addr), g_inet4_address_to_bytes (G_INET4_ADDRESS (addr->priv->address)), sizeof (sock->sin_addr));
+      memset (sock->sin_zero, 0, sizeof (sock->sin_zero));
+      return TRUE;
+    }
+  else if (G_IS_INET6_ADDRESS (addr->priv->address))
+    {
+      return FALSE;
+    }
+  else
+    return FALSE;
+}
+
 static void
 g_inet_socket_address_class_init (GInetSocketAddressClass *klass)
 {
   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+  GSocketAddressClass *gsocketaddress_class = G_SOCKET_ADDRESS_CLASS (klass);
 
   g_type_class_add_private (klass, sizeof (GInetSocketAddressPrivate));
 
@@ -106,6 +157,9 @@ g_inet_socket_address_class_init (GInetSocketAddressClass *klass)
   gobject_class->set_property = g_inet_socket_address_set_property;
   gobject_class->get_property = g_inet_socket_address_get_property;
 
+  gsocketaddress_class->to_native = g_inet_socket_address_to_native;
+  gsocketaddress_class->native_size = g_inet_socket_address_native_size;
+
   g_object_class_install_property (gobject_class, PROP_ADDRESS,
                                    g_param_spec_object ("address",
                                                         "address",
@@ -129,6 +183,9 @@ g_inet_socket_address_init (GInetSocketAddress *address)
   address->priv = G_TYPE_INSTANCE_GET_PRIVATE (address,
                                                G_TYPE_INET_SOCKET_ADDRESS,
                                                GInetSocketAddressPrivate);
+
+  address->priv->address = NULL;
+  address->priv->port = 0;
 }