gvfs r1107 - in trunk: . daemon
- From: danw svn gnome org
- To: svn-commits-list gnome org
- Subject: gvfs r1107 - in trunk: . daemon
- Date: Sat, 12 Jan 2008 02:36:58 +0000 (GMT)
Author: danw
Date: Sat Jan 12 02:36:58 2008
New Revision: 1107
URL: http://svn.gnome.org/viewvc/gvfs?rev=1107&view=rev
Log:
* daemon/soup-input-stream.c: implement GSeekable (a bit hackishly
due to a bug in libsoup 2.2.x)
* daemon/gvfsbackendhttp.c (try_seek_on_read): implement
Modified:
trunk/ChangeLog
trunk/daemon/gvfsbackendhttp.c
trunk/daemon/soup-input-stream.c
Modified: trunk/daemon/gvfsbackendhttp.c
==============================================================================
--- trunk/daemon/gvfsbackendhttp.c (original)
+++ trunk/daemon/gvfsbackendhttp.c Sat Jan 12 02:36:58 2008
@@ -272,6 +272,39 @@
return TRUE;
}
+static gboolean
+try_seek_on_read (GVfsBackend *backend,
+ GVfsJobSeekRead *job,
+ GVfsBackendHandle handle,
+ goffset offset,
+ GSeekType type)
+{
+ GVfsBackendHttp *op_backend;
+ GInputStream *stream;
+ GError *error = NULL;
+
+ op_backend = G_VFS_BACKEND_HTTP (backend);
+ stream = G_INPUT_STREAM (handle);
+
+ if (!g_seekable_seek (G_SEEKABLE (stream), offset, type,
+ G_VFS_JOB (job)->cancellable, &error))
+ {
+ g_vfs_job_failed (G_VFS_JOB (job),
+ error->domain,
+ error->code,
+ error->message);
+ g_error_free (error);
+ return FALSE;
+ }
+ else
+ {
+ g_vfs_job_seek_read_set_offset (job, g_seekable_tell (G_SEEKABLE (stream)));
+ g_vfs_job_succeeded (G_VFS_JOB (job));
+ }
+
+ return TRUE;
+}
+
/* *** read_close () *** */
static void
close_read_ready (GObject *source_object,
@@ -350,6 +383,7 @@
backend_class->try_mount = try_mount;
backend_class->try_open_for_read = try_open_for_read;
backend_class->try_read = try_read;
+ backend_class->try_seek_on_read = try_seek_on_read;
backend_class->try_close_read = try_close_read;
backend_class->try_query_info = try_query_info;
Modified: trunk/daemon/soup-input-stream.c
==============================================================================
--- trunk/daemon/soup-input-stream.c (original)
+++ trunk/daemon/soup-input-stream.c Sat Jan 12 02:36:58 2008
@@ -29,7 +29,11 @@
#include "soup-input-stream.h"
-G_DEFINE_TYPE (SoupInputStream, soup_input_stream, G_TYPE_INPUT_STREAM);
+static void soup_input_stream_seekable_iface_init (GSeekableIface *seekable_iface);
+
+G_DEFINE_TYPE_WITH_CODE (SoupInputStream, soup_input_stream, G_TYPE_INPUT_STREAM,
+ G_IMPLEMENT_INTERFACE (G_TYPE_SEEKABLE,
+ soup_input_stream_seekable_iface_init));
typedef void (*SoupInputStreamCallback) (GInputStream *);
@@ -38,6 +42,7 @@
GMainContext *async_context;
SoupMessage *msg;
gboolean got_headers;
+ goffset offset;
GCancellable *cancellable;
GSource *cancel_watch;
@@ -85,6 +90,21 @@
GAsyncResult *result,
GError **error);
+static goffset soup_input_stream_tell (GSeekable *seekable);
+
+static gboolean soup_input_stream_can_seek (GSeekable *seekable);
+static gboolean soup_input_stream_seek (GSeekable *seekable,
+ goffset offset,
+ GSeekType type,
+ GCancellable *cancellable,
+ GError **error);
+
+static gboolean soup_input_stream_can_truncate (GSeekable *seekable);
+static gboolean soup_input_stream_truncate (GSeekable *seekable,
+ goffset offset,
+ GCancellable *cancellable,
+ GError **error);
+
static void soup_input_stream_got_headers (SoupMessage *msg, gpointer stream);
static void soup_input_stream_got_chunk (SoupMessage *msg, gpointer stream);
static void soup_input_stream_finished (SoupMessage *msg, gpointer stream);
@@ -128,6 +148,16 @@
}
static void
+soup_input_stream_seekable_iface_init (GSeekableIface *seekable_iface)
+{
+ seekable_iface->tell = soup_input_stream_tell;
+ seekable_iface->can_seek = soup_input_stream_can_seek;
+ seekable_iface->seek = soup_input_stream_seek;
+ seekable_iface->can_truncate = soup_input_stream_can_truncate;
+ seekable_iface->truncate_fn = soup_input_stream_truncate;
+}
+
+static void
soup_input_stream_init (SoupInputStream *stream)
{
;
@@ -237,6 +267,7 @@
memcpy (priv->caller_buffer + priv->caller_nread, chunk, nread);
priv->caller_nread += nread;
+ priv->offset += nread;
chunk += nread;
chunk_size -= nread;
}
@@ -369,6 +400,8 @@
memcpy (buffer, priv->leftover_buffer + priv->leftover_offset, nread);
priv->leftover_offset += nread;
}
+
+ priv->offset += nread;
return nread;
}
@@ -768,6 +801,93 @@
return TRUE;
}
+static goffset
+soup_input_stream_tell (GSeekable *seekable)
+{
+ SoupInputStreamPrivate *priv = SOUP_INPUT_STREAM_GET_PRIVATE (seekable);
+
+ return priv->offset;
+}
+
+static gboolean
+soup_input_stream_can_seek (GSeekable *seekable)
+{
+ return TRUE;
+}
+
+extern void soup_message_io_cleanup (SoupMessage *msg);
+
+static gboolean
+soup_input_stream_seek (GSeekable *seekable,
+ goffset offset,
+ GSeekType type,
+ GCancellable *cancellable,
+ GError **error)
+{
+ GInputStream *stream = G_INPUT_STREAM (seekable);
+ SoupInputStreamPrivate *priv = SOUP_INPUT_STREAM_GET_PRIVATE (seekable);
+ char *range;
+
+ if (!g_input_stream_set_pending (stream, error))
+ return FALSE;
+
+ if (priv->msg->status != SOUP_MESSAGE_STATUS_FINISHED)
+ soup_session_cancel_message (priv->session, priv->msg);
+
+ switch (type)
+ {
+ case G_SEEK_CUR:
+ offset += priv->offset;
+ /* fall through */
+
+ case G_SEEK_SET:
+ range = g_strdup_printf ("bytes=%"G_GUINT64_FORMAT"-", (guint64)offset);
+ priv->offset = offset;
+ break;
+
+ case G_SEEK_END:
+ /* FIXME: we could send "bytes=-offset", but unless we know the
+ * Content-Length, we wouldn't be able to answer a tell() properly.
+ * We could find the Content-Length by doing a HEAD...
+ */
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
+ "G_SEEK_END not currently supported");
+ break;
+
+ default:
+ g_return_val_if_reached (FALSE);
+ }
+
+ soup_message_remove_header (priv->msg->request_headers, "Range");
+ soup_message_add_header (priv->msg->request_headers, "Range", range);
+ g_free (range);
+
+ soup_session_cancel_message (priv->session, priv->msg);
+ soup_message_io_cleanup (priv->msg);
+ g_object_ref (priv->msg);
+ soup_session_queue_message (priv->session, priv->msg, NULL, NULL);
+
+ g_input_stream_clear_pending (stream);
+ return TRUE;
+}
+
+static gboolean
+soup_input_stream_can_truncate (GSeekable *seekable)
+{
+ return FALSE;
+}
+
+static gboolean
+soup_input_stream_truncate (GSeekable *seekable,
+ goffset offset,
+ GCancellable *cancellable,
+ GError **error)
+{
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
+ "Truncate not allowed on input stream");
+ return FALSE;
+}
+
GQuark
soup_http_error_quark (void)
{
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]