[evolution-data-server] CamelStream: Implement GSeekable.
- From: Matthew Barnes <mbarnes src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-data-server] CamelStream: Implement GSeekable.
- Date: Wed, 2 Oct 2013 23:48:24 +0000 (UTC)
commit 4075847bb87c9fbf54961da65be817d4a9cab117
Author: Matthew Barnes <mbarnes redhat com>
Date: Wed Oct 2 19:13:50 2013 -0400
CamelStream: Implement GSeekable.
The base GIOStream may be seekable, so implement the GSeekable interface
and simply forward the request to the base GIOStream.
I think pretty much all the CamelStream subclasses are also seekable, so
they should override the base class implementation.
camel/camel-stream.c | 157 +++++++++++++++++++++++++++++++++++++++++++++++---
1 files changed, 149 insertions(+), 8 deletions(-)
---
diff --git a/camel/camel-stream.c b/camel/camel-stream.c
index f2270f4..be5f2ca 100644
--- a/camel/camel-stream.c
+++ b/camel/camel-stream.c
@@ -22,15 +22,12 @@
* USA
*/
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
+#include "camel-stream.h"
-#include <errno.h>
-#include <string.h>
+#include <config.h>
+#include <glib/gi18n-lib.h>
-#include "camel-debug.h"
-#include "camel-stream.h"
+#include <camel/camel-debug.h>
#define CAMEL_STREAM_GET_PRIVATE(obj) \
(G_TYPE_INSTANCE_GET_PRIVATE \
@@ -46,7 +43,16 @@ enum {
PROP_BASE_STREAM
};
-G_DEFINE_TYPE (CamelStream, camel_stream, CAMEL_TYPE_OBJECT)
+/* Forward Declarations */
+static void camel_stream_seekable_init (GSeekableIface *interface);
+
+G_DEFINE_TYPE_WITH_CODE (
+ CamelStream,
+ camel_stream,
+ CAMEL_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE (
+ G_TYPE_SEEKABLE,
+ camel_stream_seekable_init))
static void
stream_set_property (GObject *object,
@@ -211,6 +217,131 @@ stream_eos (CamelStream *stream)
return stream->eos;
}
+static goffset
+stream_tell (GSeekable *seekable)
+{
+ CamelStream *stream;
+ GIOStream *base_stream;
+ goffset position = 0;
+
+ stream = CAMEL_STREAM (seekable);
+ base_stream = camel_stream_ref_base_stream (stream);
+
+ if (G_IS_SEEKABLE (base_stream)) {
+ position = g_seekable_tell (G_SEEKABLE (base_stream));
+ } else if (base_stream != NULL) {
+ g_critical (
+ "Stream type '%s' is not seekable",
+ G_OBJECT_TYPE_NAME (base_stream));
+ }
+
+ g_clear_object (&base_stream);
+
+ return position;
+}
+
+static gboolean
+stream_can_seek (GSeekable *seekable)
+{
+ CamelStream *stream;
+ GIOStream *base_stream;
+ gboolean can_seek = FALSE;
+
+ stream = CAMEL_STREAM (seekable);
+ base_stream = camel_stream_ref_base_stream (stream);
+
+ if (G_IS_SEEKABLE (base_stream))
+ can_seek = g_seekable_can_seek (G_SEEKABLE (base_stream));
+
+ g_clear_object (&base_stream);
+
+ return can_seek;
+}
+
+static gboolean
+stream_seek (GSeekable *seekable,
+ goffset offset,
+ GSeekType type,
+ GCancellable *cancellable,
+ GError **error)
+{
+ CamelStream *stream;
+ GIOStream *base_stream;
+ gboolean success = FALSE;
+
+ stream = CAMEL_STREAM (seekable);
+ base_stream = camel_stream_ref_base_stream (stream);
+
+ if (G_IS_SEEKABLE (base_stream)) {
+ success = g_seekable_seek (
+ G_SEEKABLE (base_stream),
+ offset, type, cancellable, error);
+ } else if (base_stream != NULL) {
+ g_set_error (
+ error, G_IO_ERROR,
+ G_IO_ERROR_NOT_SUPPORTED,
+ _("Stream type '%s' is not seekable"),
+ G_OBJECT_TYPE_NAME (base_stream));
+ } else {
+ g_warn_if_reached ();
+ }
+
+ g_clear_object (&base_stream);
+
+ return success;
+}
+
+static gboolean
+stream_can_truncate (GSeekable *seekable)
+{
+ CamelStream *stream;
+ GIOStream *base_stream;
+ gboolean can_truncate = FALSE;
+
+ stream = CAMEL_STREAM (seekable);
+ base_stream = camel_stream_ref_base_stream (stream);
+
+ if (G_IS_SEEKABLE (base_stream))
+ can_truncate = g_seekable_can_truncate (
+ G_SEEKABLE (base_stream));
+
+ g_clear_object (&base_stream);
+
+ return can_truncate;
+}
+
+static gboolean
+stream_truncate (GSeekable *seekable,
+ goffset offset,
+ GCancellable *cancellable,
+ GError **error)
+{
+ CamelStream *stream;
+ GIOStream *base_stream;
+ gboolean success = FALSE;
+
+ stream = CAMEL_STREAM (seekable);
+ base_stream = camel_stream_ref_base_stream (stream);
+
+ if (G_IS_SEEKABLE (base_stream)) {
+ success = g_seekable_truncate (
+ G_SEEKABLE (base_stream),
+ offset, cancellable, error);
+ } else if (base_stream != NULL) {
+ g_set_error (
+ error, G_IO_ERROR,
+ G_IO_ERROR_NOT_SUPPORTED,
+ _("Stream type '%s' is not seekable"),
+ G_OBJECT_TYPE_NAME (base_stream));
+ } else {
+ g_warn_if_reached ();
+ }
+
+ g_clear_object (&base_stream);
+
+ return success;
+}
+
static void
camel_stream_class_init (CamelStreamClass *class)
{
@@ -243,6 +374,16 @@ camel_stream_class_init (CamelStreamClass *class)
}
static void
+camel_stream_seekable_init (GSeekableIface *interface)
+{
+ interface->tell = stream_tell;
+ interface->can_seek = stream_can_seek;
+ interface->seek = stream_seek;
+ interface->can_truncate = stream_can_truncate;
+ interface->truncate_fn = stream_truncate;
+}
+
+static void
camel_stream_init (CamelStream *stream)
{
stream->priv = CAMEL_STREAM_GET_PRIVATE (stream);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]