- GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (user_data);
- ReadAsyncData *data;
- GError *error;
- gssize nread;
-
- data = g_simple_async_result_get_op_res_gpointer (simple);
-
- error = NULL;
- nread = g_input_stream_read_finish (G_INPUT_STREAM (source_object),
- result, &error);
-
- /* Only report the error if we've not already read some data */
- if (nread < 0 && data->bytes_read == 0)
- g_simple_async_result_set_from_error (simple, error);
-
- if (nread > 0)
- data->bytes_read += nread;
-
- if (error)
- g_error_free (error);
-
- /* Complete immediately, not in idle, since we're already in a mainloop callout */
- g_simple_async_result_complete (simple);
- g_object_unref (simple);
-}
-
-static void
-read_fill_buffer_callback (GObject *source_object,
- GAsyncResult *result,
- gpointer user_data)
-{
- GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (user_data);
- GBufferedInputStream *bstream;
- GBufferedInputStreamPrivate *priv;
- ReadAsyncData *data;
- GError *error;
- gssize nread;
- gsize available;
-
- bstream = G_BUFFERED_INPUT_STREAM (source_object);
- priv = bstream->priv;
-
- g_input_stream_set_pending (G_INPUT_STREAM (bstream), TRUE); /* enable again */
-
- data = g_simple_async_result_get_op_res_gpointer (simple);
-
- error = NULL;
- nread = g_buffered_input_stream_fill_finish (bstream,
- result, &error);
-
- if (nread < 0 && data->bytes_read == 0)
- g_simple_async_result_set_from_error (simple, error);
-
-
- if (nread > 0)
- {
- available = priv->end - priv->pos;
- data->count = MIN (data->count, available);
-
- memcpy ((char *)data->buffer + data->bytes_read, (char *)priv->buffer + priv->pos, data->count);
- data->bytes_read += data->count;
- priv->pos += data->count;
- }
-
- if (error)
- g_error_free (error);
-
- /* Complete immediately, not in idle, since we're already in a mainloop callout */
- g_simple_async_result_complete (simple);
- g_object_unref (simple);
-}
-
-static void
-g_buffered_input_stream_read_async (GInputStream *stream,
- void *buffer,
- gsize count,
- int io_priority,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
-{
- GBufferedInputStream *bstream;
- GBufferedInputStreamPrivate *priv;
- GInputStream *base_stream;
- gsize available;
- GSimpleAsyncResult *simple;
- ReadAsyncData *data;
-
- bstream = G_BUFFERED_INPUT_STREAM (stream);
- priv = bstream->priv;
-
- data = g_slice_new (ReadAsyncData);
- data->buffer = buffer;
- data->bytes_read = 0;
- simple = g_simple_async_result_new (G_OBJECT (stream),
- callback, user_data,
- g_buffered_input_stream_read_async);
- g_simple_async_result_set_op_res_gpointer (simple, data, free_read_async_data);
-
- available = priv->end - priv->pos;
-
- if (count <= available)
- {
- memcpy (buffer, priv->buffer + priv->pos, count);
- priv->pos += count;
- data->bytes_read = count;
-
- g_simple_async_result_complete_in_idle (simple);
- g_object_unref (simple);
- return;
- }
-
-
- /* Full request not available, read all currently availbile and request refill for more */
-
- memcpy (buffer, priv->buffer + priv->pos, available);
- priv->pos = 0;
- priv->end = 0;
-
- count -= available;
-
- data->bytes_read = available;
- data->count = count;
-
- if (count > priv->len)
- {
- /* Large request, shortcut buffer */
-
- base_stream = G_FILTER_INPUT_STREAM (stream)->base_stream;
-
- g_input_stream_read_async (base_stream,
- (char *)buffer + data->bytes_read,
- count,
- io_priority, cancellable,
- large_read_callback,
- simple);
- }
- else
- {
- g_input_stream_set_pending (stream, FALSE); /* to avoid already pending error */
- g_buffered_input_stream_fill_async (bstream, priv->len,
- io_priority, cancellable,
- read_fill_buffer_callback, simple);
- }
-}
-
-static gssize
-g_buffered_input_stream_read_finish (GInputStream *stream,
- GAsyncResult *result,
- GError **error)
-{
- GSimpleAsyncResult *simple;
- ReadAsyncData *data;
-
- simple = G_SIMPLE_ASYNC_RESULT (result);
-
- g_assert (g_simple_async_result_get_source_tag (simple) == g_buffered_input_stream_read_async);
-
- data = g_simple_async_result_get_op_res_gpointer (simple);
-
- return data->bytes_read;
-}
-
-typedef struct {