[evolution-data-server] Add CamelFilterOutputStream.



commit 8d7fc09b69ab64287f6700a8b02fb272530c873d
Author: Matthew Barnes <mbarnes redhat com>
Date:   Tue Oct 1 10:33:09 2013 -0400

    Add CamelFilterOutputStream.
    
    CamelFilterOutputStream is similar to GConverterOutputStream, except it
    operates on a CamelMimeFilter instead of a GConverter.
    
    This class is meant to be a temporary solution until all of Camel's MIME
    filters are ported to the GConverter interface.

 camel/Makefile.am                       |    2 +
 camel/camel-filter-output-stream.c      |  282 +++++++++++++++++++++++++++++++
 camel/camel-filter-output-stream.h      |   75 ++++++++
 camel/camel.h                           |    1 +
 docs/reference/camel/camel-docs.sgml    |    1 +
 docs/reference/camel/camel-sections.txt |   19 ++
 docs/reference/camel/camel.types        |    1 +
 7 files changed, 381 insertions(+), 0 deletions(-)
---
diff --git a/camel/Makefile.am b/camel/Makefile.am
index e6027a9..cf13f0c 100644
--- a/camel/Makefile.am
+++ b/camel/Makefile.am
@@ -76,6 +76,7 @@ libcamel_1_2_la_SOURCES =                     \
        camel-file-utils.c                      \
        camel-filter-driver.c                   \
        camel-filter-input-stream.c             \
+       camel-filter-output-stream.c            \
        camel-filter-search.c                   \
        camel-folder-search.c                   \
        camel-folder-summary.c                  \
@@ -205,6 +206,7 @@ libcamelinclude_HEADERS =                   \
        camel-file-utils.h                      \
        camel-filter-driver.h                   \
        camel-filter-input-stream.h             \
+       camel-filter-output-stream.h            \
        camel-filter-search.h                   \
        camel-folder-search.h                   \
        camel-folder-summary.h                  \
diff --git a/camel/camel-filter-output-stream.c b/camel/camel-filter-output-stream.c
new file mode 100644
index 0000000..9887c6b
--- /dev/null
+++ b/camel/camel-filter-output-stream.c
@@ -0,0 +1,282 @@
+/*
+ * camel-filter-output-stream.c
+ *
+ * This program 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; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+/**
+ * SECTION: camel-filter-output-stream
+ * @short_description: Filtered output stream
+ * @include: camel/camel.h
+ * @see_also: #GOutputStream, #CamelMimeFilter
+ *
+ * #CamelFilterOutputStream is similar to #GConverterOutputStream, except it
+ * operates on a #CamelMimeFilter instead of a #GConverter.
+ *
+ * This class is meant to be a temporary solution until all of Camel's MIME
+ * filters are ported to the #GConverter interface.
+ **/
+
+#include "camel-filter-output-stream.h"
+
+#include <string.h>
+
+#define CAMEL_FILTER_OUTPUT_STREAM_GET_PRIVATE(obj) \
+       (G_TYPE_INSTANCE_GET_PRIVATE \
+       ((obj), CAMEL_TYPE_FILTER_OUTPUT_STREAM, CamelFilterOutputStreamPrivate))
+
+#define READ_PAD (128)         /* bytes padded before buffer */
+#define READ_SIZE (4096)
+
+struct _CamelFilterOutputStreamPrivate {
+       CamelMimeFilter *filter;
+};
+
+enum {
+       PROP_0,
+       PROP_FILTER
+};
+
+G_DEFINE_TYPE (
+       CamelFilterOutputStream,
+       camel_filter_output_stream,
+       G_TYPE_FILTER_OUTPUT_STREAM)
+
+static void
+filter_output_stream_set_filter (CamelFilterOutputStream *filter_stream,
+                                 CamelMimeFilter *filter)
+{
+       g_return_if_fail (CAMEL_IS_MIME_FILTER (filter));
+       g_return_if_fail (filter_stream->priv->filter == NULL);
+
+       filter_stream->priv->filter = g_object_ref (filter);
+}
+
+static void
+filter_output_stream_set_property (GObject *object,
+                                   guint property_id,
+                                   const GValue *value,
+                                   GParamSpec *pspec)
+{
+       switch (property_id) {
+               case PROP_FILTER:
+                       filter_output_stream_set_filter (
+                               CAMEL_FILTER_OUTPUT_STREAM (object),
+                               g_value_get_object (value));
+                       return;
+       }
+
+       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+filter_output_stream_get_property (GObject *object,
+                                   guint property_id,
+                                   GValue *value,
+                                   GParamSpec *pspec)
+{
+       switch (property_id) {
+               case PROP_FILTER:
+                       g_value_set_object (
+                               value,
+                               camel_filter_output_stream_get_filter (
+                               CAMEL_FILTER_OUTPUT_STREAM (object)));
+                       return;
+       }
+
+       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+filter_output_stream_dispose (GObject *object)
+{
+       CamelFilterOutputStreamPrivate *priv;
+
+       priv = CAMEL_FILTER_OUTPUT_STREAM_GET_PRIVATE (object);
+
+       /* XXX GOutputStream calls flush() one last time during
+        *     dispose(), so chain up before clearing our filter. */
+       G_OBJECT_CLASS (camel_filter_output_stream_parent_class)->
+               dispose (object);
+
+       g_clear_object (&priv->filter);
+}
+
+static gssize
+filter_output_stream_write (GOutputStream *stream,
+                            gconstpointer buffer,
+                            gsize count,
+                            GCancellable *cancellable,
+                            GError **error)
+{
+       CamelMimeFilter *filter;
+       GOutputStream *base_stream;
+       gchar real_buffer[READ_SIZE + READ_PAD];
+       const gchar *input_buffer = buffer;
+       gsize bytes_left = count;
+
+       filter = camel_filter_output_stream_get_filter (
+               CAMEL_FILTER_OUTPUT_STREAM (stream));
+       base_stream = g_filter_output_stream_get_base_stream (
+               G_FILTER_OUTPUT_STREAM (stream));
+
+       while (bytes_left > 0) {
+               gsize length;
+               gsize presize;
+               gchar *bufptr;
+               gboolean success;
+
+               bufptr = real_buffer + READ_PAD;
+               length = MIN (READ_SIZE, bytes_left);
+               memcpy (bufptr, input_buffer, length);
+               input_buffer += length;
+               bytes_left -= length;
+
+               presize = READ_PAD;
+
+               camel_mime_filter_filter (
+                       filter, bufptr, length, presize,
+                       &bufptr, &length, &presize);
+
+               /* XXX The bytes_written argument can be NULL,
+                *     even though the API docs don't say so. */
+               success = g_output_stream_write_all (
+                       base_stream, bufptr, length,
+                       NULL, cancellable, error);
+               if (!success)
+                       return -1;
+       }
+
+       return count;
+}
+
+static gboolean
+filter_output_stream_flush (GOutputStream *stream,
+                            GCancellable *cancellable,
+                            GError **error)
+{
+       CamelMimeFilter *filter;
+       GOutputStream *base_stream;
+       gchar *bufptr = (gchar *) "";
+       gsize length = 0;
+       gsize presize = 0;
+       gboolean success = TRUE;
+
+       filter = camel_filter_output_stream_get_filter (
+               CAMEL_FILTER_OUTPUT_STREAM (stream));
+       base_stream = g_filter_output_stream_get_base_stream (
+               G_FILTER_OUTPUT_STREAM (stream));
+
+       camel_mime_filter_complete (
+               filter, bufptr, length, presize,
+               &bufptr, &length, &presize);
+
+       if (length > 0) {
+               /* XXX The bytes_written argument can be NULL,
+                *     even though the API docs don't say so. */
+               success = g_output_stream_write_all (
+                       base_stream, bufptr, length,
+                       NULL, cancellable, error);
+       }
+
+       if (success) {
+               success = g_output_stream_flush (
+                       base_stream, cancellable, error);
+       }
+
+       return success;
+}
+
+static void
+camel_filter_output_stream_class_init (CamelFilterOutputStreamClass *class)
+{
+       GObjectClass *object_class;
+       GOutputStreamClass *stream_class;
+
+       g_type_class_add_private (
+               class, sizeof (CamelFilterOutputStreamPrivate));
+
+       object_class = G_OBJECT_CLASS (class);
+       object_class->set_property = filter_output_stream_set_property;
+       object_class->get_property = filter_output_stream_get_property;
+       object_class->dispose = filter_output_stream_dispose;
+
+       stream_class = G_OUTPUT_STREAM_CLASS (class);
+       stream_class->write_fn = filter_output_stream_write;
+       stream_class->flush = filter_output_stream_flush;
+
+       g_object_class_install_property (
+               object_class,
+               PROP_FILTER,
+               g_param_spec_object (
+                       "filter",
+                       "Filter",
+                       "The MIME filter object",
+                       CAMEL_TYPE_MIME_FILTER,
+                       G_PARAM_READWRITE |
+                       G_PARAM_CONSTRUCT_ONLY |
+                       G_PARAM_STATIC_STRINGS));
+}
+
+static void
+camel_filter_output_stream_init (CamelFilterOutputStream *filter_stream)
+{
+       filter_stream->priv =
+               CAMEL_FILTER_OUTPUT_STREAM_GET_PRIVATE (filter_stream);
+}
+
+/**
+ * camel_filter_output_stream_new:
+ * @base_stream: a #GOutputStream
+ * @filter: a #CamelMimeFilter
+ *
+ * Creates a new filtered output stream for the @base_stream.
+ *
+ * Returns: a new #GOutputStream
+ *
+ * Since: 3.12
+ **/
+GOutputStream *
+camel_filter_output_stream_new (GOutputStream *base_stream,
+                                CamelMimeFilter *filter)
+{
+       g_return_val_if_fail (G_IS_OUTPUT_STREAM (base_stream), NULL);
+       g_return_val_if_fail (CAMEL_IS_MIME_FILTER (filter), NULL);
+
+       return g_object_new (
+               CAMEL_TYPE_FILTER_OUTPUT_STREAM,
+               "base-stream", base_stream,
+               "filter", filter, NULL);
+}
+
+/**
+ * camel_filter_output_stream_get_filter:
+ * @filter_stream: a #CamelFilterOutputStream
+ *
+ * Gets the #CamelMimeFilter that is used by @filter_stream.
+ *
+ * Returns: a #CamelMimeFilter
+ *
+ * Since: 3.12
+ **/
+CamelMimeFilter *
+camel_filter_output_stream_get_filter (CamelFilterOutputStream *filter_stream)
+{
+       g_return_val_if_fail (
+               CAMEL_IS_FILTER_OUTPUT_STREAM (filter_stream), NULL);
+
+       return filter_stream->priv->filter;
+}
+
diff --git a/camel/camel-filter-output-stream.h b/camel/camel-filter-output-stream.h
new file mode 100644
index 0000000..2a8a883
--- /dev/null
+++ b/camel/camel-filter-output-stream.h
@@ -0,0 +1,75 @@
+/*
+ * camel-filter-output-stream.h
+ *
+ * This program 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; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+#if !defined (__CAMEL_H_INSIDE__) && !defined (CAMEL_COMPILATION)
+#error "Only <camel/camel.h> can be included directly."
+#endif
+
+#ifndef CAMEL_FILTER_OUTPUT_STREAM_H
+#define CAMEL_FILTER_OUTPUT_STREAM_H
+
+#include <gio/gio.h>
+#include <camel/camel-mime-filter.h>
+
+/* Standard GObject macros */
+#define CAMEL_TYPE_FILTER_OUTPUT_STREAM \
+       (camel_filter_output_stream_get_type ())
+#define CAMEL_FILTER_OUTPUT_STREAM(obj) \
+       (G_TYPE_CHECK_INSTANCE_CAST \
+       ((obj), CAMEL_TYPE_FILTER_OUTPUT_STREAM, CamelFilterOutputStream))
+#define CAMEL_FILTER_OUTPUT_STREAM_CLASS(cls) \
+       (G_TYPE_CHECK_CLASS_CAST \
+       ((cls), CAMEL_TYPE_FILTER_OUTPUT_STREAM, CamelFilterOutputStreamClass))
+#define CAMEL_IS_FILTER_OUTPUT_STREAM(obj) \
+       (G_TYPE_CHECK_INSTANCE_TYPE \
+       ((obj), CAMEL_TYPE_FILTER_OUTPUT_STREAM))
+#define CAMEL_IS_FILTER_OUTPUT_STREAM_CLASS(cls) \
+       (G_TYPE_CHECK_CLASS_TYPE \
+       ((cls), CAMEL_TYPE_FILTER_OUTPUT_STREAM))
+#define CAMEL_FILTER_OUTPUT_STREAM_GET_CLASS(obj) \
+       (G_TYPE_INSTANCE_GET_CLASS \
+       ((obj), CAMEL_TYPE_FILTER_OUTPUT_STREAM, CamelFilterOutputStreamClass))
+
+G_BEGIN_DECLS
+
+typedef struct _CamelFilterOutputStream CamelFilterOutputStream;
+typedef struct _CamelFilterOutputStreamClass CamelFilterOutputStreamClass;
+typedef struct _CamelFilterOutputStreamPrivate CamelFilterOutputStreamPrivate;
+
+struct _CamelFilterOutputStream {
+       GFilterOutputStream parent;
+       CamelFilterOutputStreamPrivate *priv;
+};
+
+struct _CamelFilterOutputStreamClass {
+       GFilterOutputStreamClass parent_class;
+};
+
+GType          camel_filter_output_stream_get_type
+                                       (void) G_GNUC_CONST;
+GOutputStream *        camel_filter_output_stream_new
+                                       (GOutputStream *base_stream,
+                                        CamelMimeFilter *filter);
+CamelMimeFilter *
+               camel_filter_output_stream_get_filter
+                                       (CamelFilterOutputStream *filter_stream);
+
+G_END_DECLS
+
+#endif /* CAMEL_FILTER_OUTPUT_STREAM_H */
+
diff --git a/camel/camel.h b/camel/camel.h
index f8d766e..1087b3c 100644
--- a/camel/camel.h
+++ b/camel/camel.h
@@ -43,6 +43,7 @@
 #include <camel/camel-file-utils.h>
 #include <camel/camel-filter-driver.h>
 #include <camel/camel-filter-input-stream.h>
+#include <camel/camel-filter-output-stream.h>
 #include <camel/camel-filter-search.h>
 #include <camel/camel-folder.h>
 #include <camel/camel-folder-search.h>
diff --git a/docs/reference/camel/camel-docs.sgml b/docs/reference/camel/camel-docs.sgml
index 742d66f..0ccf7d0 100644
--- a/docs/reference/camel/camel-docs.sgml
+++ b/docs/reference/camel/camel-docs.sgml
@@ -62,6 +62,7 @@
       <title>Stream Filters</title>
       <xi:include href="xml/camel-mime-filter.xml"/>
       <xi:include href="xml/camel-filter-input-stream.xml"/>
+      <xi:include href="xml/camel-filter-output-stream.xml"/>
       <xi:include href="xml/camel-mime-filter-basic.xml"/>
       <xi:include href="xml/camel-mime-filter-bestenc.xml"/>
       <xi:include href="xml/camel-mime-filter-canon.xml"/>
diff --git a/docs/reference/camel/camel-sections.txt b/docs/reference/camel/camel-sections.txt
index e59ad4b..707a8d9 100644
--- a/docs/reference/camel/camel-sections.txt
+++ b/docs/reference/camel/camel-sections.txt
@@ -415,6 +415,25 @@ CamelFilterInputStreamPrivate
 </SECTION>
 
 <SECTION>
+<FILE>camel-filter-output-stream</FILE>
+<TITLE>CamelFilterOutputStream</TITLE>
+CamelFilterOutputStream
+camel_filter_output_stream_new
+camel_filter_output_stream_get_filter
+<SUBSECTION Standard>
+CAMEL_FILTER_OUTPUT_STREAM
+CAMEL_IS_FILTER_OUTPUT_STREAM
+CAMEL_TYPE_FILTER_OUTPUT_STREAM
+CAMEL_FILTER_OUTPUT_STREAM_CLASS
+CAMEL_IS_FILTER_OUTPUT_STREAM_CLASS
+CAMEL_FILTER_OUTPUT_STREAM_GET_CLASS
+CamelFilterOutputStreamClass
+camel_filter_output_stream_get_type
+<SUBSECTION Private>
+CamelFilterOutputStreamPrivate
+</SECTION>
+
+<SECTION>
 <FILE>camel-folder</FILE>
 <TITLE>CamelFolder</TITLE>
 CamelFolderFlags
diff --git a/docs/reference/camel/camel.types b/docs/reference/camel/camel.types
index 11a64c6..d2e439c 100644
--- a/docs/reference/camel/camel.types
+++ b/docs/reference/camel/camel.types
@@ -12,6 +12,7 @@ camel_disco_folder_get_type
 camel_disco_store_get_type
 camel_filter_driver_get_type
 camel_filter_input_stream_get_type
+camel_filter_output_stream_get_type
 camel_folder_get_type
 camel_folder_search_get_type
 camel_folder_summary_get_type


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]