aboutsummaryrefslogblamecommitdiffstats
path: root/camel/camel-stream-data-wrapper.c
blob: f4dfbb29e9a3cbd3a17289cc15c40334bf748a4a (plain) (tree)
1
2
3
4


                                                                           
                                                            














































































































































































                                                                                                             
                                                                  
                                          
                                                    


























                                                                           
/* -*- 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;
}