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
This commit is contained in:
67
ChangeLog
67
ChangeLog
@ -1,3 +1,70 @@
|
||||
1999-11-17 Ettore Perazzoli <ettore@gnu.org>
|
||||
|
||||
* camel/camel-mime-message.c (_write_to_stream): Write
|
||||
"Mime-Version: 1.0" to the stream.
|
||||
|
||||
* tests/test1.c: If executed with a file name parameter, attach a
|
||||
file with with that name to the email without loading it into
|
||||
core, thus demonstrating usage of my latest changes.
|
||||
|
||||
* camel/camel-mime-part.c (_set_encoding): Updated to use
|
||||
`CamelMimePartEncodingType'.
|
||||
(camel_mime_part_set_encoding): Likewise.
|
||||
(_get_encoding): Likewise.
|
||||
(camel_mime_part_get_encoding): Likewise.
|
||||
(_write_content_to_stream): Honour the `encoding' member.
|
||||
(_construct_from_stream): Made static.
|
||||
(camel_mime_part_encoding_to_string): New function.
|
||||
(_write_to_stream): Write the encoding string using it.
|
||||
(camel_mime_part_init): Set encoding to
|
||||
`CAMEL_MIME_PART_ENCODING_DEFAULT'.
|
||||
(_finalize): Don't free `encoding' anymore.
|
||||
(camel_mime_part_encoding_from_string): New function.
|
||||
(_parse_header_pair): Use it.
|
||||
|
||||
* camel/camel-mime-part.h: New enum `CamelMimePartEncodingType'.
|
||||
Member `encoding' of `struct _CamelMimePart' changed from `gchar
|
||||
*' to `CamelMimePartEncodingType'. All the encoding-related
|
||||
methods changed to use this type instead of `gchar *'.
|
||||
|
||||
* camel/gmime-base64.c (gmime_encode_base64): Got it to work.
|
||||
|
||||
* camel/Makefile.am (libcamel_la_SOURCES): Compile
|
||||
`gmime-base64.c'.
|
||||
|
||||
* camel/gmime-base64.h: New, previously missing, header.
|
||||
|
||||
* camel/camel-stream-data-wrapper.c: New file implementing the
|
||||
`CamelStreamDataWrapper' class.
|
||||
* camel/camel-stream-data-wrapper.h: Corresponding header.
|
||||
|
||||
* camel/camel-simple-data-wrapper.c: Implemented the `get_stream'
|
||||
virtual method.
|
||||
(_get_stream): New function implementing the method.
|
||||
(camel_simple_data_wrapper_class_init): Install it in the class
|
||||
struct.
|
||||
(camel_simple_data_wrapper_init): New function initializing the
|
||||
`stream' member to NULL,
|
||||
(camel_simple_data_wrapper_class_init): Set it as the
|
||||
GtkObjectInitFunc.
|
||||
|
||||
* camel/camel-simple-data-wrapper.h: New member `stream' in
|
||||
`struct _CamelSimpleDataWrapper'.
|
||||
|
||||
* camel/camel-simple-data-wrapper-stream.c: New file implementing
|
||||
the `CamelSimpleDataWrapperStream' class.
|
||||
* camel/camel-simple-data-wrapper-stream.h: Corresponding header.
|
||||
|
||||
* camel/camel-data-wrapper.c (camel_data_wrapper_get_stream): New
|
||||
function.
|
||||
(_get_stream): New private function, just returning NULL.
|
||||
(camel_data_wrapper_class_init): Install it as the default
|
||||
`get_stream' virtual method.
|
||||
|
||||
* camel/camel-data-wrapper.h: New virtual method `get_stream' in
|
||||
`CamelDataWrapperClass'.
|
||||
(camel_data_wrapper_get_stream): New function prototype.
|
||||
|
||||
1999-11-05 Ettore Perazzoli <ettore@gnu.org>
|
||||
|
||||
* tests/ui-tests/msg-composer-test.c: New file for testing the
|
||||
|
||||
@ -36,6 +36,8 @@ libcamel_la_SOURCES = \
|
||||
camel-data-wrapper.c \
|
||||
camel-exception.c \
|
||||
camel-simple-data-wrapper.c \
|
||||
camel-simple-data-wrapper-stream.c \
|
||||
camel-stream-data-wrapper.c \
|
||||
camel-folder.c \
|
||||
camel-folder-summary.c \
|
||||
camel-medium.c \
|
||||
@ -56,6 +58,7 @@ libcamel_la_SOURCES = \
|
||||
camel-stream-fs.c \
|
||||
camel-stream-mem.c \
|
||||
data-wrapper-repository.c \
|
||||
gmime-base64.c \
|
||||
gmime-content-field.c \
|
||||
gmime-utils.c \
|
||||
gstring-util.c \
|
||||
@ -71,6 +74,8 @@ libcamelinclude_HEADERS = \
|
||||
camel-data-wrapper.h \
|
||||
camel-exception.h \
|
||||
camel-simple-data-wrapper.h \
|
||||
camel-simple-data-wrapper-stream.h \
|
||||
camel-stream-data-wrapper.h \
|
||||
camel-folder.h \
|
||||
camel-folder-summary.h \
|
||||
camel-mime-body-part.h \
|
||||
|
||||
@ -41,6 +41,7 @@ static void _set_mime_type (CamelDataWrapper *data_wrapper, gchar *mime_type);
|
||||
static gchar *_get_mime_type (CamelDataWrapper *data_wrapper);
|
||||
static GMimeContentField *_get_mime_type_field (CamelDataWrapper *data_wrapper);
|
||||
static void _set_mime_type_field (CamelDataWrapper *data_wrapper, GMimeContentField *mime_type);
|
||||
static CamelStream *_get_stream (CamelDataWrapper *data_wrapper);
|
||||
static void _finalize (GtkObject *object);
|
||||
|
||||
static void
|
||||
@ -57,6 +58,7 @@ camel_data_wrapper_class_init (CamelDataWrapperClass *camel_data_wrapper_class)
|
||||
camel_data_wrapper_class->get_mime_type = _get_mime_type;
|
||||
camel_data_wrapper_class->get_mime_type_field = _get_mime_type_field;
|
||||
camel_data_wrapper_class->set_mime_type_field = _set_mime_type_field;
|
||||
camel_data_wrapper_class->get_stream = _get_stream;
|
||||
|
||||
/* virtual method overload */
|
||||
gtk_object_class->finalize = _finalize;
|
||||
@ -236,4 +238,15 @@ camel_data_wrapper_set_mime_type_field (CamelDataWrapper *data_wrapper, GMimeCon
|
||||
CDW_CLASS(data_wrapper)->set_mime_type_field (data_wrapper, mime_type);
|
||||
}
|
||||
|
||||
static CamelStream *
|
||||
_get_stream (CamelDataWrapper *data_wrapper)
|
||||
{
|
||||
/* This needs to be implemented in subclasses. */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
CamelStream *
|
||||
camel_data_wrapper_get_stream (CamelDataWrapper *data_wrapper)
|
||||
{
|
||||
CDW_CLASS(data_wrapper)->get_stream (data_wrapper);
|
||||
}
|
||||
|
||||
@ -66,6 +66,7 @@ typedef struct {
|
||||
gchar * (*get_mime_type) (CamelDataWrapper *data_wrapper);
|
||||
GMimeContentField * (*get_mime_type_field) (CamelDataWrapper *data_wrapper);
|
||||
void (*set_mime_type_field) (CamelDataWrapper *data_wrapper, GMimeContentField *mime_type_field);
|
||||
CamelStream * (*get_stream) (CamelDataWrapper *data_wrapper);
|
||||
} CamelDataWrapperClass;
|
||||
|
||||
|
||||
@ -82,6 +83,7 @@ void camel_data_wrapper_set_mime_type (CamelDataWrapper *data_wrapper, gchar *mi
|
||||
gchar *camel_data_wrapper_get_mime_type (CamelDataWrapper *data_wrapper);
|
||||
GMimeContentField *camel_data_wrapper_get_mime_type_field (CamelDataWrapper *data_wrapper);
|
||||
void camel_data_wrapper_set_mime_type_field (CamelDataWrapper *data_wrapper, GMimeContentField *mime_type);
|
||||
CamelStream *camel_data_wrapper_get_stream (CamelDataWrapper *data_wrapper);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@ -599,6 +599,11 @@ _write_to_stream (CamelDataWrapper *data_wrapper, CamelStream *stream)
|
||||
WHPT (stream, "Date", mm->received_date);
|
||||
CAMEL_LOG_FULL_DEBUG ( "CamelMimeMessage:: Writing \"Subject\"\n");
|
||||
WHPT (stream, "Subject", mm->subject);
|
||||
|
||||
/* FIXME correct to do it here? */
|
||||
CAMEL_LOG_FULL_DEBUG ( "CamelMimeMessage:: Writing \"Mime-Version\"\n");
|
||||
WHPT (stream, "Mime-Version:", "1.0");
|
||||
|
||||
CAMEL_DATA_WRAPPER_CLASS (parent_class)->write_to_stream (data_wrapper, stream);
|
||||
|
||||
}
|
||||
|
||||
@ -60,7 +60,7 @@ static void _finalize (GtkObject *object);
|
||||
|
||||
/* from CamelDataWrapper */
|
||||
static void _write_to_stream (CamelDataWrapper *data_wrapper, CamelStream *stream);
|
||||
void _construct_from_stream (CamelDataWrapper *data_wrapper, CamelStream *stream);
|
||||
static void _construct_from_stream (CamelDataWrapper *data_wrapper, CamelStream *stream);
|
||||
|
||||
/* from CamelMedia */
|
||||
static void _add_header (CamelMedium *medium, gchar *header_name, gchar *header_value);
|
||||
@ -79,8 +79,8 @@ static void _set_content_id (CamelMimePart *mime_part, gchar *content_id);
|
||||
static const gchar *_get_content_id (CamelMimePart *mime_part);
|
||||
static void _set_content_MD5 (CamelMimePart *mime_part, gchar *content_MD5);
|
||||
static const gchar *_get_content_MD5 (CamelMimePart *mime_part);
|
||||
static void _set_encoding (CamelMimePart *mime_part, gchar *encoding);
|
||||
static const gchar *_get_encoding (CamelMimePart *mime_part);
|
||||
static void _set_encoding (CamelMimePart *mime_part, CamelMimePartEncodingType encoding);
|
||||
static CamelMimePartEncodingType _get_encoding (CamelMimePart *mime_part);
|
||||
static void _set_content_languages (CamelMimePart *mime_part, GList *content_languages);
|
||||
static const GList *_get_content_languages (CamelMimePart *mime_part);
|
||||
static void _set_header_lines (CamelMimePart *mime_part, GList *header_lines);
|
||||
@ -162,7 +162,7 @@ camel_mime_part_init (gpointer object, gpointer klass)
|
||||
camel_mime_part->content_id = NULL;
|
||||
camel_mime_part->content_MD5 = NULL;
|
||||
camel_mime_part->content_languages = NULL;
|
||||
camel_mime_part->encoding = NULL;
|
||||
camel_mime_part->encoding = CAMEL_MIME_PART_ENCODING_DEFAULT;
|
||||
camel_mime_part->filename = NULL;
|
||||
camel_mime_part->header_lines = NULL;
|
||||
|
||||
@ -214,7 +214,6 @@ _finalize (GtkObject *object)
|
||||
g_free (mime_part->content_id);
|
||||
g_free (mime_part->content_MD5);
|
||||
string_list_free (mime_part->content_languages);
|
||||
g_free (mime_part->encoding);
|
||||
g_free (mime_part->filename);
|
||||
if (mime_part->header_lines) string_list_free (mime_part->header_lines);
|
||||
|
||||
@ -416,14 +415,14 @@ camel_mime_part_get_content_MD5 (CamelMimePart *mime_part)
|
||||
|
||||
|
||||
static void
|
||||
_set_encoding (CamelMimePart *mime_part, gchar *encoding)
|
||||
_set_encoding (CamelMimePart *mime_part, CamelMimePartEncodingType encoding)
|
||||
{
|
||||
g_free(mime_part->encoding);
|
||||
mime_part->encoding = encoding;
|
||||
}
|
||||
|
||||
void
|
||||
camel_mime_part_set_encoding (CamelMimePart *mime_part, gchar *encoding)
|
||||
camel_mime_part_set_encoding (CamelMimePart *mime_part,
|
||||
CamelMimePartEncodingType encoding)
|
||||
{
|
||||
CMP_CLASS(mime_part)->set_encoding (mime_part, encoding);
|
||||
}
|
||||
@ -433,13 +432,13 @@ camel_mime_part_set_encoding (CamelMimePart *mime_part, gchar *encoding)
|
||||
|
||||
|
||||
|
||||
static const gchar *
|
||||
static CamelMimePartEncodingType
|
||||
_get_encoding (CamelMimePart *mime_part)
|
||||
{
|
||||
return mime_part->encoding;
|
||||
}
|
||||
|
||||
const gchar *
|
||||
const CamelMimePartEncodingType
|
||||
camel_mime_part_get_encoding (CamelMimePart *mime_part)
|
||||
{
|
||||
return CMP_CLASS(mime_part)->get_encoding (mime_part);
|
||||
@ -620,6 +619,7 @@ static void
|
||||
_write_content_to_stream (CamelMimePart *mime_part, CamelStream *stream)
|
||||
{
|
||||
CamelMedium *medium = CAMEL_MEDIUM (mime_part);
|
||||
CamelStream *wrapper_stream;
|
||||
guint buffer_size;
|
||||
gchar *buffer;
|
||||
gchar *encoded_buffer;
|
||||
@ -629,23 +629,27 @@ _write_content_to_stream (CamelMimePart *mime_part, CamelStream *stream)
|
||||
CAMEL_LOG_FULL_DEBUG ( "CamelMimePart::_write_content_to_stream, content=%p\n", content);
|
||||
if (!content) return;
|
||||
|
||||
/* buffer_size = camel_data_wrapper_size (content); */
|
||||
/* buffer = g_malloc (buffer_size); */
|
||||
|
||||
camel_data_wrapper_write_to_stream (content, stream);
|
||||
|
||||
#if 0
|
||||
//if (mime_part->encoding) {
|
||||
// encoded_buffer_size = gmime_encoded_size(buffer, buffer_size, encoding);
|
||||
// encoded_buffer = g_malloc (encoded_buffer_size);
|
||||
// gmime_encode_buffer (buffer, encoded_buffer, encoding);
|
||||
// camel_stream_write (stream, encoded_buffer, encoded_buffer_size);
|
||||
// g_free (encoded_buffer);
|
||||
//} else
|
||||
//fwrite (buffer, buffer_size, 1, file);
|
||||
//camel_stream_write (stream, buffer, buffer_size);
|
||||
//g_free (buffer);
|
||||
#endif
|
||||
switch (mime_part->encoding) {
|
||||
case CAMEL_MIME_PART_ENCODING_DEFAULT:
|
||||
case CAMEL_MIME_PART_ENCODING_7BIT:
|
||||
case CAMEL_MIME_PART_ENCODING_8BIT:
|
||||
camel_data_wrapper_write_to_stream (content, stream);
|
||||
break;
|
||||
case CAMEL_MIME_PART_ENCODING_BASE64:
|
||||
wrapper_stream = camel_data_wrapper_get_stream (content);
|
||||
if (wrapper_stream == NULL) {
|
||||
/* FIXME in this case, we should probably copy stuff
|
||||
in-memory and make sure things work anyway. */
|
||||
g_warning ("Class `%s' does not implement `get_stream'",
|
||||
gtk_type_name (GTK_OBJECT (content)->klass->type));
|
||||
}
|
||||
gmime_encode_base64 (wrapper_stream, stream);
|
||||
break;
|
||||
default:
|
||||
g_warning ("Encoding type `%s' not supported.",
|
||||
camel_mime_part_encoding_to_string
|
||||
(mime_part->encoding));
|
||||
}
|
||||
|
||||
CAMEL_LOG_FULL_DEBUG ( "Leaving CamelMimePart::_write_content_to_stream\n");
|
||||
}
|
||||
@ -665,7 +669,8 @@ _write_to_stream (CamelDataWrapper *data_wrapper, CamelStream *stream)
|
||||
CAMEL_LOG_FULL_DEBUG ( "CamelMimePart::write_to_stream writing content-disposition\n");
|
||||
gmime_content_field_write_to_stream(mp->disposition, stream);
|
||||
CAMEL_LOG_FULL_DEBUG ( "CamelMimePart::write_to_stream writing content-transfer-encoding\n");
|
||||
WHPT (stream, "Content-Transfer-Encoding", mp->encoding);
|
||||
WHPT (stream, "Content-Transfer-Encoding",
|
||||
camel_mime_part_encoding_to_string (mp->encoding));
|
||||
CAMEL_LOG_FULL_DEBUG ( "CamelMimePart::write_to_stream writing content-description\n");
|
||||
WHPT (stream, "Content-Description", mp->description);
|
||||
CAMEL_LOG_FULL_DEBUG ( "CamelMimePart::write_to_stream writing content-MD5\n");
|
||||
@ -733,7 +738,9 @@ _parse_header_pair (CamelMimePart *mime_part, gchar *header_name, gchar *header_
|
||||
"CamelMimePart::parse_header_pair found HEADER_ENCODING: %s\n",
|
||||
header_value);
|
||||
|
||||
camel_mime_part_set_encoding (mime_part, header_value);
|
||||
camel_mime_part_set_encoding
|
||||
(mime_part,
|
||||
camel_mime_part_encoding_from_string (header_value));
|
||||
header_handled = TRUE;
|
||||
break;
|
||||
|
||||
@ -767,7 +774,7 @@ _parse_header_pair (CamelMimePart *mime_part, gchar *header_name, gchar *header_
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
static void
|
||||
_construct_from_stream (CamelDataWrapper *data_wrapper, CamelStream *stream)
|
||||
{
|
||||
|
||||
@ -782,6 +789,41 @@ _construct_from_stream (CamelDataWrapper *data_wrapper, CamelStream *stream)
|
||||
}
|
||||
|
||||
|
||||
const gchar *
|
||||
camel_mime_part_encoding_to_string (CamelMimePartEncodingType encoding)
|
||||
{
|
||||
switch (encoding) {
|
||||
case CAMEL_MIME_PART_ENCODING_DEFAULT:
|
||||
case CAMEL_MIME_PART_ENCODING_7BIT:
|
||||
return "7bit";
|
||||
case CAMEL_MIME_PART_ENCODING_8BIT:
|
||||
return "8bit";
|
||||
case CAMEL_MIME_PART_ENCODING_BASE64:
|
||||
return "base64";
|
||||
case CAMEL_MIME_PART_ENCODING_QUOTEDPRINTABLE:
|
||||
return "quoted-printable";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* FIXME I am not sure this is the correct way to do this. */
|
||||
CamelMimePartEncodingType
|
||||
camel_mime_part_encoding_from_string (const gchar *string)
|
||||
{
|
||||
if (strncmp (string, "7bit") == 0)
|
||||
return CAMEL_MIME_PART_ENCODING_7BIT;
|
||||
else if (strncmp (string, "8bit") == 0)
|
||||
return CAMEL_MIME_PART_ENCODING_8BIT;
|
||||
else if (strncmp (string, "base64") == 0)
|
||||
return CAMEL_MIME_PART_ENCODING_BASE64;
|
||||
else if (strncmp (string, "quoted-printable") == 0)
|
||||
return CAMEL_MIME_PART_ENCODING_QUOTEDPRINTABLE;
|
||||
else
|
||||
/* FIXME? Spit a warning? */
|
||||
return CAMEL_MIME_PART_ENCODING_DEFAULT;
|
||||
}
|
||||
|
||||
|
||||
/******************************/
|
||||
/** Misc utility functions **/
|
||||
|
||||
|
||||
@ -45,6 +45,17 @@ extern "C" {
|
||||
#define IS_CAMEL_MIME_PART(o) (GTK_CHECK_TYPE((o), CAMEL_MIME_PART_TYPE))
|
||||
|
||||
|
||||
enum _CamelMimePartEncodingType {
|
||||
CAMEL_MIME_PART_ENCODING_DEFAULT,
|
||||
CAMEL_MIME_PART_ENCODING_7BIT,
|
||||
CAMEL_MIME_PART_ENCODING_8BIT,
|
||||
CAMEL_MIME_PART_ENCODING_BASE64,
|
||||
CAMEL_MIME_PART_ENCODING_QUOTEDPRINTABLE,
|
||||
CAMEL_MIME_PART_NUM_ENCODINGS
|
||||
};
|
||||
typedef enum _CamelMimePartEncodingType CamelMimePartEncodingType;
|
||||
|
||||
|
||||
/* Do not change these values directly, you
|
||||
would regret it one day */
|
||||
typedef struct
|
||||
@ -57,7 +68,7 @@ typedef struct
|
||||
gchar *content_id;
|
||||
gchar *content_MD5;
|
||||
GList *content_languages;
|
||||
gchar *encoding;
|
||||
CamelMimePartEncodingType encoding;
|
||||
gchar *filename;
|
||||
GList *header_lines;
|
||||
|
||||
@ -82,8 +93,8 @@ typedef struct {
|
||||
const gchar * (*get_content_id) (CamelMimePart *mime_part);
|
||||
void (*set_content_MD5) (CamelMimePart *mime_part, gchar *content_MD5);
|
||||
const gchar * (*get_content_MD5) (CamelMimePart *mime_part);
|
||||
void (*set_encoding) (CamelMimePart *mime_part, gchar *encoding);
|
||||
const gchar * (*get_encoding) (CamelMimePart *mime_part);
|
||||
void (*set_encoding) (CamelMimePart *mime_part, CamelMimePartEncodingType type);
|
||||
const CamelMimePartEncodingType (*get_encoding) (CamelMimePart *mime_part);
|
||||
void (*set_content_languages) (CamelMimePart *mime_part, GList *content_languages);
|
||||
const GList * (*get_content_languages) (CamelMimePart *mime_part);
|
||||
void (*set_header_lines) (CamelMimePart *mime_part, GList *header_lines);
|
||||
@ -116,8 +127,8 @@ const gchar *camel_mime_part_get_filename (CamelMimePart *mime_part);
|
||||
const gchar *camel_mime_part_get_content_id (CamelMimePart *mime_part);
|
||||
const gchar *camel_mime_part_get_content_MD5 (CamelMimePart *mime_part);
|
||||
void camel_mime_part_set_encoding (CamelMimePart *mime_part,
|
||||
gchar *encoding);
|
||||
const gchar *camel_mime_part_get_encoding (CamelMimePart *mime_part);
|
||||
CamelMimePartEncodingType type);
|
||||
CamelMimePartEncodingType camel_mime_part_get_encoding (CamelMimePart *mime_part);
|
||||
void camel_mime_part_set_content_languages (CamelMimePart *mime_part,
|
||||
GList *content_languages);
|
||||
const GList *camel_mime_part_get_content_languages (CamelMimePart *mime_part);
|
||||
@ -127,12 +138,13 @@ const GList *camel_mime_part_get_header_lines (CamelMimePart *mime_part);
|
||||
|
||||
GMimeContentField *camel_mime_part_get_content_type (CamelMimePart *mime_part);
|
||||
|
||||
const gchar *camel_mime_part_encoding_to_string (CamelMimePartEncodingType encoding);
|
||||
CamelMimePartEncodingType camel_mime_part_encoding_from_string (const gchar *string);
|
||||
|
||||
/* utility functions */
|
||||
void camel_mime_part_set_text (CamelMimePart *camel_mime_part, const gchar *text);
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
276
camel/camel-simple-data-wrapper-stream.c
Normal file
276
camel/camel-simple-data-wrapper-stream.c
Normal file
@ -0,0 +1,276 @@
|
||||
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
|
||||
/* camel-simple-data-wrapper-stream.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 "camel-simple-data-wrapper-stream.h"
|
||||
|
||||
|
||||
static CamelStreamClass *parent_class = NULL;
|
||||
|
||||
|
||||
/* CamelStream methods. */
|
||||
|
||||
static gint
|
||||
read (CamelStream *stream,
|
||||
gchar *buffer,
|
||||
gint n)
|
||||
{
|
||||
CamelSimpleDataWrapperStream *wrapper_stream;
|
||||
CamelSimpleDataWrapper *wrapper;
|
||||
GByteArray *array;
|
||||
gint len;
|
||||
|
||||
wrapper_stream = CAMEL_SIMPLE_DATA_WRAPPER_STREAM (stream);
|
||||
wrapper = wrapper_stream->wrapper;
|
||||
g_return_val_if_fail (wrapper != NULL, -1);
|
||||
array = wrapper->byte_array;
|
||||
|
||||
len = MIN (n, array->len - wrapper_stream->current_position);
|
||||
if (len > 0) {
|
||||
memcpy (buffer, array->data, len);
|
||||
wrapper_stream->current_position += len;
|
||||
return len;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static gint
|
||||
write (CamelStream *stream,
|
||||
const gchar *buffer,
|
||||
gint n)
|
||||
{
|
||||
CamelSimpleDataWrapperStream *wrapper_stream;
|
||||
CamelSimpleDataWrapper *wrapper;
|
||||
GByteArray *array;
|
||||
gint len;
|
||||
const gchar *buffer_next;
|
||||
gint left;
|
||||
|
||||
wrapper_stream = CAMEL_SIMPLE_DATA_WRAPPER_STREAM (stream);
|
||||
wrapper = wrapper_stream->wrapper;
|
||||
g_return_val_if_fail (wrapper != NULL, -1);
|
||||
array = wrapper->byte_array;
|
||||
|
||||
len = MIN (n, array->len - wrapper_stream->current_position);
|
||||
if (len > 0) {
|
||||
memcpy (array->data, buffer, len);
|
||||
buffer_next = buffer + len;
|
||||
left = n - len;
|
||||
} else {
|
||||
/* If we are past the end of the array, fill with zeros. */
|
||||
if (wrapper_stream->current_position > array->len) {
|
||||
gint saved_length;
|
||||
|
||||
saved_length = array->len;
|
||||
g_byte_array_set_size
|
||||
(array, wrapper_stream->current_position);
|
||||
memset (array->data + saved_length,
|
||||
0,
|
||||
(wrapper_stream->current_position
|
||||
- saved_length));
|
||||
}
|
||||
|
||||
buffer_next = buffer;
|
||||
left = n;
|
||||
}
|
||||
|
||||
if (n > 0)
|
||||
g_byte_array_append (array, buffer_next, left);
|
||||
|
||||
wrapper_stream->current_position += n;
|
||||
return n;
|
||||
}
|
||||
|
||||
static void
|
||||
flush (CamelStream *stream)
|
||||
{
|
||||
/* No op, as we don't do any buffering. */
|
||||
}
|
||||
|
||||
static gint
|
||||
available (CamelStream *stream)
|
||||
{
|
||||
CamelSimpleDataWrapperStream *wrapper_stream;
|
||||
CamelSimpleDataWrapper *wrapper;
|
||||
GByteArray *array;
|
||||
gint available;
|
||||
|
||||
wrapper_stream = CAMEL_SIMPLE_DATA_WRAPPER_STREAM (stream);
|
||||
wrapper = wrapper_stream->wrapper;
|
||||
g_return_val_if_fail (wrapper != NULL, -1);
|
||||
array = wrapper->byte_array;
|
||||
|
||||
available = array->len - wrapper_stream->current_position;
|
||||
return MAX (available, 0);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
eos (CamelStream *stream)
|
||||
{
|
||||
if (available (stream) > 0)
|
||||
return TRUE;
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
close (CamelStream *stream)
|
||||
{
|
||||
/* Nothing to do, we have no associated file descriptor. */
|
||||
}
|
||||
|
||||
static gint
|
||||
seek (CamelStream *stream,
|
||||
gint offset,
|
||||
CamelStreamSeekPolicy policy)
|
||||
{
|
||||
CamelSimpleDataWrapperStream *wrapper_stream;
|
||||
gint new_position;
|
||||
|
||||
wrapper_stream = CAMEL_SIMPLE_DATA_WRAPPER_STREAM (stream);
|
||||
|
||||
switch (policy) {
|
||||
case CAMEL_STREAM_SET:
|
||||
new_position = offset;
|
||||
break;
|
||||
case CAMEL_STREAM_CUR:
|
||||
new_position = wrapper_stream->current_position + offset;
|
||||
break;
|
||||
case CAMEL_STREAM_END:
|
||||
new_position = wrapper_stream->wrapper->byte_array->len;
|
||||
break;
|
||||
default:
|
||||
g_warning ("Unknown CamelStreamSeekPolicy %d.", policy);
|
||||
return -1;
|
||||
}
|
||||
|
||||
wrapper_stream->current_position = new_position;
|
||||
return new_position;
|
||||
}
|
||||
|
||||
|
||||
/* This handles destruction of the associated CamelDataWrapper. */
|
||||
/* Hm, this should never happen though, because we gtk_object_ref() the
|
||||
wrapper. */
|
||||
static void
|
||||
wrapper_destroy_cb (GtkObject *object,
|
||||
gpointer data)
|
||||
{
|
||||
CamelSimpleDataWrapperStream *stream;
|
||||
|
||||
g_warning ("CamelSimpleDataWrapperStream: associated CamelSimpleDataWrapper was destroyed.");
|
||||
stream = CAMEL_SIMPLE_DATA_WRAPPER_STREAM (object);
|
||||
stream->wrapper = NULL;
|
||||
}
|
||||
|
||||
|
||||
/* GtkObject methods. */
|
||||
|
||||
static void
|
||||
destroy (GtkObject *object)
|
||||
{
|
||||
CamelSimpleDataWrapperStream *stream;
|
||||
|
||||
stream = CAMEL_SIMPLE_DATA_WRAPPER_STREAM (object);
|
||||
|
||||
gtk_object_unref (GTK_OBJECT (stream->wrapper));
|
||||
|
||||
if (GTK_OBJECT_CLASS (parent_class)->destroy != NULL)
|
||||
(* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
class_init (CamelSimpleDataWrapperStreamClass *klass)
|
||||
{
|
||||
GtkObjectClass *object_class;
|
||||
|
||||
object_class = (GtkObjectClass*) klass;
|
||||
|
||||
parent_class = gtk_type_class (camel_stream_get_type ());
|
||||
}
|
||||
|
||||
static void
|
||||
init (CamelSimpleDataWrapperStream *simple_data_wrapper_stream)
|
||||
{
|
||||
simple_data_wrapper_stream->current_position = 0;
|
||||
}
|
||||
|
||||
|
||||
GtkType
|
||||
camel_simple_data_wrapper_stream_get_type (void)
|
||||
{
|
||||
static GtkType type = 0;
|
||||
|
||||
if (type == 0) {
|
||||
static const GtkTypeInfo info = {
|
||||
"CamelSimpleDataWrapperStream",
|
||||
sizeof (CamelSimpleDataWrapperStream),
|
||||
sizeof (CamelSimpleDataWrapperStreamClass),
|
||||
(GtkClassInitFunc) class_init,
|
||||
(GtkObjectInitFunc) init,
|
||||
/* reserved_1 */ NULL,
|
||||
/* reserved_2 */ NULL,
|
||||
(GtkClassInitFunc) NULL,
|
||||
};
|
||||
|
||||
type = gtk_type_unique (camel_stream_get_type (), &info);
|
||||
}
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
void
|
||||
camel_simple_data_wrapper_stream_construct (CamelSimpleDataWrapperStream *stream,
|
||||
CamelSimpleDataWrapper *wrapper)
|
||||
{
|
||||
g_return_if_fail (stream != NULL);
|
||||
g_return_if_fail (IS_CAMEL_SIMPLE_DATA_WRAPPER_STREAM (stream));
|
||||
g_return_if_fail (wrapper != NULL);
|
||||
g_return_if_fail (IS_CAMEL_SIMPLE_DATA_WRAPPER (wrapper));
|
||||
|
||||
gtk_object_ref (GTK_OBJECT (wrapper));
|
||||
stream->wrapper = wrapper;
|
||||
gtk_signal_connect (GTK_OBJECT (wrapper), "destroy",
|
||||
wrapper_destroy_cb, stream);
|
||||
}
|
||||
|
||||
CamelStream *
|
||||
camel_simple_data_wrapper_stream_new (CamelSimpleDataWrapper *wrapper)
|
||||
{
|
||||
CamelStream *stream;
|
||||
|
||||
g_return_val_if_fail (wrapper != NULL, NULL);
|
||||
g_return_val_if_fail (IS_CAMEL_SIMPLE_DATA_WRAPPER (wrapper), NULL);
|
||||
|
||||
stream = gtk_type_new (camel_simple_data_wrapper_stream_get_type ());
|
||||
|
||||
camel_simple_data_wrapper_stream_construct
|
||||
(CAMEL_SIMPLE_DATA_WRAPPER_STREAM (stream), wrapper);
|
||||
|
||||
return stream;
|
||||
}
|
||||
74
camel/camel-simple-data-wrapper-stream.h
Normal file
74
camel/camel-simple-data-wrapper-stream.h
Normal file
@ -0,0 +1,74 @@
|
||||
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
|
||||
/* camel-simple-data-wrapper-stream.h
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#ifndef __CAMEL_SIMPLE_DATA_WRAPPER_STREAM_H__
|
||||
#define __CAMEL_SIMPLE_DATA_WRAPPER_STREAM_H__
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include "camel-simple-data-wrapper.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#pragma }
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#define CAMEL_TYPE_SIMPLE_DATA_WRAPPER_STREAM \
|
||||
(camel_simple_data_wrapper_stream_get_type ())
|
||||
#define CAMEL_SIMPLE_DATA_WRAPPER_STREAM(obj) \
|
||||
(GTK_CHECK_CAST ((obj), CAMEL_TYPE_SIMPLE_DATA_WRAPPER_STREAM, CamelSimpleDataWrapperStream))
|
||||
#define CAMEL_SIMPLE_DATA_WRAPPER_STREAM_CLASS(klass) \
|
||||
(GTK_CHECK_CLASS_CAST ((klass), CAMEL_TYPE_SIMPLE_DATA_WRAPPER_STREAM, CamelSimpleDataWrapperStreamClass))
|
||||
#define IS_CAMEL_SIMPLE_DATA_WRAPPER_STREAM(obj) \
|
||||
(GTK_CHECK_TYPE ((obj), CAMEL_TYPE_SIMPLE_DATA_WRAPPER_STREAM))
|
||||
#define IS_CAMEL_SIMPLE_DATA_WRAPPER_STREAM_CLASS(klass) \
|
||||
(GTK_CHECK_CLASS_TYPE ((obj), CAMEL_TYPE_SIMPLE_DATA_WRAPPER_STREAM))
|
||||
|
||||
|
||||
typedef struct _CamelSimpleDataWrapperStream CamelSimpleDataWrapperStream;
|
||||
typedef struct _CamelSimpleDataWrapperStreamClass CamelSimpleDataWrapperStreamClass;
|
||||
|
||||
struct _CamelSimpleDataWrapperStream {
|
||||
CamelStream parent;
|
||||
|
||||
CamelSimpleDataWrapper *wrapper;
|
||||
gint current_position;
|
||||
};
|
||||
|
||||
struct _CamelSimpleDataWrapperStreamClass {
|
||||
CamelStreamClass parent_class;
|
||||
};
|
||||
|
||||
|
||||
GtkType camel_simple_data_wrapper_stream_get_type (void);
|
||||
CamelStream *camel_simple_data_wrapper_stream_new (CamelSimpleDataWrapper *wrapper);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* __CAMEL_SIMPLE_DATA_WRAPPER_STREAM_H__ */
|
||||
@ -25,7 +25,9 @@
|
||||
* USA
|
||||
*/
|
||||
#include <config.h>
|
||||
|
||||
#include "camel-simple-data-wrapper.h"
|
||||
#include "camel-simple-data-wrapper-stream.h"
|
||||
#include "camel-log.h"
|
||||
|
||||
static CamelDataWrapperClass *parent_class=NULL;
|
||||
@ -36,6 +38,7 @@ static CamelDataWrapperClass *parent_class=NULL;
|
||||
static void _construct_from_stream (CamelDataWrapper *data_wrapper, CamelStream *stream);
|
||||
static void _write_to_stream (CamelDataWrapper *data_wrapper, CamelStream *stream);
|
||||
static void _finalize (GtkObject *object);
|
||||
static CamelStream *_get_stream (CamelDataWrapper *data_wrapper);
|
||||
|
||||
static void
|
||||
camel_simple_data_wrapper_class_init (CamelSimpleDataWrapperClass *camel_simple_data_wrapper_class)
|
||||
@ -50,13 +53,17 @@ camel_simple_data_wrapper_class_init (CamelSimpleDataWrapperClass *camel_simple_
|
||||
camel_data_wrapper_class->write_to_stream = _write_to_stream;
|
||||
camel_data_wrapper_class->construct_from_stream = _construct_from_stream;
|
||||
|
||||
camel_data_wrapper_class->get_stream = _get_stream;
|
||||
|
||||
gtk_object_class->finalize = _finalize;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static void
|
||||
camel_simple_data_wrapper_init (CamelSimpleDataWrapper *wrapper)
|
||||
{
|
||||
wrapper->stream = NULL;
|
||||
}
|
||||
|
||||
GtkType
|
||||
camel_simple_data_wrapper_get_type (void)
|
||||
@ -70,7 +77,7 @@ camel_simple_data_wrapper_get_type (void)
|
||||
sizeof (CamelSimpleDataWrapper),
|
||||
sizeof (CamelSimpleDataWrapperClass),
|
||||
(GtkClassInitFunc) camel_simple_data_wrapper_class_init,
|
||||
(GtkObjectInitFunc) NULL,
|
||||
(GtkObjectInitFunc) camel_simple_data_wrapper_init,
|
||||
/* reserved_1 */ NULL,
|
||||
/* reserved_2 */ NULL,
|
||||
(GtkClassInitFunc) NULL,
|
||||
@ -134,8 +141,6 @@ _write_to_stream (CamelDataWrapper *data_wrapper, CamelStream *stream)
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#define _CMSDW_TMP_BUF_SIZE 100
|
||||
static void
|
||||
_construct_from_stream (CamelDataWrapper *data_wrapper, CamelStream *stream)
|
||||
@ -206,3 +211,20 @@ camel_simple_data_wrapper_set_text (CamelSimpleDataWrapper *simple_data_wrapper,
|
||||
CAMEL_LOG_FULL_DEBUG ("CamelSimpleDataWrapper:: Entering set_text\n");
|
||||
}
|
||||
|
||||
|
||||
|
||||
static CamelStream *
|
||||
_get_stream (CamelDataWrapper *data_wrapper)
|
||||
{
|
||||
CamelSimpleDataWrapper *simple_data_wrapper;
|
||||
|
||||
simple_data_wrapper = CAMEL_SIMPLE_DATA_WRAPPER (data_wrapper);
|
||||
if (simple_data_wrapper->stream == NULL) {
|
||||
CamelStream *s;
|
||||
|
||||
s = camel_simple_data_wrapper_stream_new (simple_data_wrapper);
|
||||
simple_data_wrapper->stream = s;
|
||||
}
|
||||
|
||||
return simple_data_wrapper->stream;
|
||||
}
|
||||
|
||||
@ -53,7 +53,7 @@ typedef struct
|
||||
CamelDataWrapper parent_object;
|
||||
|
||||
GByteArray *byte_array;
|
||||
|
||||
CamelStream *stream;
|
||||
} CamelSimpleDataWrapper;
|
||||
|
||||
|
||||
|
||||
209
camel/camel-stream-data-wrapper.c
Normal file
209
camel/camel-stream-data-wrapper.c
Normal file
@ -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;
|
||||
}
|
||||
75
camel/camel-stream-data-wrapper.h
Normal file
75
camel/camel-stream-data-wrapper.h
Normal file
@ -0,0 +1,75 @@
|
||||
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
|
||||
/* camel-stream-data-wrapper.h
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#ifndef __CAMEL_STREAM_DATA_WRAPPER_H__
|
||||
#define __CAMEL_STREAM_DATA_WRAPPER_H__
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include "camel-data-wrapper.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#pragma }
|
||||
#endif /* __cplusplus */
|
||||
|
||||
|
||||
#define CAMEL_TYPE_STREAM_DATA_WRAPPER \
|
||||
(camel_stream_data_wrapper_get_type ())
|
||||
#define CAMEL_STREAM_DATA_WRAPPER(obj) \
|
||||
(GTK_CHECK_CAST ((obj), CAMEL_TYPE_STREAM_DATA_WRAPPER, CamelStreamDataWrapper))
|
||||
#define CAMEL_STREAM_DATA_WRAPPER_CLASS(klass) \
|
||||
(GTK_CHECK_CLASS_CAST ((klass), CAMEL_TYPE_STREAM_DATA_WRAPPER, CamelStreamDataWrapperClass))
|
||||
#define IS_CAMEL_STREAM_DATA_WRAPPER(obj) \
|
||||
(GTK_CHECK_TYPE ((obj), CAMEL_TYPE_STREAM_DATA_WRAPPER))
|
||||
#define IS_CAMEL_STREAM_DATA_WRAPPER_CLASS(klass) \
|
||||
(GTK_CHECK_CLASS_TYPE ((obj), CAMEL_TYPE_STREAM_DATA_WRAPPER))
|
||||
|
||||
|
||||
typedef struct _CamelStreamDataWrapper CamelStreamDataWrapper;
|
||||
typedef struct _CamelStreamDataWrapperClass CamelStreamDataWrapperClass;
|
||||
|
||||
struct _CamelStreamDataWrapper {
|
||||
CamelDataWrapper parent;
|
||||
|
||||
CamelStream *stream;
|
||||
};
|
||||
|
||||
struct _CamelStreamDataWrapperClass {
|
||||
CamelDataWrapperClass parent_class;
|
||||
};
|
||||
|
||||
|
||||
GtkType camel_stream_data_wrapper_get_type (void);
|
||||
CamelDataWrapper *camel_stream_data_wrapper_new (CamelStream *stream);
|
||||
void camel_stream_data_wrapper_construct (CamelStreamDataWrapper *wrapper,
|
||||
CamelStream *stream);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* __CAMEL_STREAM_DATA_WRAPPER_H__ */
|
||||
@ -30,15 +30,12 @@ gmime_encode_base64 (CamelStream *input, CamelStream *output)
|
||||
char buffer [BSIZE];
|
||||
char obuf [80]; /* Output is limited to 76 characters, rfc2045 */
|
||||
int n, i, j, state;
|
||||
long bytes;
|
||||
|
||||
j = 0;
|
||||
int keep = 0;
|
||||
|
||||
state = 0;
|
||||
bytes = 0;
|
||||
while ((n = camel_stream_read (input, &buffer, sizeof (buffer))) > 0){
|
||||
int keep = 0;
|
||||
|
||||
for (i = 0; i < n; i++, state++, bytes++){
|
||||
j = 0;
|
||||
while ((n = camel_stream_read (input, buffer, sizeof (buffer))) > 0){
|
||||
for (i = 0; i < n; i++, state++){
|
||||
char c = buffer [i];
|
||||
|
||||
switch (state % 3){
|
||||
@ -48,21 +45,23 @@ gmime_encode_base64 (CamelStream *input, CamelStream *output)
|
||||
break;
|
||||
case 1:
|
||||
obuf [j++] = base64_alphabet [keep | (c >> 4)];
|
||||
keep = (c & 0xf) << 4;
|
||||
keep = (c & 0xf) << 2;
|
||||
break;
|
||||
case 2:
|
||||
obuf [j++] = base64_alphabet [keep | (c >> 6)];
|
||||
obuf [j++] = base64_alphabet [c & 0x3f];
|
||||
break;
|
||||
}
|
||||
|
||||
if ((bytes % 72) == 0){
|
||||
|
||||
if (j == 72){
|
||||
obuf [j++] = '\r';
|
||||
obuf [j++] = '\n';
|
||||
camel_stream_write (output, obuf, j);
|
||||
j = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
switch (state % 3){
|
||||
case 0:
|
||||
/* full ouput, nothing left to do */
|
||||
|
||||
16
camel/gmime-base64.h
Normal file
16
camel/gmime-base64.h
Normal file
@ -0,0 +1,16 @@
|
||||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
|
||||
/*
|
||||
* Base64 handlers
|
||||
*
|
||||
* Author:
|
||||
* Miguel de Icaza (miguel@kernel.org)
|
||||
*/
|
||||
|
||||
#ifndef _GMIME_BASE64_H
|
||||
#define _GMIME_BASE64_H
|
||||
|
||||
#include "camel-stream.h"
|
||||
|
||||
void gmime_encode_base64 (CamelStream *input, CamelStream *output);
|
||||
|
||||
#endif
|
||||
@ -3,6 +3,7 @@ CamelProvider
|
||||
CamelThreadProxy
|
||||
GtkObject
|
||||
+ CamelDataWrapper
|
||||
| + CameStreamDataWrapper
|
||||
| + CamelMedium
|
||||
| | + CamelMimePart
|
||||
| | + CamelMimeBodyPart
|
||||
@ -16,6 +17,7 @@ GtkObject
|
||||
| + CamelStore
|
||||
+ CamelSession
|
||||
+ CamelStream
|
||||
| + CameDataWrapperStream
|
||||
| + CamelStreamFs
|
||||
| + CamelStreamBufferedFs
|
||||
| + CamelStreamMem
|
||||
|
||||
@ -3,6 +3,7 @@ CamelProvider
|
||||
CamelThreadProxy
|
||||
GtkObject
|
||||
+ CamelDataWrapper
|
||||
| + CameStreamDataWrapper
|
||||
| + CamelMedium
|
||||
| | + CamelMimePart
|
||||
| | + CamelMimeBodyPart
|
||||
@ -16,6 +17,7 @@ GtkObject
|
||||
| + CamelStore
|
||||
+ CamelSession
|
||||
+ CamelStream
|
||||
| + CameDataWrapperStream
|
||||
| + CamelStreamFs
|
||||
| + CamelStreamBufferedFs
|
||||
| + CamelStreamMem
|
||||
|
||||
@ -1,10 +1,13 @@
|
||||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "camel-mime-message.h"
|
||||
#include "camel-mime-body-part.h"
|
||||
#include "camel-multipart.h"
|
||||
#include "stdio.h"
|
||||
#include "camel-stream.h"
|
||||
#include "camel-stream-fs.h"
|
||||
#include "camel-stream-data-wrapper.h"
|
||||
#include "camel-log.h"
|
||||
#include "camel.h"
|
||||
|
||||
@ -14,12 +17,33 @@ main (int argc, char**argv)
|
||||
CamelMimeMessage *message;
|
||||
CamelMultipart *multipart;
|
||||
CamelMimeBodyPart *body_part;
|
||||
CamelMimeBodyPart *attachment_part;
|
||||
CamelStream *attachment_stream;
|
||||
|
||||
/* FILE *output_file; */
|
||||
CamelStream *stream;
|
||||
|
||||
gtk_init (&argc, &argv);
|
||||
camel_init ();
|
||||
|
||||
if (argc < 2) {
|
||||
attachment_stream = NULL;
|
||||
} else {
|
||||
if (argc == 2) {
|
||||
attachment_stream = camel_stream_fs_new_with_name
|
||||
(argv[1], CAMEL_STREAM_FS_READ);
|
||||
if (attachment_stream == NULL) {
|
||||
fprintf (stderr, "Cannot open `%s'\n",
|
||||
argv[1]);
|
||||
return 1;
|
||||
}
|
||||
} else {
|
||||
fprintf (stderr, "Usage: %s [<attachment>]\n",
|
||||
argv[0]);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
message = camel_mime_message_new_with_session ((CamelSession *)NULL);
|
||||
|
||||
camel_mime_part_set_description (CAMEL_MIME_PART (message), "a test");
|
||||
@ -40,11 +64,29 @@ main (int argc, char**argv)
|
||||
camel_mime_message_add_recipient (message, RECIPIENT_TYPE_CC, g_strdup ("maury@justmagic.com"));
|
||||
camel_mime_message_add_recipient (message, RECIPIENT_TYPE_BCC, g_strdup ("Bertrand.Guiheneuf@aful.org"));
|
||||
|
||||
|
||||
multipart = camel_multipart_new ();
|
||||
body_part = camel_mime_body_part_new ();
|
||||
camel_mime_part_set_text (CAMEL_MIME_PART (body_part), "This is a test.\nThis is only a test.\n");
|
||||
camel_multipart_add_part (multipart, body_part);
|
||||
|
||||
if (attachment_stream == NULL) {
|
||||
attachment_part = NULL;
|
||||
} else {
|
||||
CamelDataWrapper *stream_wrapper;
|
||||
|
||||
stream_wrapper = camel_stream_data_wrapper_new
|
||||
(attachment_stream);
|
||||
|
||||
attachment_part = camel_mime_body_part_new ();
|
||||
camel_mime_part_set_encoding (CAMEL_MIME_PART (attachment_part),
|
||||
CAMEL_MIME_PART_ENCODING_BASE64);
|
||||
camel_medium_set_content_object (CAMEL_MEDIUM (attachment_part),
|
||||
stream_wrapper);
|
||||
camel_multipart_add_part (multipart, attachment_part);
|
||||
|
||||
gtk_object_unref (GTK_OBJECT (stream_wrapper));
|
||||
}
|
||||
|
||||
camel_medium_set_content_object (CAMEL_MEDIUM (message), CAMEL_DATA_WRAPPER (multipart));
|
||||
|
||||
stream = camel_stream_fs_new_with_name ("mail1.test", CAMEL_STREAM_FS_WRITE );
|
||||
@ -53,13 +95,17 @@ main (int argc, char**argv)
|
||||
exit(2);
|
||||
}
|
||||
|
||||
camel_data_wrapper_write_to_stream (CAMEL_DATA_WRAPPER (message), stream);
|
||||
camel_data_wrapper_write_to_stream (CAMEL_DATA_WRAPPER (message),
|
||||
stream);
|
||||
camel_stream_close (stream);
|
||||
gtk_object_unref (GTK_OBJECT (stream));
|
||||
|
||||
gtk_object_unref (GTK_OBJECT (message));
|
||||
gtk_object_unref (GTK_OBJECT (multipart));
|
||||
gtk_object_unref (GTK_OBJECT (body_part));
|
||||
|
||||
if (attachment_part != NULL)
|
||||
gtk_object_unref (GTK_OBJECT (attachment_part));
|
||||
|
||||
printf ("Test1 finished\n");
|
||||
return 1;
|
||||
|
||||
Reference in New Issue
Block a user