aboutsummaryrefslogtreecommitdiffstats
path: root/camel/camel-stream-data-wrapper.c
diff options
context:
space:
mode:
authorEttore Perazzoli <ettore@src.gnome.org>1999-11-17 22:39:25 +0800
committerEttore Perazzoli <ettore@src.gnome.org>1999-11-17 22:39:25 +0800
commitca7044930f42a698fd88f914c2512a20e2eeaae9 (patch)
tree522962a77005d741097713e87de1d50353b17768 /camel/camel-stream-data-wrapper.c
parent16de3313b700cb56ab9e829d1e9b7e7d2c81241b (diff)
downloadgsoc2013-evolution-ca7044930f42a698fd88f914c2512a20e2eeaae9.tar.gz
gsoc2013-evolution-ca7044930f42a698fd88f914c2512a20e2eeaae9.tar.zst
gsoc2013-evolution-ca7044930f42a698fd88f914c2512a20e2eeaae9.zip
Added streaming capability to CamelDataWrapper. This makes it possible, for
example, to build multipart messages out of files that are on disk without loading them in memory. svn path=/trunk/; revision=1394
Diffstat (limited to 'camel/camel-stream-data-wrapper.c')
-rw-r--r--camel/camel-stream-data-wrapper.c209
1 files changed, 209 insertions, 0 deletions
diff --git a/camel/camel-stream-data-wrapper.c b/camel/camel-stream-data-wrapper.c
new file mode 100644
index 0000000000..564571cf09
--- /dev/null
+++ b/camel/camel-stream-data-wrapper.c
@@ -0,0 +1,209 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* camel-stream-data-wrapper.c
+ *
+ * Copyright 1999 International GNOME Support (http://www.gnome-support.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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Ettore Perazzoli
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <gtk/gtk.h>
+
+#include "camel-stream-data-wrapper.h"
+
+
+static CamelDataWrapperClass *parent_class = NULL;
+
+
+/* CamelDataWrapper methods. */
+
+static void
+write_to_stream (CamelDataWrapper *data_wrapper,
+ CamelStream *output_stream)
+{
+#define BUFFER_SIZE 4096
+ gchar buffer[BUFFER_SIZE];
+ CamelStreamDataWrapper *stream_data_wrapper;
+ CamelStream *input_stream;
+
+ stream_data_wrapper = CAMEL_STREAM_DATA_WRAPPER (data_wrapper);
+ input_stream = stream_data_wrapper->stream;
+
+ while (TRUE) {
+ gchar *p;
+ gint read, written;
+
+ read = camel_stream_read (input_stream, buffer, BUFFER_SIZE);
+ if (read == 0)
+ break;
+
+ p = buffer;
+ while (read > 0) {
+ written = camel_stream_write (output_stream, p, read);
+
+ /* FIXME no way to report an error?! */
+ if (written == -1)
+ break;
+
+ p += written;
+ read -= written;
+ }
+ }
+#undef BUFFER_SIZE
+}
+
+static CamelStream *
+get_stream (CamelDataWrapper *data_wrapper)
+{
+ CamelStreamDataWrapper *stream_data_wrapper;
+
+ stream_data_wrapper = CAMEL_STREAM_DATA_WRAPPER (data_wrapper);
+ return stream_data_wrapper->stream;
+}
+
+
+/* GtkObject methods. */
+
+static void
+destroy (GtkObject *object)
+{
+ CamelStreamDataWrapper *stream_data_wrapper;
+ GtkObject *stream_object;
+
+ stream_data_wrapper = CAMEL_STREAM_DATA_WRAPPER (object);
+
+ stream_object = GTK_OBJECT (object);
+ stream_data_wrapper->stream = NULL;
+
+ gtk_object_unref (stream_object);
+}
+
+
+/* This handles destruction of the associated CamelDataWrapper outside
+ CamelStreamDataWrapper, for debuggin purposes (this should never happen). */
+static void
+stream_destroy_cb (GtkObject *object,
+ gpointer data)
+{
+ CamelStreamDataWrapper *wrapper;
+
+ wrapper = CAMEL_STREAM_DATA_WRAPPER (data);
+
+ /* Hack: when we destroy the stream ourselves, we set the `stream'
+ member to NULL first, so that we can recognize when this is done out
+ of our control. */
+ if (wrapper->stream != NULL) {
+ g_warning ("CamelSimpleDataWrapperStream: associated CamelSimpleDataWrapper was destroyed.");
+ wrapper->stream = NULL;
+ }
+}
+
+
+static void
+class_init (CamelStreamDataWrapperClass *class)
+{
+ GtkObjectClass *object_class;
+ CamelDataWrapperClass *data_wrapper_class;
+
+ object_class = GTK_OBJECT_CLASS (class);
+ object_class->destroy = destroy;
+
+ data_wrapper_class = CAMEL_DATA_WRAPPER_CLASS (class);
+ data_wrapper_class->write_to_stream = write_to_stream;
+ data_wrapper_class->get_stream = get_stream;
+
+ parent_class = gtk_type_class (camel_data_wrapper_get_type ());
+}
+
+static void
+init (CamelStreamDataWrapper *wrapper)
+{
+ wrapper->stream = NULL;
+}
+
+
+GtkType
+camel_stream_data_wrapper_get_type (void)
+{
+ static GtkType type = 0;
+
+ if (type == 0) {
+ static const GtkTypeInfo info = {
+ "CamelStreamDataWrapper",
+ sizeof (CamelStreamDataWrapper),
+ sizeof (CamelStreamDataWrapperClass),
+ (GtkClassInitFunc) class_init,
+ (GtkObjectInitFunc) init,
+ /* reserved_1 */ NULL,
+ /* reserved_2 */ NULL,
+ (GtkClassInitFunc) NULL,
+ };
+
+ type = gtk_type_unique (camel_data_wrapper_get_type (), &info);
+ }
+
+ return type;
+}
+
+/**
+ * camel_stream_data_wrapper_construct:
+ * @wrapper: A CamelStreamDataWrapper object
+ * @stream: A Camel stream object
+ *
+ * Construct @wrapper associating @stream to it. Notice that, after this call,
+ * @stream is conceptually owned by @wrapper and will be destroyed when
+ * @wrapper is destroyed.
+ **/
+void
+camel_stream_data_wrapper_construct (CamelStreamDataWrapper *wrapper,
+ CamelStream *stream)
+{
+ g_return_if_fail (wrapper != NULL);
+ g_return_if_fail (IS_CAMEL_STREAM_DATA_WRAPPER (wrapper));
+ g_return_if_fail (stream != NULL);
+ g_return_if_fail (IS_CAMEL_STREAM (stream));
+
+ wrapper->stream = stream;
+ gtk_signal_connect (GTK_OBJECT (stream), "destroy",
+ GTK_SIGNAL_FUNC (stream_destroy_cb), wrapper);
+}
+
+/**
+ * camel_stream_data_wrapper_new:
+ * @stream: A Camel stream object
+ *
+ * Create a new stream data wrapper object for @stream. Notice that, after
+ * this call, @stream is conceptually owned by the new wrapper and will be
+ * destroyed when the wrapper is destroyed.
+ *
+ * Return value: A pointer to the new CamelStreamDataWrapper object.
+ **/
+CamelDataWrapper *
+camel_stream_data_wrapper_new (CamelStream *stream)
+{
+ CamelDataWrapper *wrapper;
+
+ wrapper = gtk_type_new (camel_stream_data_wrapper_get_type ());
+ camel_stream_data_wrapper_construct
+ (CAMEL_STREAM_DATA_WRAPPER (wrapper), stream);
+
+ return wrapper;
+}