[gvfs] afp: move retrieval of volumes into GVfsAfpServer



commit 88866fdc3c34e8b9ce2d4435098885e67212ac40
Author: Carl-Anton Ingmarsson <ca ingmarsson gmail com>
Date:   Mon Sep 26 21:01:09 2011 +0200

    afp: move retrieval of volumes into GVfsAfpServer
    
    GVfsAfpServer now has a g_vfs_afp_server_get_volumes to retrieve the available
    volumes asynchronously.

 daemon/gvfsafpserver.c        |  140 ++++++++++++++++++++++++++++++++++++++++-
 daemon/gvfsafpserver.h        |   15 +++++
 daemon/gvfsbackendafpbrowse.c |  104 +++++++-----------------------
 3 files changed, 178 insertions(+), 81 deletions(-)
---
diff --git a/daemon/gvfsafpserver.c b/daemon/gvfsafpserver.c
index 613e210..5845664 100644
--- a/daemon/gvfsafpserver.c
+++ b/daemon/gvfsafpserver.c
@@ -1141,12 +1141,11 @@ done:
  * @volume_id: id of the volume whose parameters should be received.
  * @vol_bitmap: bitmap describing the parameters that should be received.
  * @cancellable: optional #GCancellable object, %NULL to ignore.
- * @error: a #GError, %NULL to ignore.
  * @callback: callback to call when the request is satisfied.
  * @user_data: the data to pass to callback function.
  * 
  * Asynchronously retrives the parameters specified by @vol_bitmap of the volume
- * with id $volume_id.
+ * with id @volume_id.
  */
 void
 g_vfs_afp_server_get_vol_parms (GVfsAfpServer       *server,
@@ -1208,3 +1207,140 @@ g_vfs_afp_server_get_vol_parms_finish (GVfsAfpServer  *server,
 
   return g_object_ref (g_simple_async_result_get_op_res_gpointer (simple));
 }
+
+static void
+volume_data_free (GVfsAfpVolumeData *vol_data)
+{
+  g_free (vol_data->name);
+  g_slice_free (GVfsAfpVolumeData, vol_data);
+}
+
+
+static void
+get_volumes_cb (GObject *source_object, GAsyncResult *res, gpointer user_data)
+{
+  GVfsAfpConnection *afp_conn = G_VFS_AFP_CONNECTION (source_object);
+  GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (user_data);
+
+  GVfsAfpReply *reply;
+  GError *err = NULL;
+  AfpResultCode res_code;
+  
+  guint8 num_volumes, i;
+  GPtrArray *volumes;
+  
+  reply = g_vfs_afp_connection_send_command_finish (afp_conn, res, &err);
+  if (!reply)
+  {
+    g_simple_async_result_take_error (simple, err);
+    goto done;
+  }
+
+  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_take_error (simple, afp_result_code_to_gerror (res_code));
+    goto done;
+  }
+  
+  /* server time */
+  g_vfs_afp_reply_read_int32 (reply, NULL);
+
+  /* NumVolStructures */
+  g_vfs_afp_reply_read_byte (reply, &num_volumes);
+  
+  volumes = g_ptr_array_sized_new (num_volumes);
+  g_ptr_array_set_free_func (volumes, (GDestroyNotify)volume_data_free);
+  for (i = 0; i < num_volumes; i++)
+  {
+    guint8 flags;
+    char *vol_name;
+
+    GVfsAfpVolumeData *volume_data;
+
+    g_vfs_afp_reply_read_byte (reply, &flags);
+    g_vfs_afp_reply_read_pascal (reply, &vol_name);
+    if (!vol_name)
+      continue;
+
+    volume_data = g_slice_new (GVfsAfpVolumeData);
+    volume_data->flags = flags;
+    volume_data->name = vol_name;
+
+    g_ptr_array_add (volumes, volume_data);
+  }
+  g_object_unref (reply);
+
+  g_simple_async_result_set_op_res_gpointer (simple, volumes,
+                                             (GDestroyNotify)g_ptr_array_unref);
+done:
+  g_simple_async_result_complete (simple);
+  g_object_unref (simple);
+}
+
+/*
+ * g_vfs_afp_server_get_volumes:
+ * 
+ * @server: a #GVfsAfpServer
+ * @cancellable: optional #GCancellable object, %NULL to ignore.
+ * @callback: callback to call when the request is satisfied.
+ * @user_data: the data to pass to callback function.
+ * 
+ * Asynchronously retrieves the volumes available on @server.
+ */
+void
+g_vfs_afp_server_get_volumes (GVfsAfpServer       *server,
+                              GCancellable        *cancellable,
+                              GAsyncReadyCallback  callback,
+                              gpointer             user_data)
+{
+  GVfsAfpCommand *comm;
+  GSimpleAsyncResult *simple;
+  
+  /* Get Server Parameters */
+  comm = g_vfs_afp_command_new (AFP_COMMAND_GET_SRVR_PARMS);
+  /* pad byte */
+  g_vfs_afp_command_put_byte (comm, 0);
+
+  simple = g_simple_async_result_new (G_OBJECT (server), callback, user_data,
+                                      g_vfs_afp_server_get_volumes);
+  
+  g_vfs_afp_connection_send_command (server->conn, comm, NULL, get_volumes_cb,
+                                     cancellable, simple);
+}
+
+/*
+ * g_vfs_afp_server_get_vol_parms_finish:
+ * 
+ * @server: a #GVfsAfpServer.
+ * @result: a #GAsyncResult.
+ * @error: a #GError, %NULL to ignore.
+ * 
+ * Finalizes the asynchronous operation started by
+ * g_vfs_afp_server_get_volumes.
+ * 
+ * Returns: A #GPtrArray containing the volumes #GVfsAfpVolumeData structures or
+ * %NULL on error.
+ *                      
+ */
+GPtrArray *
+g_vfs_afp_server_get_volumes_finish (GVfsAfpServer  *server,
+                                     GAsyncResult   *result,
+                                     GError         **error)
+{
+  GSimpleAsyncResult *simple;
+  
+  g_return_val_if_fail (g_simple_async_result_is_valid (result,
+                                                        G_OBJECT (server),
+                                                        g_vfs_afp_server_get_volumes),
+                        NULL);
+
+  simple = (GSimpleAsyncResult *)result;
+
+  if (g_simple_async_result_propagate_error (simple, error))
+    return NULL;
+
+  return g_ptr_array_ref ((GPtrArray *)g_simple_async_result_get_op_res_gpointer (simple));
+}
\ No newline at end of file
diff --git a/daemon/gvfsafpserver.h b/daemon/gvfsafpserver.h
index fc642be..0688ff1 100644
--- a/daemon/gvfsafpserver.h
+++ b/daemon/gvfsafpserver.h
@@ -95,6 +95,21 @@ GFileInfo *        g_vfs_afp_server_get_vol_parms_finish (GVfsAfpServer       *s
                                                           GAsyncResult        *result,
                                                           GError             **error);
 
+typedef struct _GVfsAfpVolumeData GVfsAfpVolumeData;
+struct _GVfsAfpVolumeData
+{
+  char *name;
+  guint16 flags;
+};
+
+void               g_vfs_afp_server_get_volumes          (GVfsAfpServer       *server,
+                                                          GCancellable        *cancellable,
+                                                          GAsyncReadyCallback  callback,
+                                                          gpointer             user_data);
+GPtrArray *        g_vfs_afp_server_get_volumes_finish   (GVfsAfpServer  *server,
+                                                          GAsyncResult   *result,
+                                                          GError         **error);
+
 G_END_DECLS
 
 #endif /* _GVFSAFPSERVER_H_ */
diff --git a/daemon/gvfsbackendafpbrowse.c b/daemon/gvfsbackendafpbrowse.c
index 5226ce8..1b5f1fc 100644
--- a/daemon/gvfsbackendafpbrowse.c
+++ b/daemon/gvfsbackendafpbrowse.c
@@ -58,26 +58,13 @@ struct _GVfsBackendAfpBrowse
   GVfsAfpServer      *server;
 
   char               *logged_in_user;
-  GSList             *volumes;
+  GPtrArray          *volumes;
 };
 
 
 G_DEFINE_TYPE (GVfsBackendAfpBrowse, g_vfs_backend_afp_browse, G_VFS_TYPE_BACKEND);
 
 
-typedef struct
-{
-  char *name;
-  guint16 flags;
-} VolumeData;
-
-static void
-volume_data_free (VolumeData *vol_data)
-{
-  g_free (vol_data->name);
-  g_slice_free (VolumeData, vol_data);
-}
-
 static gboolean
 is_root (const char *filename)
 {
@@ -91,62 +78,27 @@ is_root (const char *filename)
 }
 
 static void
-get_srvr_parms_cb (GObject *source_object, GAsyncResult *res, gpointer user_data)
+get_volumes_cb (GObject *source_object, GAsyncResult *res, gpointer user_data)
 {
-  GVfsAfpConnection *afp_conn = G_VFS_AFP_CONNECTION (source_object);
-  GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (user_data);
+  GVfsAfpServer *server = G_VFS_AFP_SERVER (source_object);
+  GSimpleAsyncResult *simple = user_data;
 
   GVfsBackendAfpBrowse *afp_backend;
-  GVfsAfpReply *reply;
+  GPtrArray *volumes;
   GError *err = NULL;
-  AfpResultCode res_code;
   
-  guint8 num_volumes, i;
-
   afp_backend = G_VFS_BACKEND_AFP_BROWSE (g_async_result_get_source_object (G_ASYNC_RESULT (simple)));
   
-  reply = g_vfs_afp_connection_send_command_finish (afp_conn, res, &err);
-  if (!reply)
+  volumes = g_vfs_afp_server_get_volumes_finish (server, res, &err);
+  if (!volumes)
   {
     g_simple_async_result_take_error (simple, err);
     goto done;
   }
 
-  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_take_error (simple, afp_result_code_to_gerror (res_code));
-    goto done;
-  }
-  
-  /* server time */
-  g_vfs_afp_reply_read_int32 (reply, NULL);
-
-  g_slist_free_full (afp_backend->volumes, (GDestroyNotify) volume_data_free);
-  afp_backend->volumes = NULL;
-
-  g_vfs_afp_reply_read_byte (reply, &num_volumes);
-  for (i = 0; i < num_volumes; i++)
-  {
-    guint8 flags;
-    char *vol_name;
-
-    VolumeData *volume_data;
-
-    g_vfs_afp_reply_read_byte (reply, &flags);
-    g_vfs_afp_reply_read_pascal (reply, &vol_name);
-    if (!vol_name)
-      continue;
-
-    volume_data = g_slice_new (VolumeData);
-    volume_data->flags = flags;
-    volume_data->name = vol_name;
-
-    afp_backend->volumes = g_slist_prepend (afp_backend->volumes, volume_data);
-  }
-  g_object_unref (reply);
+  if (afp_backend->volumes)
+    g_ptr_array_unref (afp_backend->volumes);
+  afp_backend->volumes = volumes;
 
 done:
   g_simple_async_result_complete (simple);
@@ -159,20 +111,13 @@ update_cache (GVfsBackendAfpBrowse *afp_backend,
               GAsyncReadyCallback callback,
               gpointer user_data)
 {
-  GVfsAfpCommand *comm;
   GSimpleAsyncResult *simple;
   
-  comm = g_vfs_afp_command_new (AFP_COMMAND_GET_SRVR_PARMS);
-  /* pad byte */
-  g_vfs_afp_command_put_byte (comm, 0);
-
   simple = g_simple_async_result_new (G_OBJECT (afp_backend), callback,
                                       user_data, update_cache);
-  
-  g_vfs_afp_connection_send_command (afp_backend->server->conn, comm, NULL,
-                                     get_srvr_parms_cb,
-                                     cancellable, simple);
-  g_object_unref (comm); 
+
+  g_vfs_afp_server_get_volumes (afp_backend->server, cancellable, get_volumes_cb,
+                                simple); 
 }
 
 static gboolean
@@ -194,13 +139,13 @@ update_cache_finish (GVfsBackendAfpBrowse *afp_backend,
   return TRUE;
 }
 
-static VolumeData *
+static GVfsAfpVolumeData *
 find_volume (GVfsBackendAfpBrowse *afp_backend,
              char *filename)
 {
   char *end;
   guint len;
-  GSList *l;
+  guint i;
 
   while (*filename == '/')
     filename++;
@@ -219,9 +164,9 @@ find_volume (GVfsBackendAfpBrowse *afp_backend,
   else
     len = strlen (filename);
 
-  for (l = afp_backend->volumes; l; l = g_slist_next (l))
+  for (i = 0; i < afp_backend->volumes->len; i++)
   {
-    VolumeData *vol_data = (VolumeData *)l->data;
+    GVfsAfpVolumeData *vol_data = g_ptr_array_index (afp_backend->volumes, i);
 
     if (strlen (vol_data->name) == len && strncmp (vol_data->name, filename, len) == 0)
       return vol_data;
@@ -239,7 +184,7 @@ mount_mountable_cb (GObject      *source_object,
   GVfsJobMountMountable *job = G_VFS_JOB_MOUNT_MOUNTABLE (user_data);
 
   GError *err;
-  VolumeData *vol_data;
+  GVfsAfpVolumeData *vol_data;
   GMountSpec *mount_spec;
 
   if (!update_cache_finish (afp_backend, res, &err))
@@ -292,7 +237,7 @@ try_mount_mountable (GVfsBackend *backend,
 }
 
 static void
-fill_info (GFileInfo *info, VolumeData *vol_data, GVfsBackendAfpBrowse *afp_backend)
+fill_info (GFileInfo *info, GVfsAfpVolumeData *vol_data, GVfsBackendAfpBrowse *afp_backend)
 {
   GIcon *icon;
   GMountSpec *mount_spec;
@@ -346,7 +291,7 @@ enumerate_cache_updated_cb (GObject      *source_object,
   GVfsJobEnumerate *job = G_VFS_JOB_ENUMERATE (user_data);
 
   GError *err = NULL;
-  GSList *l;
+  guint i;
 
   if (!update_cache_finish (afp_backend, res, &err))
   {
@@ -357,9 +302,9 @@ enumerate_cache_updated_cb (GObject      *source_object,
 
   g_vfs_job_succeeded (G_VFS_JOB (job));
   
-  for (l = afp_backend->volumes; l; l = l->next)
+  for (i = 0; i < afp_backend->volumes->len; i++)
   {
-    VolumeData *vol_data = l->data;
+    GVfsAfpVolumeData *vol_data = g_ptr_array_index (afp_backend->volumes, i);
     
     GFileInfo *info;
 
@@ -405,7 +350,7 @@ query_info_cb (GObject      *source_object,
   GVfsJobQueryInfo *job = G_VFS_JOB_QUERY_INFO (user_data);
 
   GError *err = NULL;
-  VolumeData *vol_data;
+  GVfsAfpVolumeData *vol_data;
 
   if (!update_cache_finish (afp_backend, res, &err))
   {
@@ -577,7 +522,8 @@ g_vfs_backend_afp_browse_finalize (GObject *object)
   g_free (afp_backend->user);
 
   g_free (afp_backend->logged_in_user);
-  g_slist_free_full (afp_backend->volumes, (GDestroyNotify)volume_data_free);
+  if (afp_backend->volumes)
+    g_ptr_array_unref (afp_backend->volumes);
 
   G_OBJECT_CLASS (g_vfs_backend_afp_browse_parent_class)->finalize (object);
 }



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]