[evolution-data-server] Add CamelFilterInputStream.



commit f400a1613785c9c7634066f444b459150ab6905a
Author: Matthew Barnes <mbarnes redhat com>
Date:   Tue Oct 1 10:19:07 2013 -0400

    Add CamelFilterInputStream.
    
    CamelFilterInputStream is similar to GConverterInputStream, 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-input-stream.c       |  262 +++++++++++++++++++++++++++++++
 camel/camel-filter-input-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, 361 insertions(+), 0 deletions(-)
---
diff --git a/camel/Makefile.am b/camel/Makefile.am
index 74a33f8..e6027a9 100644
--- a/camel/Makefile.am
+++ b/camel/Makefile.am
@@ -75,6 +75,7 @@ libcamel_1_2_la_SOURCES =                     \
        camel-disco-store.c                     \
        camel-file-utils.c                      \
        camel-filter-driver.c                   \
+       camel-filter-input-stream.c             \
        camel-filter-search.c                   \
        camel-folder-search.c                   \
        camel-folder-summary.c                  \
@@ -203,6 +204,7 @@ libcamelinclude_HEADERS =                   \
        camel-enumtypes.h                       \
        camel-file-utils.h                      \
        camel-filter-driver.h                   \
+       camel-filter-input-stream.h             \
        camel-filter-search.h                   \
        camel-folder-search.h                   \
        camel-folder-summary.h                  \
diff --git a/camel/camel-filter-input-stream.c b/camel/camel-filter-input-stream.c
new file mode 100644
index 0000000..a5d58e3
--- /dev/null
+++ b/camel/camel-filter-input-stream.c
@@ -0,0 +1,262 @@
+/*
+ * camel-filter-input-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-input-stream
+ * @short_description: Filtered input stream
+ * @include: camel/camel.h
+ * @see_also: #GInputStream, #CamelMimeFilter
+ *
+ * #CamelFilterInputStream is similar to #GConverterInputStream, 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-input-stream.h"
+
+#include <string.h>
+
+#define CAMEL_FILTER_INPUT_STREAM_GET_PRIVATE(obj) \
+       (G_TYPE_INSTANCE_GET_PRIVATE \
+       ((obj), CAMEL_TYPE_FILTER_INPUT_STREAM, CamelFilterInputStreamPrivate))
+
+#define READ_PAD (128)         /* bytes padded before buffer */
+#define READ_SIZE (4096)
+
+struct _CamelFilterInputStreamPrivate {
+       CamelMimeFilter *filter;
+
+       gchar real_buffer[READ_SIZE + READ_PAD];
+       gchar *buffer;          /* points to real_buffer + READ_PAD */
+
+       gchar *filtered;
+       gsize filtered_length;
+};
+
+enum {
+       PROP_0,
+       PROP_FILTER
+};
+
+G_DEFINE_TYPE (
+       CamelFilterInputStream,
+       camel_filter_input_stream,
+       G_TYPE_FILTER_INPUT_STREAM)
+
+static void
+filter_input_stream_set_filter (CamelFilterInputStream *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_input_stream_set_property (GObject *object,
+                                  guint property_id,
+                                  const GValue *value,
+                                  GParamSpec *pspec)
+{
+       switch (property_id) {
+               case PROP_FILTER:
+                       filter_input_stream_set_filter (
+                               CAMEL_FILTER_INPUT_STREAM (object),
+                               g_value_get_object (value));
+                       return;
+       }
+
+       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+filter_input_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_input_stream_get_filter (
+                               CAMEL_FILTER_INPUT_STREAM (object)));
+                       return;
+       }
+
+       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+filter_input_stream_dispose (GObject *object)
+{
+       CamelFilterInputStreamPrivate *priv;
+
+       priv = CAMEL_FILTER_INPUT_STREAM_GET_PRIVATE (object);
+
+       g_clear_object (&priv->filter);
+
+       /* Chain up to parent's dispose() method. */
+       G_OBJECT_CLASS (camel_filter_input_stream_parent_class)->
+               dispose (object);
+}
+
+static gssize
+filter_input_stream_read (GInputStream *stream,
+                          gpointer buffer,
+                          gsize count,
+                          GCancellable *cancellable,
+                          GError **error)
+{
+       CamelFilterInputStreamPrivate *priv;
+       CamelMimeFilter *filter;
+       GInputStream *base_stream;
+       gssize n_bytes_read;
+       gsize presize = READ_PAD;
+
+       priv = CAMEL_FILTER_INPUT_STREAM_GET_PRIVATE (stream);
+
+       filter = camel_filter_input_stream_get_filter (
+               CAMEL_FILTER_INPUT_STREAM (stream));
+       base_stream = g_filter_input_stream_get_base_stream (
+               G_FILTER_INPUT_STREAM (stream));
+
+       /* If we already have some filtered data, return it. */
+       if (priv->filtered_length > 0)
+               goto exit;
+
+       n_bytes_read = g_input_stream_read (
+               base_stream, priv->buffer,
+               READ_SIZE, cancellable, error);
+
+       if (n_bytes_read == 0) {
+               camel_mime_filter_complete (
+                       filter, priv->filtered, priv->filtered_length, presize,
+                       &priv->filtered, &priv->filtered_length, &presize);
+
+               n_bytes_read = priv->filtered_length;
+
+               if (n_bytes_read > 0)
+                       goto exit;
+       }
+
+       if (n_bytes_read <= 0)
+               return n_bytes_read;
+
+       priv->filtered = priv->buffer;
+       priv->filtered_length = n_bytes_read;
+
+       camel_mime_filter_filter (
+               filter, priv->filtered, priv->filtered_length, presize,
+               &priv->filtered, &priv->filtered_length, &presize);
+
+exit:
+       n_bytes_read = MIN (count, priv->filtered_length);
+       memcpy (buffer, priv->filtered, n_bytes_read);
+       priv->filtered_length -= n_bytes_read;
+       priv->filtered += n_bytes_read;
+
+       return n_bytes_read;
+}
+
+static void
+camel_filter_input_stream_class_init (CamelFilterInputStreamClass *class)
+{
+       GObjectClass *object_class;
+       GInputStreamClass *stream_class;
+
+       g_type_class_add_private (
+               class, sizeof (CamelFilterInputStreamPrivate));
+
+       object_class = G_OBJECT_CLASS (class);
+       object_class->set_property = filter_input_stream_set_property;
+       object_class->get_property = filter_input_stream_get_property;
+       object_class->dispose = filter_input_stream_dispose;
+
+       stream_class = G_INPUT_STREAM_CLASS (class);
+       stream_class->read_fn = filter_input_stream_read;
+
+       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_input_stream_init (CamelFilterInputStream *filter_stream)
+{
+       filter_stream->priv =
+               CAMEL_FILTER_INPUT_STREAM_GET_PRIVATE (filter_stream);
+
+       filter_stream->priv->buffer =
+               filter_stream->priv->real_buffer + READ_PAD;
+}
+
+/**
+ * camel_filter_input_stream_new:
+ * @base_stream: a #GInputStream
+ * @filter: a #CamelMimeFilter
+ *
+ * Creates a new filtered input stream for the @base_stream.
+ *
+ * Returns: a new #GInputStream
+ *
+ * Since: 3.12
+ **/
+GInputStream *
+camel_filter_input_stream_new (GInputStream *base_stream,
+                               CamelMimeFilter *filter)
+{
+       g_return_val_if_fail (G_IS_INPUT_STREAM (base_stream), NULL);
+       g_return_val_if_fail (CAMEL_IS_MIME_FILTER (filter), NULL);
+
+       return g_object_new (
+               CAMEL_TYPE_FILTER_INPUT_STREAM,
+               "base-stream", base_stream,
+               "filter", filter, NULL);
+}
+
+/**
+ * camel_filter_input_stream_get_filter:
+ * @filter_stream: a #CamelFilterInputStream
+ *
+ * Gets the #CamelMimeFilter that is used by @filter_stream.
+ *
+ * Returns: a #CamelMimeFilter
+ *
+ * Since: 3.12
+ **/
+CamelMimeFilter *
+camel_filter_input_stream_get_filter (CamelFilterInputStream *filter_stream)
+{
+       g_return_val_if_fail (
+               CAMEL_IS_FILTER_INPUT_STREAM (filter_stream), NULL);
+
+       return filter_stream->priv->filter;
+}
+
diff --git a/camel/camel-filter-input-stream.h b/camel/camel-filter-input-stream.h
new file mode 100644
index 0000000..51dbb9e
--- /dev/null
+++ b/camel/camel-filter-input-stream.h
@@ -0,0 +1,75 @@
+/*
+ * camel-filter-input-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_INPUT_STREAM_H
+#define CAMEL_FILTER_INPUT_STREAM_H
+
+#include <gio/gio.h>
+#include <camel/camel-mime-filter.h>
+
+/* Standard GObject macros */
+#define CAMEL_TYPE_FILTER_INPUT_STREAM \
+       (camel_filter_input_stream_get_type ())
+#define CAMEL_FILTER_INPUT_STREAM(obj) \
+       (G_TYPE_CHECK_INSTANCE_CAST \
+       ((obj), CAMEL_TYPE_FILTER_INPUT_STREAM, CamelFilterInputStream))
+#define CAMEL_FILTER_INPUT_STREAM_CLASS(cls) \
+       (G_TYPE_CHECK_CLASS_CAST \
+       ((cls), CAMEL_TYPE_FILTER_INPUT_STREAM, CamelFilterInputStreamClass))
+#define CAMEL_IS_FILTER_INPUT_STREAM(obj) \
+       (G_TYPE_CHECK_INSTANCE_TYPE \
+       ((obj), CAMEL_TYPE_FILTER_INPUT_STREAM))
+#define CAMEL_IS_FILTER_INPUT_STREAM_CLASS(cls) \
+       (G_TYPE_CHECK_CLASS_TYPE \
+       ((cls), CAMEL_TYPE_FILTER_INPUT_STREAM))
+#define CAMEL_FILTER_INPUT_STREAM_GET_CLASS(obj) \
+       (G_TYPE_INSTANCE_GET_CLASS \
+       ((obj), CAMEL_TYPE_FILTER_INPUT_STREAM, CamelFilterInputStreamClass))
+
+G_BEGIN_DECLS
+
+typedef struct _CamelFilterInputStream CamelFilterInputStream;
+typedef struct _CamelFilterInputStreamClass CamelFilterInputStreamClass;
+typedef struct _CamelFilterInputStreamPrivate CamelFilterInputStreamPrivate;
+
+struct _CamelFilterInputStream {
+       GFilterInputStream parent;
+       CamelFilterInputStreamPrivate *priv;
+};
+
+struct _CamelFilterInputStreamClass {
+       GFilterInputStreamClass parent_class;
+};
+
+GType          camel_filter_input_stream_get_type
+                                       (void) G_GNUC_CONST;
+GInputStream * camel_filter_input_stream_new
+                                       (GInputStream *base_stream,
+                                        CamelMimeFilter *filter);
+CamelMimeFilter *
+               camel_filter_input_stream_get_filter
+                                       (CamelFilterInputStream *filter_stream);
+
+G_END_DECLS
+
+#endif /* CAMEL_FILTER_INPUT_STREAM_H */
+
diff --git a/camel/camel.h b/camel/camel.h
index 0ea131b..f8d766e 100644
--- a/camel/camel.h
+++ b/camel/camel.h
@@ -42,6 +42,7 @@
 #include <camel/camel-enumtypes.h>
 #include <camel/camel-file-utils.h>
 #include <camel/camel-filter-driver.h>
+#include <camel/camel-filter-input-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 b69cf9c..742d66f 100644
--- a/docs/reference/camel/camel-docs.sgml
+++ b/docs/reference/camel/camel-docs.sgml
@@ -61,6 +61,7 @@
     <chapter id="Stream-Filters">
       <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-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 1f03279..e59ad4b 100644
--- a/docs/reference/camel/camel-sections.txt
+++ b/docs/reference/camel/camel-sections.txt
@@ -396,6 +396,25 @@ CamelFilterDriverPrivate
 </SECTION>
 
 <SECTION>
+<FILE>camel-filter-input-stream</FILE>
+<TITLE>CamelFilterInputStream</TITLE>
+CamelFilterInputStream
+camel_filter_input_stream_new
+camel_filter_input_stream_get_filter
+<SUBSECTION Standard>
+CAMEL_FILTER_INPUT_STREAM
+CAMEL_IS_FILTER_INPUT_STREAM
+CAMEL_TYPE_FILTER_INPUT_STREAM
+CAMEL_FILTER_INPUT_STREAM_CLASS
+CAMEL_IS_FILTER_INPUT_STREAM_CLASS
+CAMEL_FILTER_INPUT_STREAM_GET_CLASS
+CamelFilterInputStreamClass
+camel_filter_input_stream_get_type
+<SUBSECTION Private>
+CamelFilterInputStreamPrivate
+</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 232f34f..11a64c6 100644
--- a/docs/reference/camel/camel.types
+++ b/docs/reference/camel/camel.types
@@ -11,6 +11,7 @@ camel_disco_diary_get_type
 camel_disco_folder_get_type
 camel_disco_store_get_type
 camel_filter_driver_get_type
+camel_filter_input_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]