Made LmSocket into an interface and hooked up implementation of it in LmTcpSocket.
authorMikael Hallendal <micke@imendio.com>
Wed, 09 Jul 2008 15:56:07 +0300
changeset 433 2ed69f025f4a
parent 432 63a049d146c3
child 434 579db9f99cc5
Made LmSocket into an interface and hooked up implementation of it in LmTcpSocket. This design allows for the unit test framework to hook into it's mock socket object in order to short cut the network communication.
loudmouth/Makefile.am
loudmouth/lm-old-socket.h
loudmouth/lm-socket.c
loudmouth/lm-socket.h
loudmouth/lm-tcp-socket.c
loudmouth/lm-tcp-socket.h
--- a/loudmouth/Makefile.am	Tue Jul 08 00:57:01 2008 +0300
+++ b/loudmouth/Makefile.am	Wed Jul 09 15:56:07 2008 +0300
@@ -56,6 +56,8 @@
 	lm-sock.c			\
 	lm-socket.c                     \
 	lm-socket.h                     \
+	lm-tcp-socket.c                 \
+	lm-tcp-socket.h                 \
 	lm-old-socket.c                 \
 	lm-old-socket.h                 \
 	asyncns.c                       \
--- a/loudmouth/lm-old-socket.h	Tue Jul 08 00:57:01 2008 +0300
+++ b/loudmouth/lm-old-socket.h	Wed Jul 09 15:56:07 2008 +0300
@@ -18,8 +18,8 @@
  * Boston, MA 02111-1307, USA.
  */
 
-#ifndef __LM_SOCKET_H__ 
-#define __LM_SOCKET_H__
+#ifndef __LM_OLD_SOCKET_H__ 
+#define __LM_OLD_SOCKET_H__
 
 #include <glib.h>
 
@@ -73,5 +73,5 @@
 gboolean    lm_old_socket_set_keepalive       (LmOldSocket *socket, int delay);
 gchar *     lm_old_socket_get_local_host      (LmOldSocket *socket);
 
-#endif /* __LM_SOCKET_H__ */
+#endif /* __LM_OLD_SOCKET_H__ */
 
--- a/loudmouth/lm-socket.c	Tue Jul 08 00:57:01 2008 +0300
+++ b/loudmouth/lm-socket.c	Wed Jul 09 15:56:07 2008 +0300
@@ -20,155 +20,87 @@
 
 #include <config.h>
 
-#include "lm-marshal.h"
 #include "lm-socket.h"
 
-#define GET_PRIV(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), LM_TYPE_DUMMY, LmSocketPriv))
-
-typedef struct LmSocketPriv LmSocketPriv;
-struct LmSocketPriv {
-	gint my_prop;
-};
+static void    socket_base_init (LmSocketIface *iface);
 
-static void     socket_finalize            (GObject           *object);
-static void     socket_get_property        (GObject           *object,
-					   guint              param_id,
-					   GValue            *value,
-					   GParamSpec        *pspec);
-static void     socket_set_property        (GObject           *object,
-					   guint              param_id,
-					   const GValue      *value,
-					   GParamSpec        *pspec);
-
-G_DEFINE_TYPE (LmSocket, lm_socket, G_TYPE_OBJECT)
-
-enum {
-	PROP_0,
-	PROP_MY_PROP
-};
-
-enum {
-	SIGNAL_NAME,
-	LAST_SIGNAL
-};
+GType
+lm_socket_get_type (void)
+{
+	static GType iface_type = 0;
 
-static guint signals[LAST_SIGNAL] = { 0 };
-
-static void
-lm_socket_class_init (LmSocketClass *class)
-{
-	GObjectClass *object_class = G_OBJECT_CLASS (class);
-
-	object_class->finalize     = socket_finalize;
-	object_class->get_property = socket_get_property;
-	object_class->set_property = socket_set_property;
+	if (!iface_type) {
+		static const GTypeInfo iface_info = {
+			sizeof (LmSocketIface),
+			(GBaseInitFunc)     socket_base_init,
+			(GBaseFinalizeFunc) NULL,
+		};
 
-	g_object_class_install_property (object_class,
-					 PROP_MY_PROP,
-					 g_param_spec_string ("my-prop",
-							      "My Prop",
-							      "My Property",
-							      NULL,
-							      G_PARAM_READWRITE));
-	
-	signals[SIGNAL_NAME] = 
-		g_signal_new ("signal-name",
-			      G_OBJECT_CLASS_TYPE (object_class),
-			      G_SIGNAL_RUN_LAST,
-			      0,
-			      NULL, NULL,
-			      lm_marshal_VOID__INT,
-			      G_TYPE_NONE, 
-			      1, G_TYPE_INT);
-	
-	g_type_class_add_private (object_class, sizeof (LmSocketPriv));
+		iface_type = g_type_register_static (G_TYPE_INTERFACE,
+						     "LmSocketIface",
+						     &iface_info,
+						     0);
+
+		g_type_interface_add_prerequisite (iface_type, G_TYPE_OBJECT);
+	}
+
+	return iface_type;
 }
 
 static void
-lm_socket_init (LmSocket *dummy)
-{
-	LmSocketPriv *priv;
-
-	priv = GET_PRIV (dummy);
-
-}
-
-static void
-socket_finalize (GObject *object)
+socket_base_init (LmSocketIface *iface)
 {
-	LmSocketPriv *priv;
-
-	priv = GET_PRIV (object);
-
-	(G_OBJECT_CLASS (lm_socket_parent_class)->finalize) (object);
-}
-
-static void
-socket_get_property (GObject    *object,
-		   guint       param_id,
-		   GValue     *value,
-		   GParamSpec *pspec)
-{
-	LmSocketPriv *priv;
-
-	priv = GET_PRIV (object);
+	static gboolean initialized = FALSE;
 
-	switch (param_id) {
-	case PROP_MY_PROP:
-		g_value_set_int (value, priv->my_prop);
-		break;
-	default:
-		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
-		break;
-	};
-}
-
-static void
-socket_set_property (GObject      *object,
-                     guint         param_id,
-                     const GValue *value,
-                     GParamSpec   *pspec)
-{
-	LmSocketPriv *priv;
-
-	priv = GET_PRIV (object);
-
-	switch (param_id) {
-	case PROP_MY_PROP:
-		priv->my_prop = g_value_get_int (value);
-		break;
-	default:
-		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
-		break;
-	};
+	if (!initialized) {
+		/* create interface signals here. */
+		initialized = TRUE;
+	}
 }
 
 LmSocket *
 lm_socket_new (const gchar *host, guint port)
 {
+        g_return_val_if_fail (host != NULL, NULL);
+
         return NULL;
 }
 
 /* Use DNS lookup to find the port and the host */
 LmSocket *
-lm_socket_new_srv (const gchar *service)
+lm_socket_new_to_service (const gchar *service)
 {
+        g_return_val_if_fail (service != NULL, NULL);
+
         return NULL;
 }
 
 void 
 lm_socket_connect (LmSocket *socket)
 {
+        g_return_if_fail (LM_IS_SOCKET (socket));
+
+
         /* Initiate the connection process                 */
         /* DNS lookup, connect thing, create IOchannel etc */
+        if (!LM_SOCKET_GET_IFACE(socket)->write) {
+                g_assert_not_reached ();
+        }
+
+        LM_SOCKET_GET_IFACE(socket)->connect (socket);
 }
 
 gboolean
-lm_socket_write (LmSocket *socket,
-                 gchar    *data,
-                 gsize     len)
+lm_socket_write (LmSocket *socket, gchar *buf, gsize len)
 {
-        return FALSE;
+        g_return_val_if_fail (LM_IS_SOCKET (socket), FALSE);
+        g_return_val_if_fail (buf != NULL, FALSE);
+
+        if (!LM_SOCKET_GET_IFACE(socket)->write) {
+                g_assert_not_reached ();
+        }
+
+        return LM_SOCKET_GET_IFACE(socket)->write (socket, buf, len);
 }
 
 gboolean
@@ -177,12 +109,25 @@
                 gsize     buf_len,
                 gsize     read_len)
 {
-        return FALSE;
+        g_return_val_if_fail (LM_IS_SOCKET (socket), FALSE);
+        g_return_val_if_fail (buf != NULL, FALSE);
+
+        if (!LM_SOCKET_GET_IFACE(socket)->read) {
+                g_assert_not_reached ();
+        }
+
+        return LM_SOCKET_GET_IFACE(socket)->read (socket, buf, buf_len, read_len);
 }
 
 void 
 lm_socket_disconnect (LmSocket *socket)
 {
+        g_return_if_fail (LM_IS_SOCKET (socket));
+
+        if (!LM_SOCKET_GET_IFACE(socket)->disconnect) {
+                g_assert_not_reached ();
+        }
+
+        LM_SOCKET_GET_IFACE(socket)->disconnect (socket);
 }
 
-
--- a/loudmouth/lm-socket.h	Tue Jul 08 00:57:01 2008 +0300
+++ b/loudmouth/lm-socket.h	Wed Jul 09 15:56:07 2008 +0300
@@ -23,43 +23,51 @@
 
 #include <glib-object.h>
 
+#include "lm-message.h"
+#include "lm-internals.h"
+
 G_BEGIN_DECLS
 
-#define LM_TYPE_DUMMY            (lm_socket_get_type ())
-#define LM_SOCKET(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), LM_TYPE_DUMMY, LmSocket))
-#define LM_SOCKET_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), LM_TYPE_DUMMY, LmSocketClass))
-#define LM_IS_DUMMY(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), LM_TYPE_DUMMY))
-#define LM_IS_DUMMY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), LM_TYPE_DUMMY))
-#define LM_SOCKET_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), LM_TYPE_DUMMY, LmSocketClass))
+#define LM_TYPE_SOCKET             (lm_socket_get_type())
+#define LM_SOCKET(o)               (G_TYPE_CHECK_INSTANCE_CAST((o), LM_TYPE_SOCKET, LmSocket))
+#define LM_IS_SOCKET(o)            (G_TYPE_CHECK_INSTANCE_TYPE((o), LM_TYPE_SOCKET))
+#define LM_SOCKET_GET_IFACE(o)     (G_TYPE_INSTANCE_GET_INTERFACE((o), LM_TYPE_SOCKET, LmSocketIface))
+
+typedef struct _LmSocket      LmSocket;
+typedef struct _LmSocketIface LmSocketIface;
+
+struct _LmSocketIface {
+	GTypeInterface parent;
 
-typedef struct LmSocket      LmSocket;
-typedef struct LmSocketClass LmSocketClass;
-
-struct LmSocket {
-	GObject parent;
+	/* <vtable> */
+        void     (*connect)      (LmSocket *socket);
+        gboolean (*write)        (LmSocket *socket,
+                                  gchar    *buf,
+                                  gsize     len);
+        gboolean (*read)         (LmSocket *socket,
+                                  gchar    *buf,
+                                  gsize     buf_len,
+                                  gsize     read_len);
+        void     (*disconnect)   (LmSocket *socket);
 };
 
-struct LmSocketClass {
-	GObjectClass parent_class;
-};
+GType          lm_socket_get_type          (void);
 
-GType       lm_socket_get_type      (void);
-
-LmSocket *  lm_socket_new           (const gchar *host,
-                                     guint        port);
+LmSocket *     lm_socket_new               (const gchar *host,
+                                            guint        port);
 /* Use DNS lookup to find the port and the host */
-LmSocket *  lm_socket_new_srv       (const gchar *service);
+LmSocket *     lm_socket_new_to_service    (const gchar *service);
 
 /* All async functions so doesn't make a lot of sense to return anything */
-void        lm_socket_connect       (LmSocket    *socket);
-gboolean    lm_socket_write         (LmSocket    *socket,
-                                     gchar       *data,
-                                     gsize        len);
-gboolean    lm_socket_read          (LmSocket    *socket,
-                                     gchar       *buf,
-                                     gsize        buf_len,
-                                     gsize        read_len);
-void        lm_socket_disconnect    (LmSocket    *socket);
+void           lm_socket_connect           (LmSocket    *socket);
+gboolean       lm_socket_write             (LmSocket    *socket,
+                                            gchar       *buf,
+                                            gsize        len);
+gboolean       lm_socket_read              (LmSocket    *socket,
+                                            gchar       *buf,
+                                            gsize        buf_len,
+                                            gsize        read_len);
+void           lm_socket_disconnect        (LmSocket    *socket);
 
 G_END_DECLS
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/loudmouth/lm-tcp-socket.c	Wed Jul 09 15:56:07 2008 +0300
@@ -0,0 +1,195 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2008 Imendio AB
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+
+#include "lm-marshal.h"
+#include "lm-tcp-socket.h"
+#include "lm-socket.h"
+
+#define GET_PRIV(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), LM_TYPE_TCP_SOCKET, LmTcpSocketPriv))
+
+typedef struct LmTcpSocketPriv LmTcpSocketPriv;
+struct LmTcpSocketPriv {
+	gint my_prop;
+};
+
+static void     tcp_socket_iface_init          (LmSocketIface     *iface);
+static void     tcp_socket_finalize            (GObject           *object);
+static void     tcp_socket_get_property        (GObject           *object,
+                                                guint              param_id,
+                                                GValue            *value,
+                                                GParamSpec        *pspec);
+static void     tcp_socket_set_property        (GObject           *object,
+                                                guint              param_id,
+                                                const GValue      *value,
+                                                GParamSpec        *pspec);
+static void     tcp_socket_connect             (LmSocket          *socket);
+static gboolean tcp_socket_write               (LmSocket          *socket,
+                                                gchar             *data, 
+                                                gsize              len);
+static gboolean tcp_socket_read                (LmSocket          *socket,
+                                                gchar             *buf,
+                                                gsize              buf_len,
+                                                gsize              read_len);
+static void     tcp_socket_disconnect          (LmSocket          *socket);
+
+G_DEFINE_TYPE_WITH_CODE (LmTcpSocket, lm_tcp_socket, G_TYPE_OBJECT,
+                         G_IMPLEMENT_INTERFACE (LM_TYPE_SOCKET,
+                                                tcp_socket_iface_init))
+
+enum {
+	PROP_0,
+	PROP_MY_PROP
+};
+
+enum {
+	SIGNAL_NAME,
+	LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL] = { 0 };
+
+static void
+lm_tcp_socket_class_init (LmTcpSocketClass *class)
+{
+	GObjectClass *object_class = G_OBJECT_CLASS (class);
+
+	object_class->finalize     = tcp_socket_finalize;
+	object_class->get_property = tcp_socket_get_property;
+	object_class->set_property = tcp_socket_set_property;
+
+	g_object_class_install_property (object_class,
+					 PROP_MY_PROP,
+					 g_param_spec_string ("my-prop",
+							      "My Prop",
+							      "My Property",
+							      NULL,
+							      G_PARAM_READWRITE));
+	
+	signals[SIGNAL_NAME] = 
+		g_signal_new ("signal-name",
+			      G_OBJECT_CLASS_TYPE (object_class),
+			      G_SIGNAL_RUN_LAST,
+			      0,
+			      NULL, NULL,
+			      lm_marshal_VOID__INT,
+			      G_TYPE_NONE, 
+			      1, G_TYPE_INT);
+	
+	g_type_class_add_private (object_class, sizeof (LmTcpSocketPriv));
+}
+
+static void
+tcp_socket_iface_init (LmSocketIface *iface)
+{
+        iface->connect    = tcp_socket_connect;
+        iface->write      = tcp_socket_write;
+        iface->read       = tcp_socket_read;
+        iface->disconnect = tcp_socket_disconnect;
+}
+
+static void
+lm_tcp_socket_init (LmTcpSocket *dummy)
+{
+	LmTcpSocketPriv *priv;
+
+	priv = GET_PRIV (dummy);
+
+}
+
+static void
+tcp_socket_finalize (GObject *object)
+{
+	LmTcpSocketPriv *priv;
+
+	priv = GET_PRIV (object);
+
+	(G_OBJECT_CLASS (lm_tcp_socket_parent_class)->finalize) (object);
+}
+
+static void
+tcp_socket_get_property (GObject    *object,
+                         guint       param_id,
+                         GValue     *value,
+                         GParamSpec *pspec)
+{
+	LmTcpSocketPriv *priv;
+
+	priv = GET_PRIV (object);
+
+	switch (param_id) {
+	case PROP_MY_PROP:
+		g_value_set_int (value, priv->my_prop);
+		break;
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+		break;
+	};
+}
+
+static void
+tcp_socket_set_property (GObject      *object,
+                         guint         param_id,
+                         const GValue *value,
+                         GParamSpec   *pspec)
+{
+	LmTcpSocketPriv *priv;
+
+	priv = GET_PRIV (object);
+
+	switch (param_id) {
+	case PROP_MY_PROP:
+		priv->my_prop = g_value_get_int (value);
+		break;
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+		break;
+	};
+}
+
+static void 
+tcp_socket_connect (LmSocket *socket)
+{
+        /* Initiate the connection process                 */
+        /* DNS lookup, connect thing, create IOchannel etc */
+}
+
+static gboolean
+tcp_socket_write (LmSocket *socket, gchar *data, gsize len)
+{
+        return FALSE;
+}
+
+static gboolean
+tcp_socket_read (LmSocket *socket,
+                gchar    *buf,
+                gsize     buf_len,
+                gsize     read_len)
+{
+        return FALSE;
+}
+
+static void 
+tcp_socket_disconnect (LmSocket *socket)
+{
+}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/loudmouth/lm-tcp-socket.h	Wed Jul 09 15:56:07 2008 +0300
@@ -0,0 +1,53 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2008 Imendio AB
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __LM_TCP_SOCKET_H__
+#define __LM_TCP_SOCKET_H__
+
+#include <glib-object.h>
+
+#include "lm-socket.h"
+
+G_BEGIN_DECLS
+
+#define LM_TYPE_TCP_SOCKET            (lm_tcp_socket_get_type ())
+#define LM_TCP_SOCKET(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), LM_TYPE_TCP_SOCKET, LmTcpSocket))
+#define LM_TCP_SOCKET_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), LM_TYPE_TCP_SOCKET, LmTcpSocketClass))
+#define LM_IS_TCP_SOCKET(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), LM_TYPE_TCP_SOCKET))
+#define LM_IS_TCP_SOCKET_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), LM_TYPE_TCP_SOCKET))
+#define LM_TCP_SOCKET_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), LM_TYPE_TCP_SOCKET, LmTcpSocketClass))
+
+typedef struct LmTcpSocket      LmTcpSocket;
+typedef struct LmTcpSocketClass LmTcpSocketClass;
+
+struct LmTcpSocket {
+	GObject parent;
+};
+
+struct LmTcpSocketClass {
+	GObjectClass parent_class;
+};
+
+GType       lm_tcp_socket_get_type      (void);
+
+G_END_DECLS
+
+#endif /* __LM_TCP_SOCKET_H__ */
+