[gvfs] afp: add a read_all_async function
- From: Christian Kellner <gicmo src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gvfs] afp: add a read_all_async function
- Date: Thu, 25 Aug 2011 19:29:16 +0000 (UTC)
commit 6fb8847eded26016eedd94f55608d56ab7796365
Author: Carl-Anton Ingmarsson <ca ingmarsson gmail com>
Date: Tue Aug 9 16:40:55 2011 +0200
afp: add a read_all_async function
daemon/gvfsafpconnection.c | 152 ++++++++++++++++++++++++++++++++++---------
1 files changed, 120 insertions(+), 32 deletions(-)
---
diff --git a/daemon/gvfsafpconnection.c b/daemon/gvfsafpconnection.c
index 12100ed..e7ad468 100644
--- a/daemon/gvfsafpconnection.c
+++ b/daemon/gvfsafpconnection.c
@@ -640,6 +640,113 @@ run_loop (GVfsAfpConnection *afp_connection)
}
}
+typedef struct
+{
+ void *buffer;
+ gsize count;
+ int io_priority;
+ GCancellable *cancellable;
+ gsize bytes_read;
+} ReadAllData;
+
+static void
+free_read_all_data (ReadAllData *read_data)
+{
+ if (read_data->cancellable)
+ g_object_unref (read_data->cancellable);
+
+ g_slice_free (ReadAllData, read_data);
+}
+
+static void
+read_all_cb (GObject *source_object, GAsyncResult *res, gpointer user_data)
+{
+ GInputStream *stream = G_INPUT_STREAM (source_object);
+ GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (user_data);
+
+ gsize bytes_read;
+ GError *err = NULL;
+ ReadAllData *read_data;
+
+ bytes_read = g_input_stream_read_finish (stream, res, &err);
+ if (bytes_read == -1)
+ {
+ g_simple_async_result_take_error (simple, err);
+ g_simple_async_result_complete (simple);
+ return;
+ }
+
+ read_data = g_simple_async_result_get_op_res_gpointer (simple);
+
+ read_data->bytes_read += bytes_read;
+ if (read_data->bytes_read < read_data->count)
+ {
+ g_input_stream_read_async (stream,
+ (guint8 *)read_data->buffer + read_data->bytes_read,
+ read_data->count - read_data->bytes_read, 0,
+ read_data->cancellable, read_all_cb, simple);
+ return;
+ }
+
+ g_simple_async_result_complete (simple);
+}
+
+static void
+read_all_async (GInputStream *stream,
+ void *buffer,
+ gsize count,
+ int io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ ReadAllData *read_data;
+ GSimpleAsyncResult *simple;
+
+ read_data = g_slice_new0 (ReadAllData);
+ read_data->buffer = buffer;
+ read_data->count = count;
+ read_data->io_priority = io_priority;
+ if (cancellable)
+ read_data->cancellable = g_object_ref (cancellable);
+
+ simple = g_simple_async_result_new (G_OBJECT (stream), callback, user_data,
+ read_all_async);
+ g_simple_async_result_set_op_res_gpointer (simple, read_data,
+ (GDestroyNotify)free_read_all_data);
+
+ g_input_stream_read_async (stream, buffer, count, io_priority, cancellable,
+ read_all_cb, simple);
+}
+
+static gboolean
+read_all_finish (GInputStream *stream,
+ GAsyncResult *res,
+ gsize *bytes_read,
+ GError **error)
+{
+ GSimpleAsyncResult *simple;
+
+ g_return_val_if_fail (g_simple_async_result_is_valid (res, G_OBJECT (stream),
+ read_all_async),
+ FALSE);
+
+ simple = (GSimpleAsyncResult *)res;
+
+ if (g_simple_async_result_propagate_error (simple, error))
+ return FALSE;
+
+ if (bytes_read)
+ {
+ ReadAllData *read_data;
+
+ read_data = g_simple_async_result_get_op_res_gpointer (simple);
+ *bytes_read = read_data->bytes_read;
+ }
+
+ return TRUE;
+}
+
static void
dispatch_reply (GVfsAfpConnection *afp_connection)
{
@@ -715,27 +822,17 @@ read_data_cb (GObject *object, GAsyncResult *res, gpointer user_data)
{
GInputStream *input = G_INPUT_STREAM (object);
GVfsAfpConnection *afp_connection = G_VFS_AFP_CONNECTION (user_data);
- GVfsAfpConnectionPrivate *priv = afp_connection->priv;
-
- gssize bytes_read;
+
+ gboolean result;
GError *err = NULL;
-
- bytes_read = g_input_stream_read_finish (input, res, &err);
- if (bytes_read == -1)
+
+ result = read_all_finish (input, res, NULL, &err);
+ if (!result)
{
g_warning ("FAIL!!! \"%s\"\n", err->message);
g_error_free (err);
}
- priv->bytes_read += bytes_read;
- if (priv->bytes_read < priv->read_dsi_header.totalDataLength)
- {
- g_input_stream_read_async (input, priv->data + priv->bytes_read,
- priv->read_dsi_header.totalDataLength - priv->bytes_read,
- 0, NULL, read_data_cb, afp_connection);
- return;
- }
-
dispatch_reply (afp_connection);
read_reply (afp_connection);
}
@@ -747,25 +844,16 @@ read_dsi_header_cb (GObject *object, GAsyncResult *res, gpointer user_data)
GVfsAfpConnection *afp_connection = G_VFS_AFP_CONNECTION (user_data);
GVfsAfpConnectionPrivate *priv = afp_connection->priv;
- gssize bytes_read;
+ gboolean result;
GError *err = NULL;
- bytes_read = g_input_stream_read_finish (input, res, &err);
- if (bytes_read == -1)
+ result = read_all_finish (input, res, NULL, &err);
+ if (!result)
{
g_warning ("FAIL!!! \"%s\"\n", err->message);
g_error_free (err);
}
- priv->bytes_read += bytes_read;
- if (priv->bytes_read < sizeof (DSIHeader))
- {
- g_input_stream_read_async (input, &priv->read_dsi_header + priv->bytes_read,
- sizeof (DSIHeader) - priv->bytes_read, 0, NULL,
- read_dsi_header_cb, afp_connection);
- return;
- }
-
priv->read_dsi_header.requestID = GUINT16_FROM_BE (priv->read_dsi_header.requestID);
priv->read_dsi_header.errorCode = GUINT32_FROM_BE (priv->read_dsi_header.errorCode);
priv->read_dsi_header.totalDataLength = GUINT32_FROM_BE (priv->read_dsi_header.totalDataLength);
@@ -773,9 +861,8 @@ read_dsi_header_cb (GObject *object, GAsyncResult *res, gpointer user_data)
if (priv->read_dsi_header.totalDataLength > 0)
{
priv->data = g_malloc (priv->read_dsi_header.totalDataLength);
- priv->bytes_read = 0;
- g_input_stream_read_async (input, priv->data, priv->read_dsi_header.totalDataLength,
- 0, NULL, read_data_cb, afp_connection);
+ read_all_async (input, priv->data, priv->read_dsi_header.totalDataLength,
+ 0, NULL, read_data_cb, afp_connection);
return;
}
@@ -794,8 +881,9 @@ read_reply (GVfsAfpConnection *afp_connection)
priv->bytes_read = 0;
priv->data = NULL;
- g_input_stream_read_async (input, &priv->read_dsi_header, sizeof (DSIHeader), 0, NULL,
- read_dsi_header_cb, afp_connection);
+
+ read_all_async (input, &priv->read_dsi_header, sizeof (DSIHeader), 0, NULL,
+ read_dsi_header_cb, afp_connection);
}
typedef struct
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]