/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/*
* Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
*
* This library is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation.
*
* This library 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 Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library. If not, see .
*
* Authors: Michael Zucchi
*/
#ifdef HAVE_CONFIG_H
#include
#endif
#include
#include "camel-mime-filter-from.h"
#define CAMEL_MIME_FILTER_FROM_GET_PRIVATE(obj) \
(G_TYPE_INSTANCE_GET_PRIVATE \
((obj), CAMEL_TYPE_MIME_FILTER_FROM, CamelMimeFilterFromPrivate))
#define d(x)
struct _CamelMimeFilterFromPrivate {
gboolean midline; /* are we between lines? */
};
struct fromnode {
struct fromnode *next;
const gchar *pointer;
};
G_DEFINE_TYPE (CamelMimeFilterFrom, camel_mime_filter_from, CAMEL_TYPE_MIME_FILTER)
/* Yes, it is complicated ... */
static void
mime_filter_from_filter (CamelMimeFilter *mime_filter,
const gchar *in,
gsize len,
gsize prespace,
gchar **out,
gsize *outlen,
gsize *outprespace)
{
CamelMimeFilterFromPrivate *priv;
const gchar *inptr, *inend;
gint left;
gint fromcount = 0;
struct fromnode *head = NULL, *tail = (struct fromnode *) &head, *node;
gchar *outptr;
priv = CAMEL_MIME_FILTER_FROM_GET_PRIVATE (mime_filter);
inptr = in;
inend = inptr + len;
d (printf ("Filtering '%.*s'\n", len, in));
/* first, see if we need to escape any from's */
while (inptr < inend) {
register gint c = -1;
if (priv->midline)
while (inptr < inend && (c = *inptr++) != '\n')
;
if (c == '\n' || !priv->midline) {
left = inend - inptr;
if (left > 0) {
priv->midline = TRUE;
if (left < 5) {
if (inptr[0] == 'F') {
camel_mime_filter_backup (mime_filter, inptr, left);
priv->midline = FALSE;
inend = inptr;
break;
}
} else {
if (!strncmp (inptr, "From ", 5)) {
fromcount++;
/* yes, we do alloc them on the stack ... at most we're going to get
* len / 7 of them anyway */
node = alloca (sizeof (*node));
node->pointer = inptr;
node->next = NULL;
tail->next = node;
tail = node;
inptr += 5;
}
}
} else {
/* \n is at end of line, check next buffer */
priv->midline = FALSE;
}
}
}
if (fromcount > 0) {
camel_mime_filter_set_size (mime_filter, len + fromcount, FALSE);
node = head;
inptr = in;
outptr = mime_filter->outbuf;
while (node) {
memcpy (outptr, inptr, node->pointer - inptr);
outptr += node->pointer - inptr;
*outptr++ = '>';
inptr = node->pointer;
node = node->next;
}
memcpy (outptr, inptr, inend - inptr);
outptr += inend - inptr;
*out = mime_filter->outbuf;
*outlen = outptr - mime_filter->outbuf;
*outprespace = mime_filter->outbuf - mime_filter->outreal;
d (printf ("Filtered '%.*s'\n", *outlen, *out));
} else {
*out = (gchar *) in;
*outlen = inend - in;
*outprespace = prespace;
d (printf ("Filtered '%.*s'\n", *outlen, *out));
}
}
static void
mime_filter_from_complete (CamelMimeFilter *mime_filter,
const gchar *in,
gsize len,
gsize prespace,
gchar **out,
gsize *outlen,
gsize *outprespace)
{
*out = (gchar *) in;
*outlen = len;
*outprespace = prespace;
}
static void
camel_mime_filter_from_class_init (CamelMimeFilterFromClass *class)
{
CamelMimeFilterClass *mime_filter_class;
g_type_class_add_private (class, sizeof (CamelMimeFilterFromPrivate));
mime_filter_class = CAMEL_MIME_FILTER_CLASS (class);
mime_filter_class->filter = mime_filter_from_filter;
mime_filter_class->complete = mime_filter_from_complete;
}
static void
camel_mime_filter_from_init (CamelMimeFilterFrom *filter)
{
filter->priv = CAMEL_MIME_FILTER_FROM_GET_PRIVATE (filter);
}
/**
* camel_mime_filter_from_new:
*
* Create a new #CamelMimeFilterFrom object.
*
* Returns: a new #CamelMimeFilterFrom object
**/
CamelMimeFilter *
camel_mime_filter_from_new (void)
{
return g_object_new (CAMEL_TYPE_MIME_FILTER_FROM, NULL);
}
#if 0
#include
gint main (gint argc, gchar **argv)
{
CamelMimeFilterFrom *f;
gchar *buffer;
gint len, prespace;
g_tk_init (&argc, &argv);
f = camel_mime_filter_from_new ();
buffer = "This is a test\nFrom Someone\nTo someone. From Someone else, From\n From blah\nFromblah\nBye! \nFrom ";
len = strlen (buffer);
prespace = 0;
printf ("input = '%.*s'\n", len, buffer);
camel_mime_filter_filter (f, buffer, len, prespace, &buffer, &len, &prespace);
printf ("output = '%.*s'\n", len, buffer);
buffer = "";
len = 0;
prespace = 0;
camel_mime_filter_complete (f, buffer, len, prespace, &buffer, &len, &prespace);
printf ("complete = '%.*s'\n", len, buffer);
return 0;
}
#endif