[evolution-data-server] Add CamelFilterOutputStream.
- From: Matthew Barnes <mbarnes src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-data-server] Add CamelFilterOutputStream.
- Date: Tue, 1 Oct 2013 20:06:39 +0000 (UTC)
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]