[json-glib] parser: Port to GTask
- From: Emmanuele Bassi <ebassi src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [json-glib] parser: Port to GTask
- Date: Tue, 9 Jun 2015 11:59:52 +0000 (UTC)
commit 3ae9c9e82dc2423b8f6af23ae2b5d08d30f6b575
Author: Emmanuele Bassi <ebassi gnome org>
Date: Tue Jun 9 12:56:13 2015 +0100
parser: Port to GTask
GSimpleAsyncResult is deprecated in GLib 2.46, so we should drop its
use, and simplify the code in the process.
json-glib/json-parser.c | 180 ++++++++++++++++-------------------------------
1 files changed, 62 insertions(+), 118 deletions(-)
---
diff --git a/json-glib/json-parser.c b/json-glib/json-parser.c
index 08049ca..c46de5b 100644
--- a/json-glib/json-parser.c
+++ b/json-glib/json-parser.c
@@ -1249,94 +1249,22 @@ out:
return retval;
}
-typedef struct _LoadStreamData
-{
- JsonParser *parser;
- GError *error;
- GCancellable *cancellable;
- GAsyncReadyCallback callback;
- gpointer user_data;
+typedef struct {
+ GInputStream *stream;
GByteArray *content;
gsize pos;
-} LoadStreamData;
-
-static void
-load_stream_data_free (gpointer data)
-{
- LoadStreamData *closure;
-
- if (G_UNLIKELY (data == NULL))
- return;
-
- closure = data;
-
- if (closure->error)
- g_error_free (closure->error);
-
- if (closure->cancellable)
- g_object_unref (closure->cancellable);
-
- if (closure->content)
- g_byte_array_free (closure->content, TRUE);
-
- g_object_unref (closure->parser);
-
- g_free (closure);
-}
+} LoadData;
static void
-load_stream_data_read_callback (GObject *object,
- GAsyncResult *read_res,
- gpointer user_data)
+load_data_free (gpointer data_)
{
- GInputStream *stream = G_INPUT_STREAM (object);
- LoadStreamData *data = user_data;
- GError *error = NULL;
- gssize read_size;
-
- read_size = g_input_stream_read_finish (stream, read_res, &error);
- if (read_size < 0)
- {
- if (error != NULL)
- data->error = error;
- else
- {
- GSimpleAsyncResult *res;
-
- /* EOF */
- res = g_simple_async_result_new (G_OBJECT (data->parser),
- data->callback,
- data->user_data,
- json_parser_load_from_stream_async);
- g_simple_async_result_set_op_res_gpointer (res, data, load_stream_data_free);
- g_simple_async_result_complete (res);
- g_object_unref (res);
- }
- }
- else if (read_size > 0)
+ if (data_ != NULL)
{
- data->pos += read_size;
-
- g_byte_array_set_size (data->content, data->pos + GET_DATA_BLOCK_SIZE);
+ LoadData *data = data_;
- g_input_stream_read_async (stream, data->content->data + data->pos,
- GET_DATA_BLOCK_SIZE,
- 0,
- data->cancellable,
- load_stream_data_read_callback,
- data);
- }
- else
- {
- GSimpleAsyncResult *res;
-
- res = g_simple_async_result_new (G_OBJECT (data->parser),
- data->callback,
- data->user_data,
- json_parser_load_from_stream_async);
- g_simple_async_result_set_op_res_gpointer (res, data, load_stream_data_free);
- g_simple_async_result_complete (res);
- g_object_unref (res);
+ g_object_unref (data->stream);
+ g_byte_array_unref (data->content);
+ g_free (data);
}
}
@@ -1360,40 +1288,61 @@ json_parser_load_from_stream_finish (JsonParser *parser,
GAsyncResult *result,
GError **error)
{
- GSimpleAsyncResult *simple;
- GError *internal_error;
- LoadStreamData *data;
gboolean res;
g_return_val_if_fail (JSON_IS_PARSER (parser), FALSE);
- g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (result), FALSE);
+ g_return_val_if_fail (g_task_is_valid (result, parser), FALSE);
- simple = G_SIMPLE_ASYNC_RESULT (result);
+ res = g_task_propagate_boolean (G_TASK (result), error);
+ if (res)
+ {
+ LoadData *data = g_task_get_task_data (G_TASK (result));
+ GError *internal_error = NULL;
+
+ /* We need to do this inside the finis() function because JsonParser will emit
+ * signals, and we need to ensure that the signals are emitted in the right
+ * context; it's easier to do that if we just rely on the async callback being
+ * called in the right context, even if it means making the finish() function
+ * necessary to complete the async operation.
+ */
+ res = json_parser_load (parser, (const gchar *) data->content->data, data->pos, &internal_error);
+ if (internal_error != NULL)
+ g_propagate_error (error, internal_error);
+ }
- if (g_simple_async_result_propagate_error (simple, error))
- return FALSE;
+ return res;
+}
- g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == json_parser_load_from_stream_async);
+static void
+read_from_stream (GTask *task,
+ gpointer source_obj,
+ gpointer task_data,
+ GCancellable *cancellable)
+{
+ LoadData *data = task_data;
+ GError *error = NULL;
+ gssize res;
- data = g_simple_async_result_get_op_res_gpointer (simple);
+ data->pos = 0;
+ g_byte_array_set_size (data->content, data->pos + GET_DATA_BLOCK_SIZE + 1);
+ while ((res = g_input_stream_read (data->stream,
+ data->content->data + data->pos,
+ GET_DATA_BLOCK_SIZE,
+ cancellable, &error)) > 0)
+ {
+ data->pos += res;
+ g_byte_array_set_size (data->content, data->pos + GET_DATA_BLOCK_SIZE + 1);
+ }
- if (data->error)
+ if (res < 0)
{
- g_propagate_error (error, data->error);
- data->error = NULL;
- return FALSE;
+ g_task_return_error (task, error);
+ return;
}
- g_byte_array_set_size (data->content, data->pos + 1);
+ /* zero-terminate the content; we allocated an extra byte for this */
data->content->data[data->pos] = 0;
-
- internal_error = NULL;
- res = json_parser_load (parser, (const gchar *) data->content->data, data->pos, &internal_error);
-
- if (internal_error != NULL)
- g_propagate_error (error, internal_error);
-
- return res;
+ g_task_return_boolean (task, TRUE);
}
/**
@@ -1422,26 +1371,21 @@ json_parser_load_from_stream_async (JsonParser *parser,
GAsyncReadyCallback callback,
gpointer user_data)
{
- LoadStreamData *data;
+ LoadData *data;
+ GTask *task;
g_return_if_fail (JSON_IS_PARSER (parser));
g_return_if_fail (G_IS_INPUT_STREAM (stream));
g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
- data = g_new0 (LoadStreamData, 1);
+ data = g_new (LoadData, 1);
+ data->stream = g_object_ref (stream);
+ data->content = g_byte_array_new ();
+ data->pos = 0;
- if (cancellable != NULL)
- data->cancellable = g_object_ref (cancellable);
+ task = g_task_new (parser, cancellable, callback, user_data);
+ g_task_set_task_data (task, data, load_data_free);
- data->callback = callback;
- data->user_data = user_data;
- data->content = g_byte_array_new ();
- data->parser = g_object_ref (parser);
-
- g_byte_array_set_size (data->content, data->pos + GET_DATA_BLOCK_SIZE);
- g_input_stream_read_async (stream, data->content->data + data->pos,
- GET_DATA_BLOCK_SIZE, 0,
- data->cancellable,
- load_stream_data_read_callback,
- data);
+ g_task_run_in_thread (task, read_from_stream);
+ g_object_unref (task);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]