Return back camel_stream_reset() functionality where required
authorMilan Crha <mcrha@redhat.com>
Tue, 26 Jul 2011 20:19:58 +0000 (22:19 +0200)
committerMilan Crha <mcrha@redhat.com>
Tue, 26 Jul 2011 20:19:58 +0000 (22:19 +0200)
camel/camel-data-wrapper.c
camel/camel-http-stream.c
camel/camel-stream-filter.c
camel/camel-stream-null.c

index 958117d..f640f96 100644 (file)
@@ -236,6 +236,13 @@ data_wrapper_construct_from_stream_sync (CamelDataWrapper *data_wrapper,
                return FALSE;
        }
 
+       if (G_IS_SEEKABLE (stream)) {
+               if (!g_seekable_seek (G_SEEKABLE (stream), 0, G_SEEK_SET, cancellable, error)) {
+                       camel_data_wrapper_unlock (data_wrapper, CAMEL_DATA_WRAPPER_STREAM_LOCK);
+                       return FALSE;
+               }
+       }
+
        /* Wipe any previous contents from our byte array. */
        g_byte_array_set_size (data_wrapper->priv->byte_array, 0);
 
index ae2b64e..10a2206 100644 (file)
@@ -30,6 +30,8 @@
 #include <stdlib.h>
 #include <string.h>
 
+#include <glib/gi18n-lib.h>
+
 #include "camel-http-stream.h"
 #include "camel-mime-utils.h"
 #include "camel-net-utils.h"
 
 #define d(x)
 
-G_DEFINE_TYPE (CamelHttpStream, camel_http_stream, CAMEL_TYPE_STREAM)
+static void camel_http_stream_seekable_init (GSeekableIface *interface);
+
+G_DEFINE_TYPE_WITH_CODE (CamelHttpStream, camel_http_stream, CAMEL_TYPE_STREAM,
+       G_IMPLEMENT_INTERFACE (G_TYPE_SEEKABLE, camel_http_stream_seekable_init))
 
 static CamelStream *
 http_connect (CamelHttpStream *http,
@@ -512,6 +517,62 @@ http_stream_close (CamelStream *stream,
        return 0;
 }
 
+static goffset
+http_stream_tell (GSeekable *seekable)
+{
+       return 0;
+}
+
+static gboolean
+http_stream_can_seek (GSeekable *seekable)
+{
+       return TRUE;
+}
+
+static gboolean
+http_stream_seek (GSeekable *seekable,
+                 goffset offset,
+                 GSeekType type,
+                 GCancellable *cancellable,
+                 GError **error)
+{
+       CamelHttpStream *http;
+
+       http = CAMEL_HTTP_STREAM (seekable);
+
+       if (type != G_SEEK_SET || offset != 0) {
+               g_set_error_literal (
+                       error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
+                       _("Only reset to beginning is supported with CamelHttpStream"));
+               return FALSE;
+       }
+
+       if (http->raw)
+               http_disconnect (http);
+
+       return TRUE;
+}
+
+static gboolean
+http_stream_can_truncate (GSeekable *seekable)
+{
+       return FALSE;
+}
+
+static gboolean
+http_stream_truncate_fn (GSeekable *seekable,
+                        goffset offset,
+                        GCancellable *cancellable,
+                        GError **error)
+{
+       /* XXX Don't bother translating this.  Camel never calls it. */
+       g_set_error_literal (
+               error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
+               "Truncation is not supported");
+
+       return FALSE;
+}
+
 static void
 camel_http_stream_class_init (CamelHttpStreamClass *class)
 {
@@ -530,6 +591,16 @@ camel_http_stream_class_init (CamelHttpStreamClass *class)
 }
 
 static void
+camel_http_stream_seekable_init (GSeekableIface *interface)
+{
+       interface->tell = http_stream_tell;
+       interface->can_seek = http_stream_can_seek;
+       interface->seek = http_stream_seek;
+       interface->can_truncate = http_stream_can_truncate;
+       interface->truncate_fn = http_stream_truncate_fn;
+}
+
+static void
 camel_http_stream_init (CamelHttpStream *http)
 {
 }
index 1f44cfb..ace197e 100644 (file)
@@ -27,6 +27,8 @@
 #include <stdio.h>
 #include <string.h>
 
+#include <glib/gi18n-lib.h>
+
 #include "camel-stream-filter.h"
 
 #define d(x)
@@ -61,7 +63,10 @@ struct _CamelStreamFilterPrivate {
 #define READ_PAD (128)         /* bytes padded before buffer */
 #define READ_SIZE (4096)
 
-G_DEFINE_TYPE (CamelStreamFilter, camel_stream_filter, CAMEL_TYPE_STREAM)
+static void camel_stream_filter_seekable_init (GSeekableIface *interface);
+
+G_DEFINE_TYPE_WITH_CODE (CamelStreamFilter, camel_stream_filter, CAMEL_TYPE_STREAM,
+       G_IMPLEMENT_INTERFACE (G_TYPE_SEEKABLE, camel_stream_filter_seekable_init))
 
 static void
 stream_filter_finalize (GObject *object)
@@ -288,6 +293,75 @@ stream_filter_eos (CamelStream *stream)
        return camel_stream_eos (priv->source);
 }
 
+static goffset
+stream_filter_tell (GSeekable *seekable)
+{
+       CamelStreamFilterPrivate *priv;
+
+       priv = CAMEL_STREAM_FILTER (seekable)->priv;
+
+       return priv->source && G_IS_SEEKABLE (priv->source) ? g_seekable_tell (G_SEEKABLE (priv->source)) : 0;
+}
+
+static gboolean
+stream_filter_can_seek (GSeekable *seekable)
+{
+       return TRUE;
+}
+
+static gboolean
+stream_filter_seek (GSeekable *seekable,
+                   goffset offset,
+                   GSeekType type,
+                   GCancellable *cancellable,
+                   GError **error)
+{
+       CamelStreamFilterPrivate *priv;
+       struct _filter *f;
+
+       priv = CAMEL_STREAM_FILTER (seekable)->priv;
+
+       if (type != G_SEEK_SET || offset != 0) {
+               g_set_error_literal (
+                       error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
+                       _("Only reset to beginning is supported with CamelStreamFilter"));
+               return FALSE;
+       }
+
+       priv->filteredlen = 0;
+       priv->flushed = FALSE;
+
+       f = priv->filters;
+       while (f) {
+               if (G_IS_SEEKABLE (f->filter) && !g_seekable_seek (G_SEEKABLE (f->filter), offset, type, cancellable, error))
+                       return FALSE;
+
+               f = f->next;
+       }
+
+       return priv->source && G_IS_SEEKABLE (priv->source) ? g_seekable_seek (G_SEEKABLE (priv->source), offset, type, cancellable, error) : TRUE;
+}
+
+static gboolean
+stream_filter_can_truncate (GSeekable *seekable)
+{
+       return FALSE;
+}
+
+static gboolean
+stream_filter_truncate_fn (GSeekable *seekable,
+                          goffset offset,
+                          GCancellable *cancellable,
+                          GError **error)
+{
+       /* XXX Don't bother translating this.  Camel never calls it. */
+       g_set_error_literal (
+               error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
+               "Truncation is not supported");
+
+       return FALSE;
+}
+
 static void
 camel_stream_filter_class_init (CamelStreamFilterClass *class)
 {
@@ -308,6 +382,16 @@ camel_stream_filter_class_init (CamelStreamFilterClass *class)
 }
 
 static void
+camel_stream_filter_seekable_init (GSeekableIface *interface)
+{
+       interface->tell = stream_filter_tell;
+       interface->can_seek = stream_filter_can_seek;
+       interface->seek = stream_filter_seek;
+       interface->can_truncate = stream_filter_can_truncate;
+       interface->truncate_fn = stream_filter_truncate_fn;
+}
+
+static void
 camel_stream_filter_init (CamelStreamFilter *stream)
 {
        stream->priv = G_TYPE_INSTANCE_GET_PRIVATE (
index 48bf012..1d25ea0 100644 (file)
 #include <config.h>
 #endif
 
+#include <glib/gi18n-lib.h>
+
 #include "camel-stream-null.h"
 
-G_DEFINE_TYPE (CamelStreamNull, camel_stream_null, CAMEL_TYPE_STREAM)
+static void camel_stream_null_seekable_init (GSeekableIface *interface);
+
+G_DEFINE_TYPE_WITH_CODE (CamelStreamNull, camel_stream_null, CAMEL_TYPE_STREAM,
+       G_IMPLEMENT_INTERFACE (G_TYPE_SEEKABLE, camel_stream_null_seekable_init))
 
 static gssize
 stream_null_write (CamelStream *stream,
@@ -48,6 +53,57 @@ stream_null_eos (CamelStream *stream)
        return TRUE;
 }
 
+static goffset
+stream_null_tell (GSeekable *seekable)
+{
+       return 0;
+}
+
+static gboolean
+stream_null_can_seek (GSeekable *seekable)
+{
+       return TRUE;
+}
+
+static gboolean
+stream_null_seek (GSeekable *seekable,
+                 goffset offset,
+                 GSeekType type,
+                 GCancellable *cancellable,
+                 GError **error)
+{
+       if (type != G_SEEK_SET || offset != 0) {
+               g_set_error_literal (
+                       error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
+                       _("Only reset to beginning is supported with CamelHttpStream"));
+               return FALSE;
+       }
+
+       CAMEL_STREAM_NULL (seekable)->written = 0;
+
+       return TRUE;
+}
+
+static gboolean
+stream_null_can_truncate (GSeekable *seekable)
+{
+       return FALSE;
+}
+
+static gboolean
+stream_null_truncate_fn (GSeekable *seekable,
+                        goffset offset,
+                        GCancellable *cancellable,
+                        GError **error)
+{
+       /* XXX Don't bother translating this.  Camel never calls it. */
+       g_set_error_literal (
+               error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
+               "Truncation is not supported");
+
+       return FALSE;
+}
+
 static void
 camel_stream_null_class_init (CamelStreamNullClass *class)
 {
@@ -59,6 +115,16 @@ camel_stream_null_class_init (CamelStreamNullClass *class)
 }
 
 static void
+camel_stream_null_seekable_init (GSeekableIface *interface)
+{
+       interface->tell = stream_null_tell;
+       interface->can_seek = stream_null_can_seek;
+       interface->seek = stream_null_seek;
+       interface->can_truncate = stream_null_can_truncate;
+       interface->truncate_fn = stream_null_truncate_fn;
+}
+
+static void
 camel_stream_null_init (CamelStreamNull *stream_null)
 {
 }