[gvfs] afp: implement seek_on_write
- From: Christian Kellner <gicmo src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gvfs] afp: implement seek_on_write
- Date: Thu, 25 Aug 2011 19:25:24 +0000 (UTC)
commit 2fa9e6ad08a4a9b90b91af8ca79c6503d8180713
Author: Carl-Anton Ingmarsson <ca ingmarsson gmail com>
Date: Wed Jul 13 23:27:47 2011 +0200
afp: implement seek_on_write
also split out getting fork parameters into a new function get_fork_parms
daemon/gvfsbackendafp.c | 201 +++++++++++++++++++++++++++++++++++++----------
1 files changed, 160 insertions(+), 41 deletions(-)
---
diff --git a/daemon/gvfsbackendafp.c b/daemon/gvfsbackendafp.c
index be832ed..95abb39 100644
--- a/daemon/gvfsbackendafp.c
+++ b/daemon/gvfsbackendafp.c
@@ -38,6 +38,7 @@
#include "gvfsjobcloseread.h"
#include "gvfsjobread.h"
#include "gvfsjobseekread.h"
+#include "gvfsjobseekwrite.h"
#include "gvfsjobopenforwrite.h"
#include "gvfsjobwrite.h"
#include "gvfsjobclosewrite.h"
@@ -457,7 +458,96 @@ close_fork (GVfsBackendAfp *afp_backend,
job);
g_object_unref (comm);
}
-
+
+static void
+get_fork_parms_cb (GVfsAfpConnection *afp_connection,
+ GVfsAfpReply *reply,
+ GError *error,
+ gpointer user_data)
+{
+ GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (user_data);
+ GVfsBackendAfp *afp_backend = G_VFS_BACKEND_AFP (g_async_result_get_source_object (G_ASYNC_RESULT (simple)));
+
+ AfpResultCode res_code;
+ guint16 file_bitmap;
+ GFileInfo *info;
+
+ if (!reply)
+ {
+ g_simple_async_result_set_from_error (simple, error);
+ g_simple_async_result_complete (simple);
+ return;
+ }
+
+ res_code = g_vfs_afp_reply_get_result_code (reply);
+ if (res_code != AFP_RESULT_NO_ERROR)
+ {
+ g_object_unref (reply);
+
+ g_simple_async_result_set_error (simple, G_IO_ERROR, G_IO_ERROR_FAILED,
+ _("Got error code: %d from server"), res_code);
+ g_simple_async_result_complete (simple);
+ return;
+ }
+
+ g_vfs_afp_reply_read_uint16 (reply, &file_bitmap);
+
+ info = g_file_info_new ();
+ fill_info (afp_backend, info, reply, FALSE, file_bitmap);
+
+ g_simple_async_result_set_op_res_gpointer (simple, info, g_object_unref);
+ g_simple_async_result_complete (simple);
+}
+
+static void
+get_fork_parms (GVfsBackendAfp *afp_backend,
+ gint16 fork_refnum,
+ guint16 file_bitmap,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GVfsAfpCommand *comm;
+ GSimpleAsyncResult *simple;
+
+ comm = g_vfs_afp_command_new (AFP_COMMAND_GET_FORK_PARMS);
+ /* pad byte */
+ g_vfs_afp_command_put_byte (comm, 0);
+ /* OForkRefNum */
+ g_vfs_afp_command_put_int16 (comm, fork_refnum);
+ /* Bitmap */
+ g_vfs_afp_command_put_uint16 (comm, file_bitmap);
+
+ simple = g_simple_async_result_new (G_OBJECT (afp_backend), callback, user_data,
+ get_fork_parms);
+
+
+ g_vfs_afp_connection_queue_command (afp_backend->server->conn, comm,
+ get_fork_parms_cb, cancellable,
+ simple);
+ g_object_unref (comm);
+}
+
+static GFileInfo *
+get_fork_parms_finish (GVfsBackendAfp *afp_backend,
+ GAsyncResult *result,
+ GError **error)
+{
+ GSimpleAsyncResult *simple;
+
+ g_return_val_if_fail (g_simple_async_result_is_valid (result,
+ G_OBJECT (afp_backend),
+ get_fork_parms),
+ NULL);
+
+ simple = (GSimpleAsyncResult *)result;
+
+ if (g_simple_async_result_propagate_error (simple, error))
+ return NULL;
+
+ return g_object_ref (g_simple_async_result_get_op_res_gpointer (simple));
+}
+
typedef void (*CreateFileCallback) (GVfsJob *job);
static void
@@ -912,41 +1002,85 @@ try_write (GVfsBackend *backend,
}
static void
-seek_on_read_cb (GVfsAfpConnection *afp_connection,
- GVfsAfpReply *reply,
- GError *error,
- gpointer user_data)
+seek_on_write_cb (GObject *source_object, GAsyncResult *res, gpointer user_data)
{
- GVfsJobSeekRead *job = G_VFS_JOB_SEEK_READ (user_data);
- GVfsBackendAfp *afp_backend = G_VFS_BACKEND_AFP (job->backend);
+ GVfsBackendAfp *afp_backend = G_VFS_BACKEND_AFP (source_object);
+ GVfsJobSeekWrite *job = G_VFS_JOB_SEEK_WRITE (user_data);
AfpHandle *afp_handle = (AfpHandle *)job->handle;
- AfpResultCode res_code;
- guint16 file_bitmap;
+ GError *err = NULL;
GFileInfo *info;
gsize size;
-
- if (!reply)
+
+ info = get_fork_parms_finish (afp_backend, res, &err);
+ if (!info)
{
- g_vfs_job_failed_from_error (G_VFS_JOB (job), error);
+ g_vfs_job_failed_from_error (G_VFS_JOB (job), err);
+ g_error_free (err);
return;
}
+
+ size = g_file_info_get_size (info);
+ g_object_unref (info);
- res_code = g_vfs_afp_reply_get_result_code (reply);
- if (res_code != AFP_RESULT_NO_ERROR)
+ switch (job->seek_type)
{
- g_object_unref (reply);
-
- g_vfs_job_failed_literal (G_VFS_JOB (job), G_IO_ERROR,
- G_IO_ERROR_FAILED, _("Got error from server"));
- return;
+ case G_SEEK_CUR:
+ afp_handle->offset += job->requested_offset;
+ break;
+ case G_SEEK_SET:
+ afp_handle->offset = job->requested_offset;
+ break;
+ case G_SEEK_END:
+ afp_handle->offset = size + job->requested_offset;
+ break;
}
- g_vfs_afp_reply_read_uint16 (reply, &file_bitmap);
+ if (afp_handle->offset < 0)
+ afp_handle->offset = 0;
+ else if (afp_handle->offset > size)
+ afp_handle->offset = size;
- info = g_file_info_new ();
- fill_info (afp_backend, info, reply, FALSE, file_bitmap);
+ g_vfs_job_seek_write_set_offset (job, afp_handle->offset);
+ g_vfs_job_succeeded (G_VFS_JOB (job));
+}
+
+static gboolean
+try_seek_on_write (GVfsBackend *backend,
+ GVfsJobSeekRead *job,
+ GVfsBackendHandle handle,
+ goffset offset,
+ GSeekType type)
+{
+ GVfsBackendAfp *afp_backend = G_VFS_BACKEND_AFP (backend);
+ AfpHandle *afp_handle = (AfpHandle *)handle;
+
+ get_fork_parms (afp_backend, afp_handle->fork_refnum,
+ AFP_FILE_BITMAP_EXT_DATA_FORK_LEN_BIT,
+ G_VFS_JOB (job)->cancellable, seek_on_write_cb, job);
+ return TRUE;
+}
+
+static void
+seek_on_read_cb (GObject *source_object, GAsyncResult *res, gpointer user_data)
+{
+ GVfsBackendAfp *afp_backend = G_VFS_BACKEND_AFP (source_object);
+ GVfsJobSeekRead *job = G_VFS_JOB_SEEK_READ (user_data);
+ AfpHandle *afp_handle = (AfpHandle *)job->handle;
+
+ GError *err = NULL;
+ GFileInfo *info;
+ gsize size;
+
+ info = get_fork_parms_finish (afp_backend, res, &err);
+ if (!info)
+ {
+ g_vfs_job_failed_from_error (G_VFS_JOB (job), err);
+ g_error_free (err);
+ return;
+ }
+
size = g_file_info_get_size (info);
g_object_unref (info);
@@ -972,7 +1106,6 @@ seek_on_read_cb (GVfsAfpConnection *afp_connection,
g_vfs_job_succeeded (G_VFS_JOB (job));
}
-
static gboolean
try_seek_on_read (GVfsBackend *backend,
GVfsJobSeekRead *job,
@@ -983,25 +1116,10 @@ try_seek_on_read (GVfsBackend *backend,
GVfsBackendAfp *afp_backend = G_VFS_BACKEND_AFP (backend);
AfpHandle *afp_handle = (AfpHandle *)handle;
- GVfsAfpCommand *comm;
- guint16 file_bitmap;
-
- comm = g_vfs_afp_command_new (AFP_COMMAND_GET_FORK_PARMS);
- /* pad byte */
- g_vfs_afp_command_put_byte (comm, 0);
-
- /* OForkRefNum */
- g_vfs_afp_command_put_int16 (comm, afp_handle->fork_refnum);
-
- /* Bitmap */
- file_bitmap = AFP_FILE_BITMAP_EXT_DATA_FORK_LEN_BIT;
- g_vfs_afp_command_put_uint16 (comm, file_bitmap);
+ get_fork_parms (afp_backend, afp_handle->fork_refnum,
+ AFP_FILE_BITMAP_EXT_DATA_FORK_LEN_BIT,
+ G_VFS_JOB (job)->cancellable, seek_on_read_cb, job);
- g_vfs_afp_connection_queue_command (afp_backend->server->conn, comm,
- seek_on_read_cb, G_VFS_JOB (job)->cancellable,
- job);
- g_object_unref (comm);
-
return TRUE;
}
@@ -1963,6 +2081,7 @@ g_vfs_backend_afp_class_init (GVfsBackendAfpClass *klass)
backend_class->try_create = try_create;
backend_class->try_replace = try_replace;
backend_class->try_write = try_write;
+ backend_class->try_seek_on_write = try_seek_on_write;
backend_class->try_close_write = try_close_write;
backend_class->try_delete = try_delete;
backend_class->try_make_directory = try_make_directory;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]