[evolution-data-server] CamelDataWrapper: Add construct_from_input_stream() method.
- From: Matthew Barnes <mbarnes src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-data-server] CamelDataWrapper: Add construct_from_input_stream() method.
- Date: Thu, 6 Mar 2014 22:55:36 +0000 (UTC)
commit ece444a151d8edb1daf1eedab5b56beb0daaefba
Author: Matthew Barnes <mbarnes redhat com>
Date: Thu Mar 6 17:10:55 2014 -0500
CamelDataWrapper: Add construct_from_input_stream() method.
Takes a GInputStream instead of a CamelStream. This will eventually
replace the construct_from_stream() method.
New functions:
camel_data_wrapper_construct_from_input_stream_sync()
camel_data_wrapper_construct_from_input_stream()
camel_data_wrapper_construct_from_input_stream_finish()
Also adapted subclass methods in:
CamelMimePart
CamelMultipartSigned
camel/camel-data-wrapper.c | 196 +++++++++++++++++++++++++++++++
camel/camel-data-wrapper.h | 23 ++++-
camel/camel-mime-part.c | 21 ++++
camel/camel-multipart-signed.c | 27 +++++
docs/reference/camel/camel-sections.txt | 3 +
5 files changed, 269 insertions(+), 1 deletions(-)
---
diff --git a/camel/camel-data-wrapper.c b/camel/camel-data-wrapper.c
index 291ee51..c454e46 100644
--- a/camel/camel-data-wrapper.c
+++ b/camel/camel-data-wrapper.c
@@ -48,6 +48,7 @@ struct _CamelDataWrapperPrivate {
struct _AsyncContext {
CamelStream *stream;
+ GInputStream *input_stream;
GOutputStream *output_stream;
};
@@ -57,6 +58,7 @@ static void
async_context_free (AsyncContext *async_context)
{
g_clear_object (&async_context->stream);
+ g_clear_object (&async_context->input_stream);
g_clear_object (&async_context->output_stream);
g_slice_free (AsyncContext, async_context);
@@ -355,6 +357,63 @@ data_wrapper_decode_to_output_stream_sync (CamelDataWrapper *data_wrapper,
return bytes_written;
}
+static gboolean
+data_wrapper_construct_from_input_stream_sync (CamelDataWrapper *data_wrapper,
+ GInputStream *input_stream,
+ GCancellable *cancellable,
+ GError **error)
+{
+ GOutputStream *output_stream;
+ gssize bytes_written;
+ gboolean success;
+
+ /* XXX Should keep the internal data as a reference-counted
+ * GBytes to avoid locking while reading from the stream. */
+
+ g_mutex_lock (&data_wrapper->priv->stream_lock);
+
+ /* Check for cancellation after locking. */
+ if (g_cancellable_set_error_if_cancelled (cancellable, error)) {
+ g_mutex_unlock (&data_wrapper->priv->stream_lock);
+ return FALSE;
+ }
+
+ if (G_IS_SEEKABLE (input_stream)) {
+ success = g_seekable_seek (
+ G_SEEKABLE (input_stream), 0,
+ G_SEEK_SET, cancellable, error);
+ if (!success) {
+ g_mutex_unlock (&data_wrapper->priv->stream_lock);
+ return FALSE;
+ }
+ }
+
+ output_stream = g_memory_output_stream_new_resizable ();
+
+ bytes_written = g_output_stream_splice (
+ output_stream, input_stream,
+ G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET,
+ cancellable, error);
+
+ success = (bytes_written >= 0);
+
+ if (success) {
+ GBytes *bytes;
+
+ bytes = g_memory_output_stream_steal_as_bytes (
+ G_MEMORY_OUTPUT_STREAM (output_stream));
+
+ g_byte_array_free (data_wrapper->priv->byte_array, TRUE);
+ data_wrapper->priv->byte_array = g_bytes_unref_to_array (bytes);
+ }
+
+ g_object_unref (output_stream);
+
+ g_mutex_unlock (&data_wrapper->priv->stream_lock);
+
+ return success;
+}
+
static void
camel_data_wrapper_class_init (CamelDataWrapperClass *class)
{
@@ -377,6 +436,7 @@ camel_data_wrapper_class_init (CamelDataWrapperClass *class)
class->construct_from_stream_sync = data_wrapper_construct_from_stream_sync;
class->write_to_output_stream_sync = data_wrapper_write_to_output_stream_sync;
class->decode_to_output_stream_sync = data_wrapper_decode_to_output_stream_sync;
+ class->construct_from_input_stream_sync = data_wrapper_construct_from_input_stream_sync;
}
static void
@@ -1261,3 +1321,139 @@ camel_data_wrapper_decode_to_output_stream_finish (CamelDataWrapper *data_wrappe
return g_task_propagate_int (G_TASK (result), error);
}
+/**
+ * camel_data_wrapper_construct_from_input_stream_sync:
+ * @data_wrapper: a #CamelDataWrapper
+ * @input_stream: a #GInputStream
+ * @cancellable: optional #GCancellable object, or %NULL
+ * @error: return location for a #GError, or %NULL
+ *
+ * Constructs the content of @data_wrapper from @input_stream.
+ *
+ * Returns: %TRUE on success, %FALSE on error
+ *
+ * Since: 3.12
+ **/
+gboolean
+camel_data_wrapper_construct_from_input_stream_sync (CamelDataWrapper *data_wrapper,
+ GInputStream *input_stream,
+ GCancellable *cancellable,
+ GError **error)
+{
+ CamelDataWrapperClass *class;
+ gboolean success;
+
+ g_return_val_if_fail (CAMEL_IS_DATA_WRAPPER (data_wrapper), FALSE);
+ g_return_val_if_fail (G_IS_INPUT_STREAM (input_stream), FALSE);
+
+ class = CAMEL_DATA_WRAPPER_GET_CLASS (data_wrapper);
+ g_return_val_if_fail (class->construct_from_input_stream_sync != NULL, FALSE);
+
+ success = class->construct_from_input_stream_sync (
+ data_wrapper, input_stream, cancellable, error);
+ CAMEL_CHECK_GERROR (
+ data_wrapper, construct_from_input_stream_sync, success, error);
+
+ return success;
+}
+
+/* Helper for camel_data_wrapper_construct_from_input_stream() */
+static void
+data_wrapper_construct_from_input_stream_thread (GTask *task,
+ gpointer source_object,
+ gpointer task_data,
+ GCancellable *cancellable)
+{
+ gboolean success;
+ AsyncContext *async_context;
+ GError *local_error = NULL;
+
+ async_context = (AsyncContext *) task_data;
+
+ success = camel_data_wrapper_construct_from_input_stream_sync (
+ CAMEL_DATA_WRAPPER (source_object),
+ async_context->input_stream,
+ cancellable, &local_error);
+
+ if (local_error != NULL) {
+ g_task_return_error (task, local_error);
+ } else {
+ g_task_return_boolean (task, success);
+ }
+}
+
+/**
+ * camel_data_wrapper_construct_from_input_stream:
+ * @data_wrapper: a #CamelDataWrapper
+ * @input_stream: a #GInputStream
+ * @io_priority: the I/O priority of the request
+ * @cancellable: optional #GCancellable object, or %NULL
+ * @callback: a #GAsyncReadyCallback to call when the request is satisfied
+ * @user_data: data to pass to the callback function
+ *
+ * Asynchronously constructs the content of @data_wrapper from @input_stream.
+ *
+ * When the operation is finished, @callback will be called. You can then
+ * call camel_data_wrapper_construct_from_input_stream_finish() to get the
+ * result of the operation.
+ *
+ * Since: 3.12
+ **/
+void
+camel_data_wrapper_construct_from_input_stream (CamelDataWrapper *data_wrapper,
+ GInputStream *input_stream,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GTask *task;
+ AsyncContext *async_context;
+
+ g_return_if_fail (CAMEL_IS_DATA_WRAPPER (data_wrapper));
+ g_return_if_fail (G_IS_INPUT_STREAM (input_stream));
+
+ async_context = g_slice_new0 (AsyncContext);
+ async_context->input_stream = g_object_ref (input_stream);
+
+ task = g_task_new (data_wrapper, cancellable, callback, user_data);
+ g_task_set_source_tag (task, camel_data_wrapper_construct_from_input_stream);
+ g_task_set_priority (task, io_priority);
+
+ g_task_set_task_data (
+ task, async_context,
+ (GDestroyNotify) async_context_free);
+
+ g_task_run_in_thread (task, data_wrapper_construct_from_input_stream_thread);
+
+ g_object_unref (task);
+}
+
+/**
+ * camel_data_wrapper_construct_from_input_stream_finish:
+ * @data_wrapper: a #CamelDataWrapper
+ * @result: a #GAsyncResult
+ * @error: return location for a #GError, or %NULL
+ *
+ * Finishes the operation started with
+ * camel_data_wrapper_construct_from_input_stream().
+ *
+ * Returns: %TRUE on success, %FALSE on error
+ *
+ * Since: 3.12
+ **/
+gboolean
+camel_data_wrapper_construct_from_input_stream_finish (CamelDataWrapper *data_wrapper,
+ GAsyncResult *result,
+ GError **error)
+{
+ g_return_val_if_fail (CAMEL_IS_DATA_WRAPPER (data_wrapper), FALSE);
+ g_return_val_if_fail (g_task_is_valid (result, data_wrapper), FALSE);
+
+ g_return_val_if_fail (
+ g_async_result_is_tagged (
+ result, camel_data_wrapper_construct_from_input_stream), FALSE);
+
+ return g_task_propagate_boolean (G_TASK (result), error);
+}
+
diff --git a/camel/camel-data-wrapper.h b/camel/camel-data-wrapper.h
index 9199167..09990d8 100644
--- a/camel/camel-data-wrapper.h
+++ b/camel/camel-data-wrapper.h
@@ -105,9 +105,14 @@ struct _CamelDataWrapperClass {
GOutputStream *output_stream,
GCancellable *cancellable,
GError **error);
+ gboolean (*construct_from_input_stream_sync)
+ (CamelDataWrapper *data_wrapper,
+ GInputStream *input_stream,
+ GCancellable *cancellable,
+ GError **error);
/* Reserved slots. */
- gpointer reserved[4];
+ gpointer reserved[3];
};
GType camel_data_wrapper_get_type (void);
@@ -208,6 +213,22 @@ gssize camel_data_wrapper_decode_to_output_stream_finish
(CamelDataWrapper *data_wrapper,
GAsyncResult *result,
GError **error);
+gboolean camel_data_wrapper_construct_from_input_stream_sync
+ (CamelDataWrapper *data_wrapper,
+ GInputStream *input_stream,
+ GCancellable *cancellable,
+ GError **error);
+void camel_data_wrapper_construct_from_input_stream
+ (CamelDataWrapper *data_wrapper,
+ GInputStream *input_stream,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+gboolean camel_data_wrapper_construct_from_input_stream_finish
+ (CamelDataWrapper *data_wrapper,
+ GAsyncResult *result,
+ GError **error);
G_END_DECLS
diff --git a/camel/camel-mime-part.c b/camel/camel-mime-part.c
index 5563f6e..fbb783c 100644
--- a/camel/camel-mime-part.c
+++ b/camel/camel-mime-part.c
@@ -966,6 +966,26 @@ mime_part_write_to_output_stream_sync (CamelDataWrapper *dw,
}
static gboolean
+mime_part_construct_from_input_stream_sync (CamelDataWrapper *dw,
+ GInputStream *input_stream,
+ GCancellable *cancellable,
+ GError **error)
+{
+ CamelMimeParser *parser;
+ gboolean success;
+
+ parser = camel_mime_parser_new ();
+ camel_mime_parser_init_with_input_stream (parser, input_stream);
+
+ success = camel_mime_part_construct_from_parser_sync (
+ CAMEL_MIME_PART (dw), parser, cancellable, error);
+
+ g_object_unref (parser);
+
+ return success;
+}
+
+static gboolean
mime_part_construct_from_parser_sync (CamelMimePart *mime_part,
CamelMimeParser *parser,
GCancellable *cancellable,
@@ -1053,6 +1073,7 @@ camel_mime_part_class_init (CamelMimePartClass *class)
data_wrapper_class->write_to_stream_sync = mime_part_write_to_stream_sync;
data_wrapper_class->construct_from_stream_sync = mime_part_construct_from_stream_sync;
data_wrapper_class->write_to_output_stream_sync = mime_part_write_to_output_stream_sync;
+ data_wrapper_class->construct_from_input_stream_sync = mime_part_construct_from_input_stream_sync;
class->construct_from_parser_sync = mime_part_construct_from_parser_sync;
diff --git a/camel/camel-multipart-signed.c b/camel/camel-multipart-signed.c
index a02200f..228bf7f 100644
--- a/camel/camel-multipart-signed.c
+++ b/camel/camel-multipart-signed.c
@@ -528,6 +528,32 @@ multipart_signed_write_to_output_stream_sync (CamelDataWrapper *data_wrapper,
return total;
}
+static gboolean
+multipart_signed_construct_from_input_stream_sync (CamelDataWrapper *data_wrapper,
+ GInputStream *input_stream,
+ GCancellable *cancellable,
+ GError **error)
+{ CamelMultipartSignedPrivate *priv;
+ gboolean success;
+
+ priv = CAMEL_MULTIPART_SIGNED_GET_PRIVATE (data_wrapper);
+
+ /* Chain up to parent's construct_from_input_stream_sync() method. */
+ success = CAMEL_DATA_WRAPPER_CLASS (
+ camel_multipart_signed_parent_class)->
+ construct_from_input_stream_sync (
+ data_wrapper, input_stream, cancellable, error);
+
+ if (success) {
+ priv->start1 = -1;
+ g_clear_object (&priv->content);
+ g_clear_object (&priv->signature);
+ g_clear_object (&priv->contentraw);
+ }
+
+ return success;
+}
+
static void
multipart_signed_add_part (CamelMultipart *multipart,
CamelMimePart *part)
@@ -694,6 +720,7 @@ camel_multipart_signed_class_init (CamelMultipartSignedClass *class)
data_wrapper_class->construct_from_stream_sync = multipart_signed_construct_from_stream_sync;
data_wrapper_class->write_to_output_stream_sync = multipart_signed_write_to_output_stream_sync;
data_wrapper_class->decode_to_output_stream_sync = multipart_signed_write_to_output_stream_sync;
+ data_wrapper_class->construct_from_input_stream_sync =
multipart_signed_construct_from_input_stream_sync;
multipart_class = CAMEL_MULTIPART_CLASS (class);
multipart_class->add_part = multipart_signed_add_part;
diff --git a/docs/reference/camel/camel-sections.txt b/docs/reference/camel/camel-sections.txt
index c2c27a3..c31c730 100644
--- a/docs/reference/camel/camel-sections.txt
+++ b/docs/reference/camel/camel-sections.txt
@@ -226,6 +226,9 @@ camel_data_wrapper_write_to_output_stream_finish
camel_data_wrapper_decode_to_output_stream_sync
camel_data_wrapper_decode_to_output_stream
camel_data_wrapper_decode_to_output_stream_finish
+camel_data_wrapper_construct_from_input_stream_sync
+camel_data_wrapper_construct_from_input_stream
+camel_data_wrapper_construct_from_input_stream_finish
<SUBSECTION Standard>
CAMEL_DATA_WRAPPER
CAMEL_IS_DATA_WRAPPER
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]