Separate iochannel implementation from HCConn interface.
[cascardo/rnetproxy.git] / hcconn.c
index 5c6e60e..2f035ea 100644 (file)
--- a/hcconn.c
+++ b/hcconn.c
@@ -20,6 +20,7 @@
 #include "hcconn.h"
 #include <unistd.h>
 #include <fcntl.h>
+#include "hcconn_internal.h"
 
 struct hc_server_cb
 {
@@ -61,37 +62,37 @@ hc_server_add_watch (int fd,
                        hc_server_watch, cb, hc_server_cb_destroy);
 }
 
-struct _hc_conn_t
+struct channel_layer
 {
   GIOChannel *channel;
-  HCClientFunc func;
-  gpointer data;
-  ssize_t (*read) (gpointer, char *, size_t);
-  ssize_t (*write) (gpointer, char *, size_t);
-  void (*close) (gpointer);
-  gpointer layer;
   guint watch;
 };
 
+
 ssize_t
 hc_conn_channel_read (gpointer data, char *buffer, size_t len)
 {
-  int fd = g_io_channel_unix_get_fd ((GIOChannel *) data);
+  struct channel_layer *layer = data;
+  int fd = g_io_channel_unix_get_fd (layer->channel);
   return read (fd, buffer, len);
 }
 
 ssize_t
 hc_conn_channel_write (gpointer data, char *buffer, size_t len)
 {
-  int fd = g_io_channel_unix_get_fd ((GIOChannel *) data);
+  struct channel_layer *layer = data;
+  int fd = g_io_channel_unix_get_fd (layer->channel);
   return write (fd, buffer, len);
 }
 
 void
 hc_conn_channel_close (gpointer data)
 {
-  int fd = g_io_channel_unix_get_fd ((GIOChannel *) data);
+  struct channel_layer *layer = data;
+  int fd = g_io_channel_unix_get_fd (layer->channel);
+  g_source_remove (layer->watch);
   shutdown (fd, SHUT_RDWR);
+  g_io_channel_unref (layer->channel);
 }
 
 gboolean
@@ -104,22 +105,28 @@ hc_conn_watch (GIOChannel *channel, GIOCondition cond, gpointer data)
   return TRUE;
 }
 
-HCConn *
-hc_conn_new (int fd, HCClientFunc func, gpointer data)
+void
+hc_conn_set_driver_channel (HCConn *conn, int fd)
 {
-  HCConn *conn;
-  conn = g_slice_new (HCConn);
-  conn->channel = g_io_channel_unix_new (fd);
-  conn->func = func;
-  conn->data = data;
-  conn->layer = conn->channel;
+  struct channel_layer *layer = g_slice_new (struct channel_layer);
+  layer->channel = g_io_channel_unix_new (fd);
+  conn->layer = layer;
   conn->read = hc_conn_channel_read;
   conn->write = hc_conn_channel_write;
   conn->close = hc_conn_channel_close;
-  conn->watch = g_io_add_watch (conn->channel, G_IO_IN, hc_conn_watch, conn);
+  layer->watch = g_io_add_watch (layer->channel, G_IO_IN, hc_conn_watch, conn);
   if (conn->func)
     conn->func (conn, HC_EVENT_CONNECT, conn->data);
   fcntl (fd, F_SETFL, fcntl (fd, F_GETFL, 0) | O_NONBLOCK);
+}
+
+HCConn *
+hc_conn_new (HCClientFunc func, gpointer data)
+{
+  HCConn *conn;
+  conn = g_slice_new (HCConn);
+  conn->func = func;
+  conn->data = data;
   return conn;
 }
 
@@ -147,7 +154,5 @@ void
 hc_conn_close (HCConn *conn)
 {
   conn->close (conn->layer);
-  g_source_remove (conn->watch);
-  g_io_channel_unref (conn->channel);
   g_slice_free (HCConn, conn);
 }