Make GSSDPSocketSource a GObject
authorJens Georg <mail@jensge.org>
Tue, 7 Sep 2010 21:14:15 +0000 (23:14 +0200)
committerZeeshan Ali (Khattak) <zeeshanak@gnome.org>
Sun, 10 Oct 2010 19:24:22 +0000 (22:24 +0300)
libgssdp/gssdp-client.c
libgssdp/gssdp-socket-source.c
libgssdp/gssdp-socket-source.h

index ffa2de3..4819734 100644 (file)
@@ -138,11 +138,10 @@ gssdp_client_constructed (GObject *object)
                                          gssdp_client_get_host_ip (client),
                                          &error);
         if (client->priv->request_socket != NULL) {
-                g_source_set_callback
-                        (client->priv->request_socket->source,
-                         (GSourceFunc) request_socket_source_cb,
-                         client,
-                         NULL);
+                gssdp_socket_source_set_callback
+                        (client->priv->request_socket,
+                        (GSourceFunc) request_socket_source_cb,
+                        client);
         } else {
                 goto errors;
         }
@@ -152,11 +151,10 @@ gssdp_client_constructed (GObject *object)
                                          gssdp_client_get_host_ip (client),
                                          &error);
         if (client->priv->multicast_socket != NULL) {
-                g_source_set_callback
-                        (client->priv->multicast_socket->source,
+                gssdp_socket_source_set_callback
+                        (client->priv->multicast_socket,
                          (GSourceFunc) multicast_socket_source_cb,
-                         client,
-                         NULL);
+                         client);
         }
 
  errors:
@@ -167,13 +165,11 @@ gssdp_client_constructed (GObject *object)
                 return;
         }
 
-        g_source_attach (client->priv->request_socket->source,
-                         client->priv->main_context);
-        g_source_unref (client->priv->request_socket->source);
+        gssdp_socket_source_attach (client->priv->request_socket,
+                                    client->priv->main_context);
 
-        g_source_attach (client->priv->multicast_socket->source,
-                         client->priv->main_context);
-        g_source_unref (client->priv->multicast_socket->source);
+        gssdp_socket_source_attach (client->priv->multicast_socket,
+                                    client->priv->main_context);
 }
 
 static void
@@ -258,12 +254,12 @@ gssdp_client_dispose (GObject *object)
 
         /* Destroy the SocketSources */
         if (client->priv->request_socket) {
-                gssdp_socket_source_destroy (client->priv->request_socket);
+                g_object_unref (client->priv->request_socket);
                 client->priv->request_socket = NULL;
         }
 
         if (client->priv->multicast_socket) {
-                gssdp_socket_source_destroy (client->priv->multicast_socket);
+                g_object_unref (client->priv->multicast_socket);
                 client->priv->multicast_socket = NULL;
         }
 
index e52fe48..bf7b955 100644 (file)
 #include "gssdp-protocol.h"
 #include "gssdp-error.h"
 
+static void
+gssdp_socket_source_initable_init (gpointer g_iface,
+                                   gpointer iface_data);
+
+G_DEFINE_TYPE_EXTENDED (GSSDPSocketSource,
+                        gssdp_socket_source,
+                        G_TYPE_OBJECT,
+                        0,
+                        G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
+                                    gssdp_socket_source_initable_init));
+
+struct _GSSDPSocketSourcePrivate {
+        GSource              *source;
+        GSocket              *socket;
+        GSSDPSocketSourceType type;
+        char                 *host_ip;
+};
+
+enum {
+    PROP_0,
+    PROP_TYPE,
+    PROP_HOST_IP
+};
+
+static void
+gssdp_socket_source_init (GSSDPSocketSource *self)
+{
+        self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
+                                                  GSSDP_TYPE_SOCKET_SOURCE,
+                                                  GSSDPSocketSourcePrivate);
+}
+
+static gboolean
+gssdp_socket_source_do_init (GInitable     *initable,
+                             GCancellable  *cancellable,
+                             GError       **error);
+
+static void
+gssdp_socket_source_initable_init (gpointer g_iface,
+                                   gpointer iface_data)
+{
+        GInitableIface *iface = (GInitableIface *)g_iface;
+        iface->init = gssdp_socket_source_do_init;
+}
+
+static void
+gssdp_socket_source_get_property (GObject    *object,
+                                  guint       property_id,
+                                  GValue     *value,
+                                  GParamSpec *pspec)
+{
+        GSSDPSocketSource *self;
+
+        self = GSSDP_SOCKET_SOURCE (object);
+
+        /* All properties are construct-only, write-only */
+        switch (property_id) {
+        default:
+                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+                break;
+        }
+}
+
+static void
+gssdp_socket_source_set_property (GObject          *object,
+                                  guint             property_id,
+                                  const GValue     *value,
+                                  GParamSpec       *pspec)
+{
+        GSSDPSocketSource *self;
+
+        self = GSSDP_SOCKET_SOURCE (object);
+
+        switch (property_id) {
+        case PROP_TYPE:
+                self->priv->type = g_value_get_int (value);
+                break;
+        case PROP_HOST_IP:
+                self->priv->host_ip = g_value_dup_string (value);
+                break;
+        default:
+                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+                break;
+        }
+}
+
 /**
  * gssdp_socket_source_new
  *
@@ -42,20 +128,36 @@ gssdp_socket_source_new (GSSDPSocketSourceType type,
                          const char           *host_ip,
                          GError              **error)
 {
-        GSSDPSocketSource *socket_source = NULL;
+        return g_initable_new (GSSDP_TYPE_SOCKET_SOURCE,
+                               NULL,
+                               error,
+                               "type",
+                               type,
+                               "host-ip",
+                               host_ip,
+                               NULL);
+}
+
+static gboolean
+gssdp_socket_source_do_init (GInitable     *initable,
+                             GCancellable  *cancellable,
+                             GError       **error)
+{
+        GSSDPSocketSource *self = NULL;
         GInetAddress *iface_address = NULL;
         GSocketAddress *bind_address = NULL;
         GInetAddress *group = NULL;
         GError *inner_error = NULL;
         GSocketFamily family;
 
-        iface_address = g_inet_address_new_from_string (host_ip);
+        self = GSSDP_SOCKET_SOURCE (initable);
+        iface_address = g_inet_address_new_from_string (self->priv->host_ip);
         if (iface_address == NULL) {
                 if (error != NULL) {
                         *error = g_error_new (GSSDP_ERROR,
                                               GSSDP_ERROR_FAILED,
                                               "Invalid host ip: %s",
-                                              host_ip);
+                                              self->priv->host_ip);
                         inner_error = *error;
                 }
 
@@ -78,16 +180,13 @@ gssdp_socket_source_new (GSSDPSocketSourceType type,
         }
 
 
-        /* Create source */
-        socket_source = g_slice_new0 (GSSDPSocketSource);
-
         /* Create socket */
-        socket_source->socket = g_socket_new (G_SOCKET_FAMILY_IPV4,
-                                              G_SOCKET_TYPE_DATAGRAM,
-                                              G_SOCKET_PROTOCOL_UDP,
-                                              &inner_error);
+        self->priv->socket = g_socket_new (G_SOCKET_FAMILY_IPV4,
+                                           G_SOCKET_TYPE_DATAGRAM,
+                                           G_SOCKET_PROTOCOL_UDP,
+                                           &inner_error);
 
-        if (!socket_source->socket) {
+        if (!self->priv->socket) {
                 g_propagate_prefixed_error (error,
                                             inner_error,
                                             "Could not create socket");
@@ -96,7 +195,7 @@ gssdp_socket_source_new (GSSDPSocketSourceType type,
         }
 
         /* Enable broadcasting */
-        if (!gssdp_socket_enable_broadcast (socket_source->socket,
+        if (!gssdp_socket_enable_broadcast (self->priv->socket,
                                             TRUE,
                                             &inner_error)) {
                 g_propagate_prefixed_error (error,
@@ -106,7 +205,7 @@ gssdp_socket_source_new (GSSDPSocketSourceType type,
         }
 
         /* TTL */
-        if (!gssdp_socket_set_ttl (socket_source->socket,
+        if (!gssdp_socket_set_ttl (self->priv->socket,
                                    4,
                                    &inner_error)) {
                 g_propagate_prefixed_error (error,
@@ -115,9 +214,9 @@ gssdp_socket_source_new (GSSDPSocketSourceType type,
 
         }
         /* Set up additional things according to the type of socket desired */
-        if (type == GSSDP_SOCKET_SOURCE_TYPE_MULTICAST) {
+        if (self->priv->type == GSSDP_SOCKET_SOURCE_TYPE_MULTICAST) {
                 /* Enable multicast loopback */
-                if (!gssdp_socket_enable_loop (socket_source->socket,
+                if (!gssdp_socket_enable_loop (self->priv->socket,
                                                TRUE,
                                                &inner_error)) {
                         g_propagate_prefixed_error (
@@ -128,7 +227,7 @@ gssdp_socket_source_new (GSSDPSocketSourceType type,
                         goto error;
                 }
 
-                if (!gssdp_socket_mcast_interface_set (socket_source->socket,
+                if (!gssdp_socket_mcast_interface_set (self->priv->socket,
                                                        iface_address,
                                                        &inner_error)) {
                         g_propagate_prefixed_error (
@@ -152,7 +251,7 @@ gssdp_socket_source_new (GSSDPSocketSourceType type,
         }
 
         /* Bind to requested port and address */
-        if (!g_socket_bind (socket_source->socket,
+        if (!g_socket_bind (self->priv->socket,
                             bind_address,
                             TRUE,
                             &inner_error)) {
@@ -163,10 +262,10 @@ gssdp_socket_source_new (GSSDPSocketSourceType type,
                 goto error;
         }
 
-        if (type == GSSDP_SOCKET_SOURCE_TYPE_MULTICAST) {
+        if (self->priv->type == GSSDP_SOCKET_SOURCE_TYPE_MULTICAST) {
 
                  /* Subscribe to multicast channel */
-                if (!gssdp_socket_mcast_group_join (socket_source->socket,
+                if (!gssdp_socket_mcast_group_join (self->priv->socket,
                                                     group,
                                                     iface_address,
                                                     &inner_error)) {
@@ -181,9 +280,9 @@ gssdp_socket_source_new (GSSDPSocketSourceType type,
                 }
         }
 
-        socket_source->source = g_socket_create_source (socket_source->socket,
-                                                        G_IO_IN | G_IO_ERR,
-                                                        NULL);
+        self->priv->source = g_socket_create_source (self->priv->socket,
+                                                     G_IO_IN | G_IO_ERR,
+                                                     NULL);
 error:
         if (iface_address != NULL)
                 g_object_unref (iface_address);
@@ -198,10 +297,10 @@ error:
                         g_error_free (inner_error);
                 }
 
-                return NULL;
+                return FALSE;
         }
 
-        return socket_source;
+        return TRUE;
 }
 
 GSocket *
@@ -209,15 +308,104 @@ gssdp_socket_source_get_socket (GSSDPSocketSource *socket_source)
 {
         g_return_val_if_fail (socket_source != NULL, NULL);
 
-        return socket_source->socket;
+        return socket_source->priv->socket;
 }
 
 void
-gssdp_socket_source_destroy (GSSDPSocketSource *socket_source)
+gssdp_socket_source_set_callback (GSSDPSocketSource *self,
+                                  GSourceFunc        callback,
+                                  gpointer           user_data)
 {
-        g_return_if_fail (socket_source != NULL);
-        g_source_destroy (socket_source->source);
-        g_socket_close (socket_source->socket, NULL);
-        g_object_unref (socket_source->socket);
-        g_slice_free (GSSDPSocketSource, socket_source);
+        g_return_if_fail (self != NULL);
+        g_return_if_fail (GSSDP_IS_SOCKET_SOURCE (self));
+
+        g_source_set_callback (self->priv->source, callback, user_data, NULL);
+}
+
+void
+gssdp_socket_source_attach (GSSDPSocketSource *self,
+                            GMainContext      *context)
+{
+        g_return_if_fail (self != NULL);
+        g_return_if_fail (GSSDP_IS_SOCKET_SOURCE (self));
+
+        g_source_attach (self->priv->source, context);
+}
+
+static void
+gssdp_socket_source_dispose (GObject *object)
+{
+        GSSDPSocketSource *self;
+
+        self = GSSDP_SOCKET_SOURCE (object);
+
+        if (self->priv->source != NULL) {
+                g_source_unref (self->priv->source);
+                g_source_destroy (self->priv->source);
+                self->priv->source = NULL;
+        }
+
+        if (self->priv->socket != NULL) {
+                g_socket_close (self->priv->socket, NULL);
+                g_object_unref (self->priv->socket);
+                self->priv->socket = NULL;
+        }
+
+        G_OBJECT_CLASS (gssdp_socket_source_parent_class)->dispose (object);
+}
+
+static void
+gssdp_socket_source_finalize (GObject *object)
+{
+        GSSDPSocketSource *self;
+
+        self = GSSDP_SOCKET_SOURCE (object);
+
+        if (self->priv->host_ip != NULL) {
+                g_free (self->priv->host_ip);
+                self->priv->host_ip = NULL;
+        }
+
+        G_OBJECT_CLASS (gssdp_socket_source_parent_class)->finalize (object);
+}
+
+static void
+gssdp_socket_source_class_init (GSSDPSocketSourceClass *klass)
+{
+        GObjectClass *object_class;
+
+        object_class = G_OBJECT_CLASS (klass);
+
+        object_class->get_property = gssdp_socket_source_get_property;
+        object_class->set_property = gssdp_socket_source_set_property;
+        object_class->dispose = gssdp_socket_source_dispose;
+        object_class->finalize = gssdp_socket_source_finalize;
+
+        g_type_class_add_private (klass, sizeof (GSSDPSocketSourcePrivate));
+
+        g_object_class_install_property
+                (object_class,
+                 PROP_TYPE,
+                 g_param_spec_int
+                        ("type",
+                         "Type",
+                         "Type of socket-source (Multicast/Unicast)",
+                         GSSDP_SOCKET_SOURCE_TYPE_REQUEST,
+                         GSSDP_SOCKET_SOURCE_TYPE_MULTICAST,
+                         GSSDP_SOCKET_SOURCE_TYPE_REQUEST,
+                         G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY |
+                         G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK |
+                         G_PARAM_STATIC_BLURB));
+
+        g_object_class_install_property
+                (object_class,
+                 PROP_HOST_IP,
+                 g_param_spec_string
+                        ("host-ip",
+                         "Host ip",
+                         "IP address of associated network interface",
+                         NULL,
+                         G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY |
+                         G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK |
+                         G_PARAM_STATIC_BLURB));
 }
index c5c7369..93a64a2 100644 (file)
 #ifndef __GSSDP_SOCKET_SOURCE_H__
 #define __GSSDP_SOCKET_SOURCE_H__
 
+#include <glib-object.h>
+
 #include <gio/gio.h>
 
 G_BEGIN_DECLS
 
-struct _GSSDPSocketSource {
-        GSource    *source;
-        GSocket    *socket;
-};
+#define GSSDP_TYPE_SOCKET_SOURCE \
+                (gssdp_socket_source_get_type ())
+#define GSSDP_SOCKET_SOURCE(obj) \
+                (G_TYPE_CHECK_INSTANCE_CAST ((obj), \
+                 GSSDP_TYPE_SOCKET_SOURCE, \
+                 GSSDPSocketSource))
+#define GSSDP_SOCKET_SOURCE_CLASS(klass) \
+                (G_TYPE_CHECK_CLASS_CAST ((klass), \
+                 GSSDP_TYPE_SOCKET_SOURCE, \
+                 GSSDPSocketSourceClass))
+#define GSSDP_IS_SOCKET_SOURCE(obj) \
+                (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
+                 GSSDP_TYPE_SOCKET_SOURCE))
+#define GSSDP_IS_SOCKET_SOURCE_CLASS(klass) \
+                (G_TYPE_CHECK_CLASS_TYPE ((klass), \
+                 GSSDP_TYPE_SOCKET_SOURCE))
+#define GSSDP_SOCKET_SOURCE_GET_CLASS(obj) \
+                (G_TYPE_INSTANCE_GET_CLASS ((obj), \
+                 GSSDP_TYPE_SOCKET_SOURCE, \
+                 GSSDPSocketSourceClass))
 
-typedef struct _GSSDPSocketSource GSSDPSocketSource;
+typedef struct _GSSDPSocketSourcePrivate GSSDPSocketSourcePrivate;
 
 typedef enum {
         GSSDP_SOCKET_SOURCE_TYPE_REQUEST,
         GSSDP_SOCKET_SOURCE_TYPE_MULTICAST
 } GSSDPSocketSourceType;
 
+
+
+typedef struct _GSSDPSocketSource {
+        GObject                   parent;
+
+        GSSDPSocketSourcePrivate *priv;
+} GSSDPSocketSource;
+
+typedef struct _GSSDPSocketSourceClass {
+        GObjectClass parent_class;
+} GSSDPSocketSourceClass;
+
 G_GNUC_INTERNAL GSSDPSocketSource *
 gssdp_socket_source_new        (GSSDPSocketSourceType  type,
                                 const char            *host_ip,
                                 GError               **error);
-G_GNUC_INTERNAL void
-gssdp_socket_source_destroy    (GSSDPSocketSource     *socket_source);
-
 G_GNUC_INTERNAL GSocket*
 gssdp_socket_source_get_socket (GSSDPSocketSource     *socket_source);
 
+G_GNUC_INTERNAL void
+gssdp_socket_source_set_callback (GSSDPSocketSource   *socket_source,
+                                  GSourceFunc          callback,
+                                  gpointer             user_data);
+
+G_GNUC_INTERNAL void
+gssdp_socket_source_attach       (GSSDPSocketSource   *socket_source,
+                                  GMainContext        *context);
+
 G_END_DECLS
 
 #endif /* __GSSDP_SOCKET_SOURCE_H__ */