/* GIO - GLib Input, Output and Streaming Library
 * 
 * Copyright (C) 2006-2007 Red Hat, Inc.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General
 * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
 *
 * Author: Alexander Larsson <alexl@redhat.com>
 */

#include "config.h"
#include <glib.h>
#include "glibintl.h"

#include "ginputstream.h"
#include "gioprivate.h"
#include "gseekable.h"
#include "gcancellable.h"
#include "gasyncresult.h"
#include "gioerror.h"
#include "gpollableinputstream.h"

/**
 * SECTION:ginputstream
 * @short_description: Base class for implementing streaming input
 * @include: gio/gio.h
 *
 * #GInputStream has functions to read from a stream (g_input_stream_read()),
 * to close a stream (g_input_stream_close()) and to skip some content
 * (g_input_stream_skip()). 
 *
 * To copy the content of an input stream to an output stream without 
 * manually handling the reads and writes, use g_output_stream_splice().
 *
 * See the documentation for #GIOStream for details of thread safety of
 * streaming APIs.
 *
 * All of these functions have async variants too.
 **/

struct _GInputStreamPrivate {
  guint closed : 1;
  guint pending : 1;
  GAsyncReadyCallback outstanding_callback;
};

G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (GInputStream, g_input_stream, G_TYPE_OBJECT)

static gssize   g_input_stream_real_skip         (GInputStream         *stream,
						  gsize                 count,
						  GCancellable         *cancellable,
						  GError              **error);
static void     g_input_stream_real_read_async   (GInputStream         *stream,
						  void                 *buffer,
						  gsize                 count,
						  int                   io_priority,
						  GCancellable         *cancellable,
						  GAsyncReadyCallback   callback,
						  gpointer              user_data);
static gssize   g_input_stream_real_read_finish  (GInputStream         *stream,
						  GAsyncResult         *result,
						  GError              **error);
static void     g_input_stream_real_skip_async   (GInputStream         *stream,
						  gsize                 count,
						  int                   io_priority,
						  GCancellable         *cancellable,
						  GAsyncReadyCallback   callback,
						  gpointer              data);
static gssize   g_input_stream_real_skip_finish  (GInputStream         *stream,
						  GAsyncResult         *result,
						  GError              **error);
static void     g_input_stream_real_close_async  (GInputStream         *stream,
						  int                   io_priority,
						  GCancellable         *cancellable,
						  GAsyncReadyCallback   callback,
						  gpointer              data);
static gboolean g_input_stream_real_close_finish (GInputStream         *stream,
						  GAsyncResult         *result,
						  GError              **error);

static void
g_input_stream_dispose (GObject *object)
{
  GInputStream *stream;

  stream = G_INPUT_STREAM (object);
  
  if (!stream->priv->closed)
    g_input_stream_close (stream, NULL, NULL);

  G_OBJECT_CLASS (g_input_stream_parent_class)->dispose (object);
}


static void
g_input_stream_class_init (GInputStreamClass *klass)
{
  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
  
  gobject_class->dispose = g_input_stream_dispose;
  
  klass->skip = g_input_stream_real_skip;
  klass->read_async = g_input_stream_real_read_async;
  klass->read_finish = g_input_stream_real_read_finish;
  klass->skip_async = g_input_stream_real_skip_async;
  klass->skip_finish = g_input_stream_real_skip_finish;
  klass->close_async = g_input_stream_real_close_async;
  klass->close_finish = g_input_stream_real_close_finish;
}

static void
g_input_stream_init (GInputStream *stream)
{
  stream->priv = g_input_stream_get_instance_private (stream);
}

/**
 * g_input_stream_read:
 * @stream: a #GInputStream.
 * @buffer: (array length=count) (element-type guint8): a buffer to
 *     read data into (which should be at least count bytes long).
 * @count: the number of bytes that will be read from the stream
 * @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore.
 * @error: location to store the error occurring, or %NULL to ignore
 *
 * Tries to read @count bytes from the stream into the buffer starting at
 * @buffer. Will block during this read.
 * 
 * If count is zero returns zero and does nothing. A value of @count
 * larger than %G_MAXSSIZE will cause a %G_IO_ERROR_INVALID_ARGUMENT error.
 *
 * On success, the number of bytes read into the buffer is returned.
 * It is not an error if this is not the same as the requested size, as it
 * can happen e.g. near the end of a file. Zero is returned on end of file
 * (or if @count is zero),  but never otherwise.
 *
 * The returned @buffer is not a nul-terminated string, it can contain nul bytes
 * at any position, and this function doesn't nul-terminate the @buffer.
 *
 * If @cancellable is not %NULL, then the operation can be cancelled by
 * triggering the cancellable object from another thread. If the operation
 * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. If an
 * operation was partially finished when the operation was cancelled the
 * partial result will be returned, without an error.
 *
 * On error -1 is returned and @error is set accordingly.
 * 
 * Returns: Number of bytes read, or -1 on error, or 0 on end of file.
 **/
gssize
g_input_stream_read  (GInputStream  *stream,
		      void          *buffer,
		      gsize          count,
		      GCancellable  *cancellable,
		      GError       **error)
{
  GInputStreamClass *class;
  gssize res;

  g_return_val_if_fail (G_IS_INPUT_STREAM (stream), -1);
  g_return_val_if_fail (buffer != NULL, 0);

  if (count == 0)
    return 0;
  
  if (((gssize) count) < 0)
    {
      g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
		   _("Too large count value passed to %s"), G_STRFUNC);
      return -1;
    }

  class = G_INPUT_STREAM_GET_CLASS (stream);

  if (class->read_fn == NULL) 
    {
      g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
                           _("Input stream doesn't implement read"));
      return -1;
    }

  if (!g_input_stream_set_pending (stream, error))
    return -1;

  if (cancellable)
    g_cancellable_push_current (cancellable);
  
  res = class->read_fn (stream, buffer, count, cancellable, error);

  if (cancellable)
    g_cancellable_pop_current (cancellable);
  
  g_input_stream_clear_pending (stream);

  return res;
}

/**
 * g_input_stream_read_all:
 * @stream: a #GInputStream.
 * @buffer: (array length=count) (element-type guint8): a buffer to
 *     read data into (which should be at least count bytes long).
 * @count: the number of bytes that will be read from the stream
 * @bytes_read: (out): location to store the number of bytes that was read from the stream
 * @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore.
 * @error: location to store the error occurring, or %NULL to ignore
 *
 * Tries to read @count bytes from the stream into the buffer starting at
 * @buffer. Will block during this read.
 *
 * This function is similar to g_input_stream_read(), except it tries to
 * read as many bytes as requested, only stopping on an error or end of stream.
 *
 * On a successful read of @count bytes, or if we reached the end of the
 * stream,  %TRUE is returned, and @bytes_read is set to the number of bytes
 * read into @buffer.
 * 
 * If there is an error during the operation %FALSE is returned and @error
 * is set to indicate the error status.
 *
 * As a special exception to the normal conventions for functions that
 * use #GError, if this function returns %FALSE (and sets @error) then
 * @bytes_read will be set to the number of bytes that were successfully
 * read before the error was encountered.  This functionality is only
 * available from C.  If you need it from another language then you must
 * write your own loop around g_input_stream_read().
 *
 * Returns: %TRUE on success, %FALSE if there was an error
 **/
gboolean
g_input_stream_read_all (GInputStream  *stream,
			 void          *buffer,
			 gsize          count,
			 gsize         *bytes_read,
			 GCancellable  *cancellable,
			 GError       **error)
{
  gsize _bytes_read;
  gssize res;

  g_return_val_if_fail (G_IS_INPUT_STREAM (stream), FALSE);
  g_return_val_if_fail (buffer != NULL, FALSE);

  _bytes_read = 0;
  while (_bytes_read < count)
    {
      res = g_input_stream_read (stream, (char *)buffer + _bytes_read, count - _bytes_read,
				 cancellable, error);
      if (res == -1)
	{
	  if (bytes_read)
	    *bytes_read = _bytes_read;
	  return FALSE;
	}
      
      if (res == 0)
	break;

      _bytes_read += res;
    }

  if (bytes_read)
    *bytes_read = _bytes_read;
  return TRUE;
}

/**
 * g_input_stream_read_bytes:
 * @stream: a #GInputStream.
 * @count: maximum number of bytes that will be read from the stream. Common
 * values include 4096 and 8192.
 * @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore.
 * @error: location to store the error occurring, or %NULL to ignore
 *
 * Like g_input_stream_read(), this tries to read @count bytes from
 * the stream in a blocking fashion. However, rather than reading into
 * a user-supplied buffer, this will create a new #GBytes containing
 * the data that was read. This may be easier to use from language
 * bindings.
 *
 * If count is zero, returns a zero-length #GBytes and does nothing. A
 * value of @count larger than %G_MAXSSIZE will cause a
 * %G_IO_ERROR_INVALID_ARGUMENT error.
 *
 * On success, a new #GBytes is returned. It is not an error if the
 * size of this object is not the same as the requested size, as it
 * can happen e.g. near the end of a file. A zero-length #GBytes is
 * returned on end of file (or if @count is zero), but never
 * otherwise.
 *
 * If @cancellable is not %NULL, then the operation can be cancelled by
 * triggering the cancellable object from another thread. If the operation
 * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. If an
 * operation was partially finished when the operation was cancelled the
 * partial result will be returned, without an error.
 *
 * On error %NULL is returned and @error is set accordingly.
 *
 * Returns: a new #GBytes, or %NULL on error
 *
 * Since: 2.34
 **/
GBytes *
g_input_stream_read_bytes (GInputStream  *stream,
			   gsize          count,
			   GCancellable  *cancellable,
			   GError       **error)
{
  guchar *buf;
  gssize nread;

  buf = g_malloc (count);
  nread = g_input_stream_read (stream, buf, count, cancellable, error);
  if (nread == -1)
    {
      g_free (buf);
      return NULL;
    }
  else if (nread == 0)
    {
      g_free (buf);
      return g_bytes_new_static ("", 0);
    }
  else
    return g_bytes_new_take (buf, nread);
}

/**
 * g_input_stream_skip:
 * @stream: a #GInputStream.
 * @count: the number of bytes that will be skipped from the stream
 * @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore. 
 * @error: location to store the error occurring, or %NULL to ignore
 *
 * Tries to skip @count bytes from the stream. Will block during the operation.
 *
 * This is identical to g_input_stream_read(), from a behaviour standpoint,
 * but the bytes that are skipped are not returned to the user. Some
 * streams have an implementation that is more efficient than reading the data.
 *
 * This function is optional for inherited classes, as the default implementation
 * emulates it using read.
 *
 * If @cancellable is not %NULL, then the operation can be cancelled by
 * triggering the cancellable object from another thread. If the operation
 * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. If an
 * operation was partially finished when the operation was cancelled the
 * partial result will be returned, without an error.
 *
 * Returns: Number of bytes skipped, or -1 on error
 **/
gssize
g_input_stream_skip (GInputStream  *stream,
		     gsize          count,
		     GCancellable  *cancellable,
		     GError       **error)
{
  GInputStreamClass *class;
  gssize res;

  g_return_val_if_fail (G_IS_INPUT_STREAM (stream), -1);

  if (count == 0)
    return 0;

  if (((gssize) count) < 0)
    {
      g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
		   _("Too large count value passed to %s"), G_STRFUNC);
      return -1;
    }
  
  class = G_INPUT_STREAM_GET_CLASS (stream);

  if (!g_input_stream_set_pending (stream, error))
    return -1;

  if (cancellable)
    g_cancellable_push_current (cancellable);
  
  res = class->skip (stream, count, cancellable, error);

  if (cancellable)
    g_cancellable_pop_current (cancellable);
  
  g_input_stream_clear_pending (stream);

  return res;
}

static gssize
g_input_stream_real_skip (GInputStream  *stream,
			  gsize          count,
			  GCancellable  *cancellable,
			  GError       **error)
{
  GInputStreamClass *class;
  gssize ret, read_bytes;
  char buffer[8192];
  GError *my_error;

  if (G_IS_SEEKABLE (stream) && g_seekable_can_seek (G_SEEKABLE (stream)))
    {
      if (g_seekable_seek (G_SEEKABLE (stream),
			   count,
			   G_SEEK_CUR,
			   cancellable,
			   NULL))
	return count;
    }

  /* If not seekable, or seek failed, fall back to reading data: */

  class = G_INPUT_STREAM_GET_CLASS (stream);

  read_bytes = 0;
  while (1)
    {
      my_error = NULL;

      ret = class->read_fn (stream, buffer, MIN (sizeof (buffer), count),
                            cancellable, &my_error);
      if (ret == -1)
	{
	  if (read_bytes > 0 &&
	      my_error->domain == G_IO_ERROR &&
	      my_error->code == G_IO_ERROR_CANCELLED)
	    {
	      g_error_free (my_error);
	      return read_bytes;
	    }

	  g_propagate_error (error, my_error);
	  return -1;
	}

      count -= ret;
      read_bytes += ret;

      if (ret == 0 || count == 0)
        return read_bytes;
    }
}

/**
 * g_input_stream_close:
 * @stream: A #GInputStream.
 * @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore.
 * @error: location to store the error occurring, or %NULL to ignore
 *
 * Closes the stream, releasing resources related to it.
 *
 * Once the stream is closed, all other operations will return %G_IO_ERROR_CLOSED.
 * Closing a stream multiple times will not return an error.
 *
 * Streams will be automatically closed when the last reference
 * is dropped, but you might want to call this function to make sure 
 * resources are released as early as possible.
 *
 * Some streams might keep the backing store of the stream (e.g. a file descriptor)
 * open after the stream is closed. See the documentation for the individual
 * stream for details.
 *
 * On failure the first error that happened will be reported, but the close
 * operation will finish as much as possible. A stream that failed to
 * close will still return %G_IO_ERROR_CLOSED for all operations. Still, it
 * is important to check and report the error to the user.
 *
 * If @cancellable is not %NULL, then the operation can be cancelled by
 * triggering the cancellable object from another thread. If the operation
 * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
 * Cancelling a close will still leave the stream closed, but some streams
 * can use a faster close that doesn't block to e.g. check errors. 
 *
 * Returns: %TRUE on success, %FALSE on failure
 **/
gboolean
g_input_stream_close (GInputStream  *stream,
		      GCancellable  *cancellable,
		      GError       **error)
{
  GInputStreamClass *class;
  gboolean res;

  g_return_val_if_fail (G_IS_INPUT_STREAM (stream), FALSE);

  class = G_INPUT_STREAM_GET_CLASS (stream);

  if (stream->priv->closed)
    return TRUE;

  res = TRUE;

  if (!g_input_stream_set_pending (stream, error))
    return FALSE;

  if (cancellable)
    g_cancellable_push_current (cancellable);

  if (class->close_fn)
    res = class->close_fn (stream, cancellable, error);

  if (cancellable)
    g_cancellable_pop_current (cancellable);

  g_input_stream_clear_pending (stream);
  
  stream->priv->closed = TRUE;
  
  return res;
}

static void
async_ready_callback_wrapper (GObject      *source_object,
			      GAsyncResult *res,
			      gpointer      user_data)
{
  GInputStream *stream = G_INPUT_STREAM (source_object);

  g_input_stream_clear_pending (stream);
  if (stream->priv->outstanding_callback)
    (*stream->priv->outstanding_callback) (source_object, res, user_data);
  g_object_unref (stream);
}

static void
async_ready_close_callback_wrapper (GObject      *source_object,
				    GAsyncResult *res,
				    gpointer      user_data)
{
  GInputStream *stream = G_INPUT_STREAM (source_object);

  g_input_stream_clear_pending (stream);
  stream->priv->closed = TRUE;
  if (stream->priv->outstanding_callback)
    (*stream->priv->outstanding_callback) (source_object, res, user_data);
  g_object_unref (stream);
}

/**
 * g_input_stream_read_async:
 * @stream: A #GInputStream.
 * @buffer: (array length=count) (element-type guint8): a buffer to
 *     read data into (which should be at least count bytes long).
 * @count: the number of bytes that will be read from the stream
 * @io_priority: the [I/O priority][io-priority]
 * of the request. 
 * @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore.
 * @callback: (scope async): callback to call when the request is satisfied
 * @user_data: (closure): the data to pass to callback function
 *
 * Request an asynchronous read of @count bytes from the stream into the buffer
 * starting at @buffer. When the operation is finished @callback will be called. 
 * You can then call g_input_stream_read_finish() to get the result of the 
 * operation.
 *
 * During an async request no other sync and async calls are allowed on @stream, and will
 * result in %G_IO_ERROR_PENDING errors. 
 *
 * A value of @count larger than %G_MAXSSIZE will cause a %G_IO_ERROR_INVALID_ARGUMENT error.
 *
 * On success, the number of bytes read into the buffer will be passed to the
 * callback. It is not an error if this is not the same as the requested size, as it
 * can happen e.g. near the end of a file, but generally we try to read
 * as many bytes as requested. Zero is returned on end of file
 * (or if @count is zero),  but never otherwise.
 *
 * Any outstanding i/o request with higher priority (lower numerical value) will
 * be executed before an outstanding request with lower priority. Default
 * priority is %G_PRIORITY_DEFAULT.
 *
 * The asyncronous methods have a default fallback that uses threads to implement
 * asynchronicity, so they are optional for inheriting classes. However, if you
 * override one you must override all.
 **/
void
g_input_stream_read_async (GInputStream        *stream,
			   void                *buffer,
			   gsize                count,
			   int                  io_priority,
			   GCancellable        *cancellable,
			   GAsyncReadyCallback  callback,
			   gpointer             user_data)
{
  GInputStreamClass *class;
  GError *error = NULL;

  g_return_if_fail (G_IS_INPUT_STREAM (stream));
  g_return_if_fail (buffer != NULL);

  if (count == 0)
    {
      GTask *task;

      task = g_task_new (stream, cancellable, callback, user_data);
      g_task_set_source_tag (task, g_input_stream_read_async);
      g_task_return_int (task, 0);
      g_object_unref (task);
      return;
    }
  
  if (((gssize) count) < 0)
    {
      g_task_report_new_error (stream, callback, user_data,
                               g_input_stream_read_async,
                               G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
                               _("Too large count value passed to %s"),
                               G_STRFUNC);
      return;
    }

  if (!g_input_stream_set_pending (stream, &error))
    {
      g_task_report_error (stream, callback, user_data,
                           g_input_stream_read_async,
                           error);
      return;
    }

  class = G_INPUT_STREAM_GET_CLASS (stream);
  stream->priv->outstanding_callback = callback;
  g_object_ref (stream);
  class->read_async (stream, buffer, count, io_priority, cancellable,
		     async_ready_callback_wrapper, user_data);
}

/**
 * g_input_stream_read_finish:
 * @stream: a #GInputStream.
 * @result: a #GAsyncResult.
 * @error: a #GError location to store the error occurring, or %NULL to 
 * ignore.
 * 
 * Finishes an asynchronous stream read operation. 
 * 
 * Returns: number of bytes read in, or -1 on error, or 0 on end of file.
 **/
gssize
g_input_stream_read_finish (GInputStream  *stream,
			    GAsyncResult  *result,
			    GError       **error)
{
  GInputStreamClass *class;
  
  g_return_val_if_fail (G_IS_INPUT_STREAM (stream), -1);
  g_return_val_if_fail (G_IS_ASYNC_RESULT (result), -1);

  if (g_async_result_legacy_propagate_error (result, error))
    return -1;
  else if (g_async_result_is_tagged (result, g_input_stream_read_async))
    return g_task_propagate_int (G_TASK (result), error);

  class = G_INPUT_STREAM_GET_CLASS (stream);
  return class->read_finish (stream, result, error);
}

typedef struct
{
  gchar *buffer;
  gsize to_read;
  gsize bytes_read;
} AsyncReadAll;

static void
free_async_read_all (gpointer data)
{
  g_slice_free (AsyncReadAll, data);
}

static void
read_all_callback (GObject      *stream,
                   GAsyncResult *result,
                   gpointer      user_data)
{
  GTask *task = user_data;
  AsyncReadAll *data = g_task_get_task_data (task);
  gboolean got_eof = FALSE;

  if (result)
    {
      GError *error = NULL;
      gssize nread;

      nread = g_input_stream_read_finish (G_INPUT_STREAM (stream), result, &error);

      if (nread == -1)
        {
          g_task_return_error (task, error);
          g_object_unref (task);
          return;
        }

      g_assert_cmpint (nread, <=, data->to_read);
      data->to_read -= nread;
      data->bytes_read += nread;
      got_eof = (nread == 0);
    }

  if (got_eof || data->to_read == 0)
    {
      g_task_return_boolean (task, TRUE);
      g_object_unref (task);
    }

  else
    g_input_stream_read_async (G_INPUT_STREAM (stream),
                               data->buffer + data->bytes_read,
                               data->to_read,
                               g_task_get_priority (task),
                               g_task_get_cancellable (task),
                               read_all_callback, task);
}


static void
read_all_async_thread (GTask        *task,
                       gpointer      source_object,
                       gpointer      task_data,
                       GCancellable *cancellable)
{
  GInputStream *stream = source_object;
  AsyncReadAll *data = task_data;
  GError *error = NULL;

  if (g_input_stream_read_all (stream, data->buffer, data->to_read, &data->bytes_read,
                               g_task_get_cancellable (task), &error))
    g_task_return_boolean (task, TRUE);
  else
    g_task_return_error (task, error);
}

/**
 * g_input_stream_read_all_async:
 * @stream: A #GInputStream
 * @buffer: (array length=count) (element-type guint8): a buffer to
 *     read data into (which should be at least count bytes long)
 * @count: the number of bytes that will be read from the stream
 * @io_priority: the [I/O priority][io-priority] of the request
 * @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore
 * @callback: (scope async): callback to call when the request is satisfied
 * @user_data: (closure): the data to pass to callback function
 *
 * Request an asynchronous read of @count bytes from the stream into the
 * buffer starting at @buffer.
 *
 * This is the asynchronous equivalent of g_input_stream_read_all().
 *
 * Call g_input_stream_read_all_finish() to collect the result.
 *
 * Any outstanding I/O request with higher priority (lower numerical
 * value) will be executed before an outstanding request with lower
 * priority. Default priority is %G_PRIORITY_DEFAULT.
 *
 * Since: 2.44
 **/
void
g_input_stream_read_all_async (GInputStream        *stream,
                               void                *buffer,
                               gsize                count,
                               int                  io_priority,
                               GCancellable        *cancellable,
                               GAsyncReadyCallback  callback,
                               gpointer             user_data)
{
  AsyncReadAll *data;
  GTask *task;

  g_return_if_fail (G_IS_INPUT_STREAM (stream));
  g_return_if_fail (buffer != NULL || count == 0);

  task = g_task_new (stream, cancellable, callback, user_data);
  data = g_slice_new0 (AsyncReadAll);
  data->buffer = buffer;
  data->to_read = count;

  g_task_set_source_tag (task, g_input_stream_read_all_async);
  g_task_set_task_data (task, data, free_async_read_all);
  g_task_set_priority (task, io_priority);

  /* If async reads are going to be handled via the threadpool anyway
   * then we may as well do it with a single dispatch instead of
   * bouncing in and out.
   */
  if (g_input_stream_async_read_is_via_threads (stream))
    {
      g_task_run_in_thread (task, read_all_async_thread);
      g_object_unref (task);
    }
  else
    read_all_callback (G_OBJECT (stream), NULL, task);
}

/**
 * g_input_stream_read_all_finish:
 * @stream: a #GInputStream
 * @result: a #GAsyncResult
 * @bytes_read: (out): location to store the number of bytes that was read from the stream
 * @error: a #GError location to store the error occurring, or %NULL to ignore
 *
 * Finishes an asynchronous stream read operation started with
 * g_input_stream_read_all_async().
 *
 * As a special exception to the normal conventions for functions that
 * use #GError, if this function returns %FALSE (and sets @error) then
 * @bytes_read will be set to the number of bytes that were successfully
 * read before the error was encountered.  This functionality is only
 * available from C.  If you need it from another language then you must
 * write your own loop around g_input_stream_read_async().
 *
 * Returns: %TRUE on success, %FALSE if there was an error
 *
 * Since: 2.44
 **/
gboolean
g_input_stream_read_all_finish (GInputStream  *stream,
                                GAsyncResult  *result,
                                gsize         *bytes_read,
                                GError       **error)
{
  GTask *task;

  g_return_val_if_fail (G_IS_INPUT_STREAM (stream), FALSE);
  g_return_val_if_fail (g_task_is_valid (result, stream), FALSE);

  task = G_TASK (result);

  if (bytes_read)
    {
      AsyncReadAll *data = g_task_get_task_data (task);

      *bytes_read = data->bytes_read;
    }

  return g_task_propagate_boolean (task, error);
}

static void
read_bytes_callback (GObject      *stream,
		     GAsyncResult *result,
		     gpointer      user_data)
{
  GTask *task = user_data;
  guchar *buf = g_task_get_task_data (task);
  GError *error = NULL;
  gssize nread;
  GBytes *bytes = NULL;

  nread = g_input_stream_read_finish (G_INPUT_STREAM (stream),
				      result, &error);
  if (nread == -1)
    {
      g_free (buf);
      g_task_return_error (task, error);
    }
  else if (nread == 0)
    {
      g_free (buf);
      bytes = g_bytes_new_static ("", 0);
    }
  else
    bytes = g_bytes_new_take (buf, nread);

  if (bytes)
    g_task_return_pointer (task, bytes, (GDestroyNotify)g_bytes_unref);

  g_object_unref (task);
}

/**
 * g_input_stream_read_bytes_async:
 * @stream: A #GInputStream.
 * @count: the number of bytes that will be read from the stream
 * @io_priority: the [I/O priority][io-priority] of the request
 * @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore.
 * @callback: (scope async): callback to call when the request is satisfied
 * @user_data: (closure): the data to pass to callback function
 *
 * Request an asynchronous read of @count bytes from the stream into a
 * new #GBytes. When the operation is finished @callback will be
 * called. You can then call g_input_stream_read_bytes_finish() to get the
 * result of the operation.
 *
 * During an async request no other sync and async calls are allowed
 * on @stream, and will result in %G_IO_ERROR_PENDING errors.
 *
 * A value of @count larger than %G_MAXSSIZE will cause a
 * %G_IO_ERROR_INVALID_ARGUMENT error.
 *
 * On success, the new #GBytes will be passed to the callback. It is
 * not an error if this is smaller than the requested size, as it can
 * happen e.g. near the end of a file, but generally we try to read as
 * many bytes as requested. Zero is returned on end of file (or if
 * @count is zero), but never otherwise.
 *
 * Any outstanding I/O request with higher priority (lower numerical
 * value) will be executed before an outstanding request with lower
 * priority. Default priority is %G_PRIORITY_DEFAULT.
 *
 * Since: 2.34
 **/
void
g_input_stream_read_bytes_async (GInputStream          *stream,
				 gsize                  count,
				 int                    io_priority,
				 GCancellable          *cancellable,
				 GAsyncReadyCallback    callback,
				 gpointer               user_data)
{
  GTask *task;
  guchar *buf;

  task = g_task_new (stream, cancellable, callback, user_data);
  g_task_set_source_tag (task, g_input_stream_read_bytes_async);

  buf = g_malloc (count);
  g_task_set_task_data (task, buf, NULL);

  g_input_stream_read_async (stream, buf, count,
                             io_priority, cancellable,
                             read_bytes_callback, task);
}

/**
 * g_input_stream_read_bytes_finish:
 * @stream: a #GInputStream.
 * @result: a #GAsyncResult.
 * @error: a #GError location to store the error occurring, or %NULL to
 *   ignore.
 *
 * Finishes an asynchronous stream read-into-#GBytes operation.
 *
 * Returns: the newly-allocated #GBytes, or %NULL on error
 *
 * Since: 2.34
 **/
GBytes *
g_input_stream_read_bytes_finish (GInputStream  *stream,
				  GAsyncResult  *result,
				  GError       **error)
{
  g_return_val_if_fail (G_IS_INPUT_STREAM (stream), NULL);
  g_return_val_if_fail (g_task_is_valid (result, stream), NULL);

  return g_task_propagate_pointer (G_TASK (result), error);
}

/**
 * g_input_stream_skip_async:
 * @stream: A #GInputStream.
 * @count: the number of bytes that will be skipped from the stream
 * @io_priority: the [I/O priority][io-priority] of the request
 * @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore.
 * @callback: (scope async): callback to call when the request is satisfied
 * @user_data: (closure): the data to pass to callback function
 *
 * Request an asynchronous skip of @count bytes from the stream.
 * When the operation is finished @callback will be called.
 * You can then call g_input_stream_skip_finish() to get the result
 * of the operation.
 *
 * During an async request no other sync and async calls are allowed,
 * and will result in %G_IO_ERROR_PENDING errors.
 *
 * A value of @count larger than %G_MAXSSIZE will cause a %G_IO_ERROR_INVALID_ARGUMENT error.
 *
 * On success, the number of bytes skipped will be passed to the callback.
 * It is not an error if this is not the same as the requested size, as it
 * can happen e.g. near the end of a file, but generally we try to skip
 * as many bytes as requested. Zero is returned on end of file
 * (or if @count is zero), but never otherwise.
 *
 * Any outstanding i/o request with higher priority (lower numerical value)
 * will be executed before an outstanding request with lower priority.
 * Default priority is %G_PRIORITY_DEFAULT.
 *
 * The asynchronous methods have a default fallback that uses threads to
 * implement asynchronicity, so they are optional for inheriting classes.
 * However, if you override one, you must override all.
 **/
void
g_input_stream_skip_async (GInputStream        *stream,
			   gsize                count,
			   int                  io_priority,
			   GCancellable        *cancellable,
			   GAsyncReadyCallback  callback,
			   gpointer             user_data)
{
  GInputStreamClass *class;
  GError *error = NULL;

  g_return_if_fail (G_IS_INPUT_STREAM (stream));

  if (count == 0)
    {
      GTask *task;

      task = g_task_new (stream, cancellable, callback, user_data);
      g_task_set_source_tag (task, g_input_stream_skip_async);
      g_task_return_int (task, 0);
      g_object_unref (task);
      return;
    }
  
  if (((gssize) count) < 0)
    {
      g_task_report_new_error (stream, callback, user_data,
                               g_input_stream_skip_async,
                               G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
                               _("Too large count value passed to %s"),
                               G_STRFUNC);
      return;
    }

  if (!g_input_stream_set_pending (stream, &error))
    {
      g_task_report_error (stream, callback, user_data,
                           g_input_stream_skip_async,
                           error);
      return;
    }

  class = G_INPUT_STREAM_GET_CLASS (stream);
  stream->priv->outstanding_callback = callback;
  g_object_ref (stream);
  class->skip_async (stream, count, io_priority, cancellable,
		     async_ready_callback_wrapper, user_data);
}

/**
 * g_input_stream_skip_finish:
 * @stream: a #GInputStream.
 * @result: a #GAsyncResult.
 * @error: a #GError location to store the error occurring, or %NULL to 
 * ignore.
 * 
 * Finishes a stream skip operation.
 * 
 * Returns: the size of the bytes skipped, or %-1 on error.
 **/
gssize
g_input_stream_skip_finish (GInputStream  *stream,
			    GAsyncResult  *result,
			    GError       **error)
{
  GInputStreamClass *class;

  g_return_val_if_fail (G_IS_INPUT_STREAM (stream), -1);
  g_return_val_if_fail (G_IS_ASYNC_RESULT (result), -1);

  if (g_async_result_legacy_propagate_error (result, error))
    return -1;
  else if (g_async_result_is_tagged (result, g_input_stream_skip_async))
    return g_task_propagate_int (G_TASK (result), error);

  class = G_INPUT_STREAM_GET_CLASS (stream);
  return class->skip_finish (stream, result, error);
}

/**
 * g_input_stream_close_async:
 * @stream: A #GInputStream.
 * @io_priority: the [I/O priority][io-priority] of the request
 * @cancellable: (allow-none): optional cancellable object
 * @callback: (scope async): callback to call when the request is satisfied
 * @user_data: (closure): the data to pass to callback function
 *
 * Requests an asynchronous closes of the stream, releasing resources related to it.
 * When the operation is finished @callback will be called. 
 * You can then call g_input_stream_close_finish() to get the result of the 
 * operation.
 *
 * For behaviour details see g_input_stream_close().
 *
 * The asyncronous methods have a default fallback that uses threads to implement
 * asynchronicity, so they are optional for inheriting classes. However, if you
 * override one you must override all.
 **/
void
g_input_stream_close_async (GInputStream        *stream,
			    int                  io_priority,
			    GCancellable        *cancellable,
			    GAsyncReadyCallback  callback,
			    gpointer             user_data)
{
  GInputStreamClass *class;
  GError *error = NULL;

  g_return_if_fail (G_IS_INPUT_STREAM (stream));

  if (stream->priv->closed)
    {
      GTask *task;

      task = g_task_new (stream, cancellable, callback, user_data);
      g_task_set_source_tag (task, g_input_stream_close_async);
      g_task_return_boolean (task, TRUE);
      g_object_unref (task);
      return;
    }

  if (!g_input_stream_set_pending (stream, &error))
    {
      g_task_report_error (stream, callback, user_data,
                           g_input_stream_close_async,
                           error);
      return;
    }
  
  class = G_INPUT_STREAM_GET_CLASS (stream);
  stream->priv->outstanding_callback = callback;
  g_object_ref (stream);
  class->close_async (stream, io_priority, cancellable,
		      async_ready_close_callback_wrapper, user_data);
}

/**
 * g_input_stream_close_finish:
 * @stream: a #GInputStream.
 * @result: a #GAsyncResult.
 * @error: a #GError location to store the error occurring, or %NULL to 
 * ignore.
 * 
 * Finishes closing a stream asynchronously, started from g_input_stream_close_async().
 * 
 * Returns: %TRUE if the stream was closed successfully.
 **/
gboolean
g_input_stream_close_finish (GInputStream  *stream,
			     GAsyncResult  *result,
			     GError       **error)
{
  GInputStreamClass *class;

  g_return_val_if_fail (G_IS_INPUT_STREAM (stream), FALSE);
  g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);

  if (g_async_result_legacy_propagate_error (result, error))
    return FALSE;
  else if (g_async_result_is_tagged (result, g_input_stream_close_async))
    return g_task_propagate_boolean (G_TASK (result), error);

  class = G_INPUT_STREAM_GET_CLASS (stream);
  return class->close_finish (stream, result, error);
}

/**
 * g_input_stream_is_closed:
 * @stream: input stream.
 * 
 * Checks if an input stream is closed.
 * 
 * Returns: %TRUE if the stream is closed.
 **/
gboolean
g_input_stream_is_closed (GInputStream *stream)
{
  g_return_val_if_fail (G_IS_INPUT_STREAM (stream), TRUE);
  
  return stream->priv->closed;
}
 
/**
 * g_input_stream_has_pending:
 * @stream: input stream.
 * 
 * Checks if an input stream has pending actions.
 * 
 * Returns: %TRUE if @stream has pending actions.
 **/  
gboolean
g_input_stream_has_pending (GInputStream *stream)
{
  g_return_val_if_fail (G_IS_INPUT_STREAM (stream), TRUE);
  
  return stream->priv->pending;
}

/**
 * g_input_stream_set_pending:
 * @stream: input stream
 * @error: a #GError location to store the error occurring, or %NULL to 
 * ignore.
 * 
 * Sets @stream to have actions pending. If the pending flag is
 * already set or @stream is closed, it will return %FALSE and set
 * @error.
 *
 * Returns: %TRUE if pending was previously unset and is now set.
 **/
gboolean
g_input_stream_set_pending (GInputStream *stream, GError **error)
{
  g_return_val_if_fail (G_IS_INPUT_STREAM (stream), FALSE);
  
  if (stream->priv->closed)
    {
      g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_CLOSED,
                           _("Stream is already closed"));
      return FALSE;
    }
  
  if (stream->priv->pending)
    {
      g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_PENDING,
		/* Translators: This is an error you get if there is already an
		 * operation running against this stream when you try to start
		 * one */
		 _("Stream has outstanding operation"));
      return FALSE;
    }
  
  stream->priv->pending = TRUE;
  return TRUE;
}

/**
 * g_input_stream_clear_pending:
 * @stream: input stream
 * 
 * Clears the pending flag on @stream.
 **/
void
g_input_stream_clear_pending (GInputStream *stream)
{
  g_return_if_fail (G_IS_INPUT_STREAM (stream));
  
  stream->priv->pending = FALSE;
}

/*< internal >
 * g_input_stream_async_read_is_via_threads:
 * @stream: input stream
 *
 * Checks if an input stream's read_async function uses threads.
 *
 * Returns: %TRUE if @stream's read_async function uses threads.
 **/
gboolean
g_input_stream_async_read_is_via_threads (GInputStream *stream)
{
  GInputStreamClass *class;

  g_return_val_if_fail (G_IS_INPUT_STREAM (stream), FALSE);

  class = G_INPUT_STREAM_GET_CLASS (stream);

  return (class->read_async == g_input_stream_real_read_async &&
      !(G_IS_POLLABLE_INPUT_STREAM (stream) &&
        g_pollable_input_stream_can_poll (G_POLLABLE_INPUT_STREAM (stream))));
}

/*< internal >
 * g_input_stream_async_close_is_via_threads:
 * @stream: input stream
 *
 * Checks if an input stream's close_async function uses threads.
 *
 * Returns: %TRUE if @stream's close_async function uses threads.
 **/
gboolean
g_input_stream_async_close_is_via_threads (GInputStream *stream)
{
  GInputStreamClass *class;

  g_return_val_if_fail (G_IS_INPUT_STREAM (stream), FALSE);

  class = G_INPUT_STREAM_GET_CLASS (stream);

  return class->close_async == g_input_stream_real_close_async;
}

/********************************************
 *   Default implementation of async ops    *
 ********************************************/

typedef struct {
  void   *buffer;
  gsize   count;
} ReadData;

static void
free_read_data (ReadData *op)
{
  g_slice_free (ReadData, op);
}

static void
read_async_thread (GTask        *task,
                   gpointer      source_object,
                   gpointer      task_data,
                   GCancellable *cancellable)
{
  GInputStream *stream = source_object;
  ReadData *op = task_data;
  GInputStreamClass *class;
  GError *error = NULL;
  gssize nread;
 
  class = G_INPUT_STREAM_GET_CLASS (stream);

  nread = class->read_fn (stream,
                          op->buffer, op->count,
                          g_task_get_cancellable (task),
                          &error);
  if (nread == -1)
    g_task_return_error (task, error);
  else
    g_task_return_int (task, nread);
}

static void read_async_pollable (GPollableInputStream *stream,
                                 GTask                *task);

static gboolean
read_async_pollable_ready (GPollableInputStream *stream,
			   gpointer              user_data)
{
  GTask *task = user_data;

  read_async_pollable (stream, task);
  return FALSE;
}

static void
read_async_pollable (GPollableInputStream *stream,
                     GTask                *task)
{
  ReadData *op = g_task_get_task_data (task);
  GError *error = NULL;
  gssize nread;

  if (g_task_return_error_if_cancelled (task))
    return;

  nread = G_POLLABLE_INPUT_STREAM_GET_INTERFACE (stream)->
    read_nonblocking (stream, op->buffer, op->count, &error);

  if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK))
    {
      GSource *source;

      g_error_free (error);

      source = g_pollable_input_stream_create_source (stream,
                                                      g_task_get_cancellable (task));
      g_task_attach_source (task, source,
                            (GSourceFunc) read_async_pollable_ready);
      g_source_unref (source);
      return;
    }

  if (nread == -1)
    g_task_return_error (task, error);
  else
    g_task_return_int (task, nread);
  /* g_input_stream_real_read_async() unrefs task */
}


static void
g_input_stream_real_read_async (GInputStream        *stream,
				void                *buffer,
				gsize                count,
				int                  io_priority,
				GCancellable        *cancellable,
				GAsyncReadyCallback  callback,
				gpointer             user_data)
{
  GTask *task;
  ReadData *op;
  
  op = g_slice_new0 (ReadData);
  task = g_task_new (stream, cancellable, callback, user_data);
  g_task_set_source_tag (task, g_input_stream_real_read_async);
  g_task_set_task_data (task, op, (GDestroyNotify) free_read_data);
  g_task_set_priority (task, io_priority);
  op->buffer = buffer;
  op->count = count;

  if (!g_input_stream_async_read_is_via_threads (stream))
    read_async_pollable (G_POLLABLE_INPUT_STREAM (stream), task);
  else
    g_task_run_in_thread (task, read_async_thread);
  g_object_unref (task);
}

static gssize
g_input_stream_real_read_finish (GInputStream  *stream,
				 GAsyncResult  *result,
				 GError       **error)
{
  g_return_val_if_fail (g_task_is_valid (result, stream), -1);

  return g_task_propagate_int (G_TASK (result), error);
}


static void
skip_async_thread (GTask        *task,
                   gpointer      source_object,
                   gpointer      task_data,
                   GCancellable *cancellable)
{
  GInputStream *stream = source_object;
  gsize count = GPOINTER_TO_SIZE (task_data);
  GInputStreamClass *class;
  GError *error = NULL;
  gssize ret;

  class = G_INPUT_STREAM_GET_CLASS (stream);
  ret = class->skip (stream, count,
                     g_task_get_cancellable (task),
                     &error);
  if (ret == -1)
    g_task_return_error (task, error);
  else
    g_task_return_int (task, ret);
}

typedef struct {
  char buffer[8192];
  gsize count;
  gsize count_skipped;
} SkipFallbackAsyncData;

static void
skip_callback_wrapper (GObject      *source_object,
		       GAsyncResult *res,
		       gpointer      user_data)
{
  GInputStreamClass *class;
  GTask *task = user_data;
  SkipFallbackAsyncData *data = g_task_get_task_data (task);
  GError *error = NULL;
  gssize ret;

  ret = g_input_stream_read_finish (G_INPUT_STREAM (source_object), res, &error);

  if (ret > 0)
    {
      data->count -= ret;
      data->count_skipped += ret;

      if (data->count > 0)
	{
	  class = G_INPUT_STREAM_GET_CLASS (source_object);
	  class->read_async (G_INPUT_STREAM (source_object),
                             data->buffer, MIN (8192, data->count),
                             g_task_get_priority (task),
                             g_task_get_cancellable (task),
                             skip_callback_wrapper, task);
	  return;
	}
    }

  if (ret == -1 &&
      g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED) &&
      data->count_skipped)
    {
      /* No error, return partial read */
      g_clear_error (&error);
    }

  if (error)
    g_task_return_error (task, error);
  else
    g_task_return_int (task, data->count_skipped);
  g_object_unref (task);
 }

static void
g_input_stream_real_skip_async (GInputStream        *stream,
				gsize                count,
				int                  io_priority,
				GCancellable        *cancellable,
				GAsyncReadyCallback  callback,
				gpointer             user_data)
{
  GInputStreamClass *class;
  SkipFallbackAsyncData *data;
  GTask *task;

  class = G_INPUT_STREAM_GET_CLASS (stream);

  task = g_task_new (stream, cancellable, callback, user_data);
  g_task_set_source_tag (task, g_input_stream_real_skip_async);
  g_task_set_priority (task, io_priority);

  if (g_input_stream_async_read_is_via_threads (stream))
    {
      /* Read is thread-using async fallback.
       * Make skip use threads too, so that we can use a possible sync skip
       * implementation. */
      g_task_set_task_data (task, GSIZE_TO_POINTER (count), NULL);

      g_task_run_in_thread (task, skip_async_thread);
      g_object_unref (task);
    }
  else
    {
      /* TODO: Skip fallback uses too much memory, should do multiple read calls */
      
      /* There is a custom async read function, lets use that. */
      data = g_new (SkipFallbackAsyncData, 1);
      data->count = count;
      data->count_skipped = 0;
      g_task_set_task_data (task, data, g_free);
      g_task_set_check_cancellable (task, FALSE);
      class->read_async (stream, data->buffer, MIN (8192, count), io_priority, cancellable,
			 skip_callback_wrapper, task);
    }

}

static gssize
g_input_stream_real_skip_finish (GInputStream  *stream,
				 GAsyncResult  *result,
				 GError       **error)
{
  g_return_val_if_fail (g_task_is_valid (result, stream), -1);

  return g_task_propagate_int (G_TASK (result), error);
}

static void
close_async_thread (GTask        *task,
                    gpointer      source_object,
                    gpointer      task_data,
                    GCancellable *cancellable)
{
  GInputStream *stream = source_object;
  GInputStreamClass *class;
  GError *error = NULL;
  gboolean result;

  class = G_INPUT_STREAM_GET_CLASS (stream);
  if (class->close_fn)
    {
      result = class->close_fn (stream,
                                g_task_get_cancellable (task),
                                &error);
      if (!result)
        {
          g_task_return_error (task, error);
          return;
        }
    }

  g_task_return_boolean (task, TRUE);
}

static void
g_input_stream_real_close_async (GInputStream        *stream,
				 int                  io_priority,
				 GCancellable        *cancellable,
				 GAsyncReadyCallback  callback,
				 gpointer             user_data)
{
  GTask *task;

  task = g_task_new (stream, cancellable, callback, user_data);
  g_task_set_source_tag (task, g_input_stream_real_close_async);
  g_task_set_check_cancellable (task, FALSE);
  g_task_set_priority (task, io_priority);
  
  g_task_run_in_thread (task, close_async_thread);
  g_object_unref (task);
}

static gboolean
g_input_stream_real_close_finish (GInputStream  *stream,
				  GAsyncResult  *result,
				  GError       **error)
{
  g_return_val_if_fail (g_task_is_valid (result, stream), FALSE);

  return g_task_propagate_boolean (G_TASK (result), error);
}
