summaryrefslogtreecommitdiff
path: root/src/common.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/common.c')
-rw-r--r--src/common.c103
1 files changed, 103 insertions, 0 deletions
diff --git a/src/common.c b/src/common.c
new file mode 100644
index 0000000..4a8a38e
--- /dev/null
+++ b/src/common.c
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2010 Xavier Claessens <xclaesse@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU 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
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+
+#include "common.h"
+
+typedef struct
+{
+ guint ref_count;
+ GIOStream *stream1;
+ GIOStream *stream2;
+
+ _GIOStreamSpliceCallback callback;
+ gpointer user_data;
+} SpliceContext;
+
+static SpliceContext *
+splice_context_ref (SpliceContext *self)
+{
+ self->ref_count++;
+ return self;
+}
+
+static void
+splice_context_unref (SpliceContext *self)
+{
+ if (--self->ref_count == 0)
+ {
+ if (self->callback != NULL)
+ self->callback (self->user_data);
+
+ g_object_unref (self->stream1);
+ g_object_unref (self->stream2);
+
+ g_slice_free (SpliceContext, self);
+ }
+}
+
+static void
+splice_context_close (SpliceContext *self)
+{
+ g_io_stream_close (self->stream1, NULL, NULL);
+ g_io_stream_close (self->stream2, NULL, NULL);
+}
+
+static void
+splice_cb (GObject *ostream,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ SpliceContext *ctx = user_data;
+
+ splice_context_close (ctx);
+ splice_context_unref (ctx);
+}
+
+void
+_g_io_stream_splice (GIOStream *stream1,
+ GIOStream *stream2,
+ _GIOStreamSpliceCallback callback,
+ gpointer user_data)
+{
+ SpliceContext *ctx;
+ GInputStream *istream;
+ GOutputStream *ostream;
+
+ ctx = g_slice_new0 (SpliceContext);
+ ctx->ref_count = 1;
+ ctx->stream1 = g_object_ref (stream1);
+ ctx->stream2 = g_object_ref (stream2);
+ ctx->callback = callback;
+ ctx->user_data = user_data;
+
+ istream = g_io_stream_get_input_stream (stream1);
+ ostream = g_io_stream_get_output_stream (stream2);
+ g_output_stream_splice_async (ostream, istream, G_OUTPUT_STREAM_SPLICE_NONE,
+ G_PRIORITY_DEFAULT, NULL, splice_cb, splice_context_ref (ctx));
+
+ istream = g_io_stream_get_input_stream (stream2);
+ ostream = g_io_stream_get_output_stream (stream1);
+ g_output_stream_splice_async (ostream, istream, G_OUTPUT_STREAM_SPLICE_NONE,
+ G_PRIORITY_DEFAULT, NULL, splice_cb, splice_context_ref (ctx));
+
+ splice_context_unref (ctx);
+}
+