210 lines
5.3 KiB
C
210 lines
5.3 KiB
C
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
|
||
/* camel-stream-data-wrapper.c
|
||
*
|
||
* Copyright 1999, 2000 HelixCode (http://www.helixcode.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 (CAMEL_IS_STREAM_DATA_WRAPPER (wrapper));
|
||
g_return_if_fail (stream != NULL);
|
||
g_return_if_fail (CAMEL_IS_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;
|
||
}
|