/* 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, write to the
 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 * Boston, MA 02111-1307, USA.
 *
 * Author: Alexander Larsson <alexl@redhat.com>
 */

#include "config.h"
#include "goutputstream.h"
#include "gcancellable.h"
#include "gasyncresult.h"
#include "gsimpleasyncresult.h"
#include "ginputstream.h"
#include "gioerror.h"
#include "glibintl.h"
#include "gpollableoutputstream.h"

/**
 * SECTION:goutputstream
 * @short_description: Base class for implementing streaming output
 * @include: gio/gio.h
 *
 * #GOutputStream has functions to write to a stream (g_output_stream_write()),
 * to close a stream (g_output_stream_close()) and to flush pending writes
 * (g_output_stream_flush()). 
 *
 * To copy the content of an input stream to an output stream without 
 * manually handling the reads and writes, use g_output_stream_splice(). 
 *
 * All of these functions have async variants too.
 **/

G_DEFINE_ABSTRACT_TYPE (GOutputStream, g_output_stream, G_TYPE_OBJECT);

struct _GOutputStreamPrivate {
  guint closed : 1;
  guint pending : 1;
  guint closing : 1;
  GAsyncReadyCallback outstanding_callback;
};

static gssize   g_output_stream_real_splice        (GOutputStream             *stream,
						    GInputStream              *source,
						    GOutputStreamSpliceFlags   flags,
						    GCancellable              *cancellable,
						    GError                   **error);
static void     g_output_stream_real_write_async   (GOutputStream             *stream,
						    const void                *buffer,
						    gsize                      count,
						    int                        io_priority,
						    GCancellable              *cancellable,
						    GAsyncReadyCallback        callback,
						    gpointer                   data);
static gssize   g_output_stream_real_write_finish  (GOutputStream             *stream,
						    GAsyncResult              *result,
						    GError                   **error);
static void     g_output_stream_real_splice_async  (GOutputStream             *stream,
						    GInputStream              *source,
						    GOutputStreamSpliceFlags   flags,
						    int                        io_priority,
						    GCancellable              *cancellable,
						    GAsyncReadyCallback        callback,
						    gpointer                   data);
static gssize   g_output_stream_real_splice_finish (GOutputStream             *stream,
						    GAsyncResult              *result,
						    GError                   **error);
static void     g_output_stream_real_flush_async   (GOutputStream             *stream,
						    int                        io_priority,
						    GCancellable              *cancellable,
						    GAsyncReadyCallback        callback,
						    gpointer                   data);
static gboolean g_output_stream_real_flush_finish  (GOutputStream             *stream,
						    GAsyncResult              *result,
						    GError                   **error);
static void     g_output_stream_real_close_async   (GOutputStream             *stream,
						    int                        io_priority,
						    GCancellable              *cancellable,
						    GAsyncReadyCallback        callback,
						    gpointer                   data);
static gboolean g_output_stream_real_close_finish  (GOutputStream             *stream,
						    GAsyncResult              *result,
						    GError                   **error);
static gboolean _g_output_stream_close_internal    (GOutputStream             *stream,
                                                    GCancellable              *cancellable,
                                                    GError                   **error);

static void
g_output_stream_finalize (GObject *object)
{
  G_OBJECT_CLASS (g_output_stream_parent_class)->finalize (object);
}

static void
g_output_stream_dispose (GObject *object)
{
  GOutputStream *stream;

  stream = G_OUTPUT_STREAM (object);
  
  if (!stream->priv->closed)
    g_output_stream_close (stream, NULL, NULL);

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

static void
g_output_stream_class_init (GOutputStreamClass *klass)
{
  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
  
  g_type_class_add_private (klass, sizeof (GOutputStreamPrivate));
  
  gobject_class->finalize = g_output_stream_finalize;
  gobject_class->dispose = g_output_stream_dispose;

  klass->splice = g_output_stream_real_splice;
  
  klass->write_async = g_output_stream_real_write_async;
  klass->write_finish = g_output_stream_real_write_finish;
  klass->splice_async = g_output_stream_real_splice_async;
  klass->splice_finish = g_output_stream_real_splice_finish;
  klass->flush_async = g_output_stream_real_flush_async;
  klass->flush_finish = g_output_stream_real_flush_finish;
  klass->close_async = g_output_stream_real_close_async;
  klass->close_finish = g_output_stream_real_close_finish;
}

static void
g_output_stream_init (GOutputStream *stream)
{
  stream->priv = G_TYPE_INSTANCE_GET_PRIVATE (stream,
					      G_TYPE_OUTPUT_STREAM,
					      GOutputStreamPrivate);
}

/**
 * g_output_stream_write:
 * @stream: a #GOutputStream.
 * @buffer: (array length=count) (element-type guint8): the buffer containing the data to write. 
 * @count: the number of bytes to write
 * @cancellable: (allow-none): optional cancellable object
 * @error: location to store the error occurring, or %NULL to ignore
 *
 * Tries to write @count bytes from @buffer into the stream. Will block
 * during the operation.
 * 
 * If count is 0, returns 0 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 written to the stream is returned.
 * It is not an error if this is not the same as the requested size, as it
 * can happen e.g. on a partial I/O error, or if there is not enough
 * storage in the stream. All writes block until at least one byte
 * is written or an error occurs; 0 is never returned (unless
 * @count is 0).
 * 
 * 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.
 * 
 * Virtual: write_fn
 *
 * Return value: Number of bytes written, or -1 on error
 **/
gssize
g_output_stream_write (GOutputStream  *stream,
		       const void     *buffer,
		       gsize           count,
		       GCancellable   *cancellable,
		       GError        **error)
{
  GOutputStreamClass *class;
  gssize res;

  g_return_val_if_fail (G_IS_OUTPUT_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_OUTPUT_STREAM_GET_CLASS (stream);

  if (class->write_fn == NULL) 
    {
      g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
                           _("Output stream doesn't implement write"));
      return -1;
    }
  
  if (!g_output_stream_set_pending (stream, error))
    return -1;
  
  if (cancellable)
    g_cancellable_push_current (cancellable);
  
  res = class->write_fn (stream, buffer, count, cancellable, error);
  
  if (cancellable)
    g_cancellable_pop_current (cancellable);
  
  g_output_stream_clear_pending (stream);

  return res; 
}

/**
 * g_output_stream_write_all:
 * @stream: a #GOutputStream.
 * @buffer: (array length=count) (element-type guint8): the buffer containing the data to write. 
 * @count: the number of bytes to write
 * @bytes_written: (out): location to store the number of bytes that was 
 *     written to the stream
 * @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore.
 * @error: location to store the error occurring, or %NULL to ignore
 *
 * Tries to write @count bytes from @buffer into the stream. Will block
 * during the operation.
 * 
 * This function is similar to g_output_stream_write(), except it tries to
 * write as many bytes as requested, only stopping on an error.
 *
 * On a successful write of @count bytes, %TRUE is returned, and @bytes_written
 * is set to @count.
 * 
 * If there is an error during the operation %FALSE is returned and @error
 * is set to indicate the error status, @bytes_written is updated to contain
 * the number of bytes written into the stream before the error occurred.
 *
 * Return value: %TRUE on success, %FALSE if there was an error
 **/
gboolean
g_output_stream_write_all (GOutputStream  *stream,
			   const void     *buffer,
			   gsize           count,
			   gsize          *bytes_written,
			   GCancellable   *cancellable,
			   GError        **error)
{
  gsize _bytes_written;
  gssize res;

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

  _bytes_written = 0;
  while (_bytes_written < count)
    {
      res = g_output_stream_write (stream, (char *)buffer + _bytes_written, count - _bytes_written,
				   cancellable, error);
      if (res == -1)
	{
	  if (bytes_written)
	    *bytes_written = _bytes_written;
	  return FALSE;
	}
      
      if (res == 0)
	g_warning ("Write returned zero without error");

      _bytes_written += res;
    }
  
  if (bytes_written)
    *bytes_written = _bytes_written;

  return TRUE;
}

/**
 * g_output_stream_write_bytes:
 * @stream: a #GOutputStream.
 * @bytes: the #GBytes to write
 * @cancellable: (allow-none): optional cancellable object
 * @error: location to store the error occurring, or %NULL to ignore
 *
 * Tries to write the data from @bytes into the stream. Will block
 * during the operation.
 *
 * If @bytes is 0-length, returns 0 and does nothing. A #GBytes larger
 * than %G_MAXSSIZE will cause a %G_IO_ERROR_INVALID_ARGUMENT error.
 *
 * On success, the number of bytes written to the stream is returned.
 * It is not an error if this is not the same as the requested size, as it
 * can happen e.g. on a partial I/O error, or if there is not enough
 * storage in the stream. All writes block until at least one byte
 * is written or an error occurs; 0 is never returned (unless
 * the size of @bytes is 0).
 *
 * 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.
 *
 * Return value: Number of bytes written, or -1 on error
 **/
gssize
g_output_stream_write_bytes (GOutputStream  *stream,
			     GBytes         *bytes,
			     GCancellable   *cancellable,
			     GError        **error)
{
  gsize size;
  gconstpointer data;

  data = g_bytes_get_data (bytes, &size);

  return g_output_stream_write (stream,
                                data, size,
				cancellable,
				error);
}

/**
 * g_output_stream_flush:
 * @stream: a #GOutputStream.
 * @cancellable: (allow-none): optional cancellable object
 * @error: location to store the error occurring, or %NULL to ignore
 *
 * Forces a write of all user-space buffered data for the given
 * @stream. Will block during the operation. Closing the stream will
 * implicitly cause a flush.
 *
 * This function is optional for inherited classes.
 * 
 * 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.
 *
 * Return value: %TRUE on success, %FALSE on error
 **/
gboolean
g_output_stream_flush (GOutputStream  *stream,
                       GCancellable   *cancellable,
                       GError        **error)
{
  GOutputStreamClass *class;
  gboolean res;

  g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), FALSE);

  if (!g_output_stream_set_pending (stream, error))
    return FALSE;
  
  class = G_OUTPUT_STREAM_GET_CLASS (stream);

  res = TRUE;
  if (class->flush)
    {
      if (cancellable)
	g_cancellable_push_current (cancellable);
      
      res = class->flush (stream, cancellable, error);
      
      if (cancellable)
	g_cancellable_pop_current (cancellable);
    }
  
  g_output_stream_clear_pending (stream);

  return res;
}

/**
 * g_output_stream_splice:
 * @stream: a #GOutputStream.
 * @source: a #GInputStream.
 * @flags: a set of #GOutputStreamSpliceFlags.
 * @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore.
 * @error: a #GError location to store the error occurring, or %NULL to
 * ignore.
 *
 * Splices an input stream into an output stream.
 *
 * Returns: a #gssize containing the size of the data spliced, or
 *     -1 if an error occurred. Note that if the number of bytes
 *     spliced is greater than %G_MAXSSIZE, then that will be
 *     returned, and there is no way to determine the actual number
 *     of bytes spliced.
 **/
gssize
g_output_stream_splice (GOutputStream             *stream,
			GInputStream              *source,
			GOutputStreamSpliceFlags   flags,
			GCancellable              *cancellable,
			GError                   **error)
{
  GOutputStreamClass *class;
  gssize bytes_copied;

  g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), -1);
  g_return_val_if_fail (G_IS_INPUT_STREAM (source), -1);

  if (g_input_stream_is_closed (source))
    {
      g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_CLOSED,
                           _("Source stream is already closed"));
      return -1;
    }

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

  class = G_OUTPUT_STREAM_GET_CLASS (stream);

  if (cancellable)
    g_cancellable_push_current (cancellable);

  bytes_copied = class->splice (stream, source, flags, cancellable, error);

  if (cancellable)
    g_cancellable_pop_current (cancellable);

  g_output_stream_clear_pending (stream);

  return bytes_copied;
}

static gssize
g_output_stream_real_splice (GOutputStream             *stream,
                             GInputStream              *source,
                             GOutputStreamSpliceFlags   flags,
                             GCancellable              *cancellable,
                             GError                   **error)
{
  GOutputStreamClass *class = G_OUTPUT_STREAM_GET_CLASS (stream);
  gssize n_read, n_written;
  gsize bytes_copied;
  char buffer[8192], *p;
  gboolean res;

  bytes_copied = 0;
  if (class->write_fn == NULL)
    {
      g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
                           _("Output stream doesn't implement write"));
      res = FALSE;
      goto notsupported;
    }

  res = TRUE;
  do
    {
      n_read = g_input_stream_read (source, buffer, sizeof (buffer), cancellable, error);
      if (n_read == -1)
	{
	  res = FALSE;
	  break;
	}

      if (n_read == 0)
	break;

      p = buffer;
      while (n_read > 0)
	{
	  n_written = class->write_fn (stream, p, n_read, cancellable, error);
	  if (n_written == -1)
	    {
	      res = FALSE;
	      break;
	    }

	  p += n_written;
	  n_read -= n_written;
	  bytes_copied += n_written;
	}

      if (bytes_copied > G_MAXSSIZE)
	bytes_copied = G_MAXSSIZE;
    }
  while (res);

 notsupported:
  if (!res)
    error = NULL; /* Ignore further errors */

  if (flags & G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE)
    {
      /* Don't care about errors in source here */
      g_input_stream_close (source, cancellable, NULL);
    }

  if (flags & G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET)
    {
      /* But write errors on close are bad! */
      res = _g_output_stream_close_internal (stream, cancellable, error);
    }

  if (res)
    return bytes_copied;

  return -1;
}

/* Must always be called inside
 * g_output_stream_set_pending()/g_output_stream_clear_pending(). */
static gboolean
_g_output_stream_close_internal (GOutputStream  *stream,
                                 GCancellable   *cancellable,
                                 GError        **error)
{
  GOutputStreamClass *class;
  gboolean res;

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

  class = G_OUTPUT_STREAM_GET_CLASS (stream);

  stream->priv->closing = TRUE;

  if (cancellable)
    g_cancellable_push_current (cancellable);

  if (class->flush)
    res = class->flush (stream, cancellable, error);
  else
    res = TRUE;

  if (!res)
    {
      /* flushing caused the error that we want to return,
       * but we still want to close the underlying stream if possible
       */
      if (class->close_fn)
        class->close_fn (stream, cancellable, NULL);
    }
  else
    {
      res = TRUE;
      if (class->close_fn)
        res = class->close_fn (stream, cancellable, error);
    }

  if (cancellable)
    g_cancellable_pop_current (cancellable);

  stream->priv->closing = FALSE;
  stream->priv->closed = TRUE;

  return res;
}

/**
 * g_output_stream_close:
 * @stream: A #GOutputStream.
 * @cancellable: (allow-none): optional cancellable object
 * @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.
 *
 * Closing a stream will automatically flush any outstanding buffers in the
 * stream.
 *
 * 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, otherwise
 * there might be a loss of data as all data might not be written.
 * 
 * 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 there some streams
 * can use a faster close that doesn't block to e.g. check errors. On
 * cancellation (as with any error) there is no guarantee that all written
 * data will reach the target. 
 *
 * Return value: %TRUE on success, %FALSE on failure
 **/
gboolean
g_output_stream_close (GOutputStream  *stream,
		       GCancellable   *cancellable,
		       GError        **error)
{
  gboolean res;

  g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), FALSE);

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

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

  res = _g_output_stream_close_internal (stream, cancellable, error);

  g_output_stream_clear_pending (stream);
  
  return res;
}

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

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

typedef struct {
  gint io_priority;
  GCancellable *cancellable;
  GError *flush_error;
  gpointer user_data;
} CloseUserData;

static void
async_ready_close_callback_wrapper (GObject      *source_object,
                                    GAsyncResult *res,
                                    gpointer      user_data)
{
  GOutputStream *stream = G_OUTPUT_STREAM (source_object);
  CloseUserData *data = user_data;

  stream->priv->closing = FALSE;
  stream->priv->closed = TRUE;

  g_output_stream_clear_pending (stream);

  if (stream->priv->outstanding_callback)
    {
      if (data->flush_error != NULL)
        {
          GSimpleAsyncResult *err;

          err = g_simple_async_result_new_take_error (source_object,
                                                      stream->priv->outstanding_callback,
                                                      data->user_data,
                                                      data->flush_error);
          data->flush_error = NULL;

          (*stream->priv->outstanding_callback) (source_object,
                                                 G_ASYNC_RESULT (err),
                                                 data->user_data);
          g_object_unref (err);
        }
      else
        {
          (*stream->priv->outstanding_callback) (source_object,
                                                 res,
                                                 data->user_data);
        }
    }

  g_object_unref (stream);

  if (data->cancellable)
    g_object_unref (data->cancellable);

  if (data->flush_error)
    g_error_free (data->flush_error);

  g_slice_free (CloseUserData, data);
}

static void
async_ready_close_flushed_callback_wrapper (GObject      *source_object,
                                            GAsyncResult *res,
                                            gpointer      user_data)
{
  GOutputStream *stream = G_OUTPUT_STREAM (source_object);
  GOutputStreamClass *class;
  CloseUserData *data = user_data;
  GSimpleAsyncResult *simple;

  /* propagate the possible error */
  if (G_IS_SIMPLE_ASYNC_RESULT (res))
    {
      simple = G_SIMPLE_ASYNC_RESULT (res);
      g_simple_async_result_propagate_error (simple, &data->flush_error);
    }

  class = G_OUTPUT_STREAM_GET_CLASS (stream);

  /* we still close, even if there was a flush error */
  class->close_async (stream, data->io_priority, data->cancellable,
		      async_ready_close_callback_wrapper, user_data);
}

/**
 * g_output_stream_write_async:
 * @stream: A #GOutputStream.
 * @buffer: (array length=count) (element-type guint8): the buffer containing the data to write. 
 * @count: the number of bytes to write
 * @io_priority: the 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 write of @count bytes from @buffer into 
 * the stream. When the operation is finished @callback will be called.
 * You can then call g_output_stream_write_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 written 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. on a partial I/O error, 
 * but generally we try to write as many bytes as requested. 
 *
 * You are guaranteed that this method will never fail with
 * %G_IO_ERROR_WOULD_BLOCK - if @stream can't accept more data, the
 * method will just wait until this changes.
 *
 * 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.
 *
 * For the synchronous, blocking version of this function, see 
 * g_output_stream_write().
 **/
void
g_output_stream_write_async (GOutputStream       *stream,
			     const void          *buffer,
			     gsize                count,
			     int                  io_priority,
			     GCancellable        *cancellable,
			     GAsyncReadyCallback  callback,
			     gpointer             user_data)
{
  GOutputStreamClass *class;
  GSimpleAsyncResult *simple;
  GError *error = NULL;

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

  if (count == 0)
    {
      simple = g_simple_async_result_new (G_OBJECT (stream),
					  callback,
					  user_data,
					  g_output_stream_write_async);
      g_simple_async_result_complete_in_idle (simple);
      g_object_unref (simple);
      return;
    }

  if (((gssize) count) < 0)
    {
      g_simple_async_report_error_in_idle (G_OBJECT (stream),
					   callback,
					   user_data,
					   G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
					   _("Too large count value passed to %s"),
					   G_STRFUNC);
      return;
    }

  if (!g_output_stream_set_pending (stream, &error))
    {
      g_simple_async_report_take_gerror_in_idle (G_OBJECT (stream),
					    callback,
					    user_data,
					    error);
      return;
    }
  
  class = G_OUTPUT_STREAM_GET_CLASS (stream);

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

/**
 * g_output_stream_write_finish:
 * @stream: a #GOutputStream.
 * @result: a #GAsyncResult.
 * @error: a #GError location to store the error occurring, or %NULL to 
 * ignore.
 * 
 * Finishes a stream write operation.
 * 
 * Returns: a #gssize containing the number of bytes written to the stream.
 **/
gssize
g_output_stream_write_finish (GOutputStream  *stream,
                              GAsyncResult   *result,
                              GError        **error)
{
  GSimpleAsyncResult *simple;
  GOutputStreamClass *class;

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

  if (G_IS_SIMPLE_ASYNC_RESULT (result))
    {
      simple = G_SIMPLE_ASYNC_RESULT (result);
      if (g_simple_async_result_propagate_error (simple, error))
	return -1;

      /* Special case writes of 0 bytes */
      if (g_simple_async_result_get_source_tag (simple) == g_output_stream_write_async)
	return 0;
    }
  
  class = G_OUTPUT_STREAM_GET_CLASS (stream);
  return class->write_finish (stream, result, error);
}

static void
write_bytes_callback (GObject      *stream,
		      GAsyncResult *result,
		      gpointer      user_data)
{
  GSimpleAsyncResult *simple = user_data;
  GError *error = NULL;
  gssize nwrote;

  nwrote = g_output_stream_write_finish (G_OUTPUT_STREAM (stream),
					 result, &error);
  if (nwrote == -1)
    g_simple_async_result_take_error (simple, error);
  else
    g_simple_async_result_set_op_res_gssize (simple, nwrote);
  g_simple_async_result_complete (simple);
  g_object_unref (simple);
}

/**
 * g_output_stream_write_bytes_async:
 * @stream: A #GOutputStream.
 * @bytes: The bytes to write
 * @io_priority: the 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 write of the data in @bytes to the stream.
 * When the operation is finished @callback will be called. You can
 * then call g_output_stream_write_bytes_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 #GBytes larger than %G_MAXSSIZE will cause a
 * %G_IO_ERROR_INVALID_ARGUMENT error.
 *
 * On success, the number of bytes written 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. on a partial I/O error,
 * but generally we try to write as many bytes as requested.
 *
 * You are guaranteed that this method will never fail with
 * %G_IO_ERROR_WOULD_BLOCK - if @stream can't accept more data, the
 * method will just wait until this changes.
 *
 * 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.
 *
 * For the synchronous, blocking version of this function, see
 * g_output_stream_write_bytes().
 **/
void
g_output_stream_write_bytes_async (GOutputStream       *stream,
				   GBytes              *bytes,
				   int                  io_priority,
				   GCancellable        *cancellable,
				   GAsyncReadyCallback  callback,
				   gpointer             user_data)
{
  GSimpleAsyncResult *simple;
  gsize size;
  gconstpointer data;

  data = g_bytes_get_data (bytes, &size);

  simple = g_simple_async_result_new (G_OBJECT (stream),
				      callback, user_data,
				      g_output_stream_write_bytes_async);
  g_simple_async_result_set_op_res_gpointer (simple, g_bytes_ref (bytes),
					     (GDestroyNotify) g_bytes_unref);

  g_output_stream_write_async (stream,
                               data, size,
                               io_priority,
                               cancellable,
                               write_bytes_callback,
                               simple);
}

/**
 * g_output_stream_write_bytes_finish:
 * @stream: a #GOutputStream.
 * @result: a #GAsyncResult.
 * @error: a #GError location to store the error occurring, or %NULL to
 * ignore.
 *
 * Finishes a stream write-from-#GBytes operation.
 *
 * Returns: a #gssize containing the number of bytes written to the stream.
 **/
gssize
g_output_stream_write_bytes_finish (GOutputStream  *stream,
				    GAsyncResult   *result,
				    GError        **error)
{
  GSimpleAsyncResult *simple;

  g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), -1);
  g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (stream), g_output_stream_write_bytes_async), -1);

  simple = G_SIMPLE_ASYNC_RESULT (result);
  if (g_simple_async_result_propagate_error (simple, error))
    return -1;
  return g_simple_async_result_get_op_res_gssize (simple);
}

typedef struct {
  GInputStream *source;
  gpointer user_data;
  GAsyncReadyCallback callback;
} SpliceUserData;

static void
async_ready_splice_callback_wrapper (GObject      *source_object,
                                     GAsyncResult *res,
                                     gpointer     _data)
{
  GOutputStream *stream = G_OUTPUT_STREAM (source_object);
  SpliceUserData *data = _data;
  
  g_output_stream_clear_pending (stream);
  
  if (data->callback)
    (*data->callback) (source_object, res, data->user_data);
  
  g_object_unref (stream);
  g_object_unref (data->source);
  g_free (data);
}

/**
 * g_output_stream_splice_async:
 * @stream: a #GOutputStream.
 * @source: a #GInputStream. 
 * @flags: a set of #GOutputStreamSpliceFlags.
 * @io_priority: the io priority of the request.
 * @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore. 
 * @callback: (scope async): a #GAsyncReadyCallback. 
 * @user_data: (closure): user data passed to @callback.
 * 
 * Splices a stream asynchronously.
 * When the operation is finished @callback will be called.
 * You can then call g_output_stream_splice_finish() to get the 
 * result of the operation.
 *
 * For the synchronous, blocking version of this function, see 
 * g_output_stream_splice().
 **/
void
g_output_stream_splice_async (GOutputStream            *stream,
			      GInputStream             *source,
			      GOutputStreamSpliceFlags  flags,
			      int                       io_priority,
			      GCancellable             *cancellable,
			      GAsyncReadyCallback       callback,
			      gpointer                  user_data)
{
  GOutputStreamClass *class;
  SpliceUserData *data;
  GError *error = NULL;

  g_return_if_fail (G_IS_OUTPUT_STREAM (stream));
  g_return_if_fail (G_IS_INPUT_STREAM (source));

  if (g_input_stream_is_closed (source))
    {
      g_simple_async_report_error_in_idle (G_OBJECT (stream),
					   callback,
					   user_data,
					   G_IO_ERROR, G_IO_ERROR_CLOSED,
					   _("Source stream is already closed"));
      return;
    }
  
  if (!g_output_stream_set_pending (stream, &error))
    {
      g_simple_async_report_take_gerror_in_idle (G_OBJECT (stream),
					    callback,
					    user_data,
					    error);
      return;
    }

  class = G_OUTPUT_STREAM_GET_CLASS (stream);

  data = g_new0 (SpliceUserData, 1);
  data->callback = callback;
  data->user_data = user_data;
  data->source = g_object_ref (source);
  
  g_object_ref (stream);
  class->splice_async (stream, source, flags, io_priority, cancellable,
		      async_ready_splice_callback_wrapper, data);
}

/**
 * g_output_stream_splice_finish:
 * @stream: a #GOutputStream.
 * @result: a #GAsyncResult.
 * @error: a #GError location to store the error occurring, or %NULL to 
 * ignore.
 *
 * Finishes an asynchronous stream splice operation.
 * 
 * Returns: a #gssize of the number of bytes spliced. Note that if the
 *     number of bytes spliced is greater than %G_MAXSSIZE, then that
 *     will be returned, and there is no way to determine the actual
 *     number of bytes spliced.
 **/
gssize
g_output_stream_splice_finish (GOutputStream  *stream,
			       GAsyncResult   *result,
			       GError        **error)
{
  GSimpleAsyncResult *simple;
  GOutputStreamClass *class;

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

  if (G_IS_SIMPLE_ASYNC_RESULT (result))
    {
      simple = G_SIMPLE_ASYNC_RESULT (result);
      if (g_simple_async_result_propagate_error (simple, error))
	return -1;
    }
  
  class = G_OUTPUT_STREAM_GET_CLASS (stream);
  return class->splice_finish (stream, result, error);
}

/**
 * g_output_stream_flush_async:
 * @stream: a #GOutputStream.
 * @io_priority: the io priority of the request.
 * @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore.
 * @callback: (scope async): a #GAsyncReadyCallback to call when the request is satisfied
 * @user_data: (closure): the data to pass to callback function
 * 
 * Forces an asynchronous write of all user-space buffered data for
 * the given @stream.
 * For behaviour details see g_output_stream_flush().
 *
 * When the operation is finished @callback will be 
 * called. You can then call g_output_stream_flush_finish() to get the 
 * result of the operation.
 **/
void
g_output_stream_flush_async (GOutputStream       *stream,
                             int                  io_priority,
                             GCancellable        *cancellable,
                             GAsyncReadyCallback  callback,
                             gpointer             user_data)
{
  GOutputStreamClass *class;
  GSimpleAsyncResult *simple;
  GError *error = NULL;

  g_return_if_fail (G_IS_OUTPUT_STREAM (stream));

  if (!g_output_stream_set_pending (stream, &error))
    {
      g_simple_async_report_take_gerror_in_idle (G_OBJECT (stream),
					    callback,
					    user_data,
					    error);
      return;
    }

  stream->priv->outstanding_callback = callback;
  g_object_ref (stream);

  class = G_OUTPUT_STREAM_GET_CLASS (stream);
  
  if (class->flush_async == NULL)
    {
      simple = g_simple_async_result_new (G_OBJECT (stream),
					  async_ready_callback_wrapper,
					  user_data,
					  g_output_stream_flush_async);
      g_simple_async_result_complete_in_idle (simple);
      g_object_unref (simple);
      return;
    }
      
  class->flush_async (stream, io_priority, cancellable,
		      async_ready_callback_wrapper, user_data);
}

/**
 * g_output_stream_flush_finish:
 * @stream: a #GOutputStream.
 * @result: a GAsyncResult.
 * @error: a #GError location to store the error occurring, or %NULL to 
 * ignore.
 * 
 * Finishes flushing an output stream.
 * 
 * Returns: %TRUE if flush operation succeeded, %FALSE otherwise.
 **/
gboolean
g_output_stream_flush_finish (GOutputStream  *stream,
                              GAsyncResult   *result,
                              GError        **error)
{
  GSimpleAsyncResult *simple;
  GOutputStreamClass *klass;

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

  if (G_IS_SIMPLE_ASYNC_RESULT (result))
    {
      simple = G_SIMPLE_ASYNC_RESULT (result);
      if (g_simple_async_result_propagate_error (simple, error))
	return FALSE;

      /* Special case default implementation */
      if (g_simple_async_result_get_source_tag (simple) == g_output_stream_flush_async)
	return TRUE;
    }

  klass = G_OUTPUT_STREAM_GET_CLASS (stream);
  return klass->flush_finish (stream, result, error);
}


/**
 * g_output_stream_close_async:
 * @stream: A #GOutputStream.
 * @io_priority: the 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 close of the stream, releasing resources 
 * related to it. When the operation is finished @callback will be 
 * called. You can then call g_output_stream_close_finish() to get 
 * the result of the operation.
 *
 * For behaviour details see g_output_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_output_stream_close_async (GOutputStream       *stream,
                             int                  io_priority,
                             GCancellable        *cancellable,
                             GAsyncReadyCallback  callback,
                             gpointer             user_data)
{
  GOutputStreamClass *class;
  GSimpleAsyncResult *simple;
  GError *error = NULL;
  CloseUserData *data;

  g_return_if_fail (G_IS_OUTPUT_STREAM (stream));
  
  if (stream->priv->closed)
    {
      simple = g_simple_async_result_new (G_OBJECT (stream),
					  callback,
					  user_data,
					  g_output_stream_close_async);
      g_simple_async_result_complete_in_idle (simple);
      g_object_unref (simple);
      return;
    }

  if (!g_output_stream_set_pending (stream, &error))
    {
      g_simple_async_report_take_gerror_in_idle (G_OBJECT (stream),
					    callback,
					    user_data,
					    error);
      return;
    }
  
  class = G_OUTPUT_STREAM_GET_CLASS (stream);
  stream->priv->closing = TRUE;
  stream->priv->outstanding_callback = callback;
  g_object_ref (stream);

  data = g_slice_new0 (CloseUserData);

  if (cancellable != NULL)
    data->cancellable = g_object_ref (cancellable);

  data->io_priority = io_priority;
  data->user_data = user_data;

  /* Call close_async directly if there is no need to flush, or if the flush
     can be done sync (in the output stream async close thread) */
  if (class->flush_async == NULL ||
      (class->flush_async == g_output_stream_real_flush_async &&
       (class->flush == NULL || class->close_async == g_output_stream_real_close_async)))
    {
      class->close_async (stream, io_priority, cancellable,
                          async_ready_close_callback_wrapper, data);
    }
  else
    {
      /* First do an async flush, then do the async close in the callback
         wrapper (see async_ready_close_flushed_callback_wrapper) */
      class->flush_async (stream, io_priority, cancellable,
                          async_ready_close_flushed_callback_wrapper, data);
    }
}

/**
 * g_output_stream_close_finish:
 * @stream: a #GOutputStream.
 * @result: a #GAsyncResult.
 * @error: a #GError location to store the error occurring, or %NULL to 
 * ignore.
 * 
 * Closes an output stream.
 * 
 * Returns: %TRUE if stream was successfully closed, %FALSE otherwise.
 **/
gboolean
g_output_stream_close_finish (GOutputStream  *stream,
                              GAsyncResult   *result,
                              GError        **error)
{
  GSimpleAsyncResult *simple;
  GOutputStreamClass *class;

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

  if (G_IS_SIMPLE_ASYNC_RESULT (result))
    {
      simple = G_SIMPLE_ASYNC_RESULT (result);
      if (g_simple_async_result_propagate_error (simple, error))
	return FALSE;

      /* Special case already closed */
      if (g_simple_async_result_get_source_tag (simple) == g_output_stream_close_async)
	return TRUE;
    }

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

/**
 * g_output_stream_is_closed:
 * @stream: a #GOutputStream.
 * 
 * Checks if an output stream has already been closed.
 * 
 * Returns: %TRUE if @stream is closed. %FALSE otherwise. 
 **/
gboolean
g_output_stream_is_closed (GOutputStream *stream)
{
  g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), TRUE);
  
  return stream->priv->closed;
}

/**
 * g_output_stream_is_closing:
 * @stream: a #GOutputStream.
 *
 * Checks if an output stream is being closed. This can be
 * used inside e.g. a flush implementation to see if the
 * flush (or other i/o operation) is called from within
 * the closing operation.
 *
 * Returns: %TRUE if @stream is being closed. %FALSE otherwise.
 *
 * Since: 2.24
 **/
gboolean
g_output_stream_is_closing (GOutputStream *stream)
{
  g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), TRUE);

  return stream->priv->closing;
}

/**
 * g_output_stream_has_pending:
 * @stream: a #GOutputStream.
 * 
 * Checks if an ouput stream has pending actions.
 * 
 * Returns: %TRUE if @stream has pending actions. 
 **/
gboolean
g_output_stream_has_pending (GOutputStream *stream)
{
  g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), FALSE);
  
  return stream->priv->pending;
}

/**
 * g_output_stream_set_pending:
 * @stream: a #GOutputStream.
 * @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.
 *
 * Return value: %TRUE if pending was previously unset and is now set.
 **/
gboolean
g_output_stream_set_pending (GOutputStream *stream,
			     GError **error)
{
  g_return_val_if_fail (G_IS_OUTPUT_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_output_stream_clear_pending:
 * @stream: output stream
 * 
 * Clears the pending flag on @stream.
 **/
void
g_output_stream_clear_pending (GOutputStream *stream)
{
  g_return_if_fail (G_IS_OUTPUT_STREAM (stream));
  
  stream->priv->pending = FALSE;
}


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

typedef struct {
  const void         *buffer;
  gsize               count_requested;
  gssize              count_written;

  GCancellable       *cancellable;
  gint                io_priority;
  gboolean            need_idle;
} WriteData;

static void
free_write_data (WriteData *op)
{
  if (op->cancellable)
    g_object_unref (op->cancellable);
  g_slice_free (WriteData, op);
}

static void
write_async_thread (GSimpleAsyncResult *res,
                    GObject            *object,
                    GCancellable       *cancellable)
{
  WriteData *op;
  GOutputStreamClass *class;
  GError *error = NULL;

  class = G_OUTPUT_STREAM_GET_CLASS (object);
  op = g_simple_async_result_get_op_res_gpointer (res);
  op->count_written = class->write_fn (G_OUTPUT_STREAM (object), op->buffer, op->count_requested,
				       cancellable, &error);
  if (op->count_written == -1)
    g_simple_async_result_take_error (res, error);
}

static void write_async_pollable (GPollableOutputStream *stream,
				  GSimpleAsyncResult    *result);

static gboolean
write_async_pollable_ready (GPollableOutputStream *stream,
			    gpointer               user_data)
{
  GSimpleAsyncResult *result = user_data;

  write_async_pollable (stream, result);
  return FALSE;
}

static void
write_async_pollable (GPollableOutputStream *stream,
		      GSimpleAsyncResult    *result)
{
  GError *error = NULL;
  WriteData *op = g_simple_async_result_get_op_res_gpointer (result);

  if (g_cancellable_set_error_if_cancelled (op->cancellable, &error))
    op->count_written = -1;
  else
    {
      op->count_written = G_POLLABLE_OUTPUT_STREAM_GET_INTERFACE (stream)->
	write_nonblocking (stream, op->buffer, op->count_requested, &error);
    }

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

      g_error_free (error);
      op->need_idle = FALSE;

      source = g_pollable_output_stream_create_source (stream, op->cancellable);
      g_source_set_callback (source,
			     (GSourceFunc) write_async_pollable_ready,
			     g_object_ref (result), g_object_unref);
      g_source_set_priority (source, op->io_priority);
      g_source_attach (source, g_main_context_get_thread_default ());
      g_source_unref (source);
      return;
    }

  if (op->count_written == -1)
    g_simple_async_result_take_error (result, error);

  if (op->need_idle)
    g_simple_async_result_complete_in_idle (result);
  else
    g_simple_async_result_complete (result);
}

static void
g_output_stream_real_write_async (GOutputStream       *stream,
                                  const void          *buffer,
                                  gsize                count,
                                  int                  io_priority,
                                  GCancellable        *cancellable,
                                  GAsyncReadyCallback  callback,
                                  gpointer             user_data)
{
  GSimpleAsyncResult *res;
  WriteData *op;

  op = g_slice_new0 (WriteData);
  res = g_simple_async_result_new (G_OBJECT (stream), callback, user_data, g_output_stream_real_write_async);
  g_simple_async_result_set_op_res_gpointer (res, op, (GDestroyNotify) free_write_data);
  op->buffer = buffer;
  op->count_requested = count;
  op->cancellable = cancellable ? g_object_ref (cancellable) : NULL;
  op->io_priority = io_priority;
  op->need_idle = TRUE;
  
  if (G_IS_POLLABLE_OUTPUT_STREAM (stream) &&
      g_pollable_output_stream_can_poll (G_POLLABLE_OUTPUT_STREAM (stream)))
    write_async_pollable (G_POLLABLE_OUTPUT_STREAM (stream), res);
  else
    g_simple_async_result_run_in_thread (res, write_async_thread, io_priority, cancellable);
  g_object_unref (res);
}

static gssize
g_output_stream_real_write_finish (GOutputStream  *stream,
                                   GAsyncResult   *result,
                                   GError        **error)
{
  GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
  WriteData *op;

  g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_output_stream_real_write_async);
  op = g_simple_async_result_get_op_res_gpointer (simple);
  return op->count_written;
}

typedef struct {
  GInputStream *source;
  GOutputStreamSpliceFlags flags;
  gssize bytes_copied;
} SpliceData;

static void
splice_async_thread (GSimpleAsyncResult *result,
                     GObject            *object,
                     GCancellable       *cancellable)
{
  SpliceData *op;
  GOutputStreamClass *class;
  GError *error = NULL;
  GOutputStream *stream;

  stream = G_OUTPUT_STREAM (object);
  class = G_OUTPUT_STREAM_GET_CLASS (object);
  op = g_simple_async_result_get_op_res_gpointer (result);
  
  op->bytes_copied = class->splice (stream,
				    op->source,
				    op->flags,
				    cancellable,
				    &error);
  if (op->bytes_copied == -1)
    g_simple_async_result_take_error (result, error);
}

static void
g_output_stream_real_splice_async (GOutputStream             *stream,
                                   GInputStream              *source,
                                   GOutputStreamSpliceFlags   flags,
                                   int                        io_priority,
                                   GCancellable              *cancellable,
                                   GAsyncReadyCallback        callback,
                                   gpointer                   user_data)
{
  GSimpleAsyncResult *res;
  SpliceData *op;

  op = g_new0 (SpliceData, 1);
  res = g_simple_async_result_new (G_OBJECT (stream), callback, user_data, g_output_stream_real_splice_async);
  g_simple_async_result_set_op_res_gpointer (res, op, g_free);
  op->flags = flags;
  op->source = source;

  /* TODO: In the case where both source and destintion have
     non-threadbased async calls we can use a true async copy here */
  
  g_simple_async_result_run_in_thread (res, splice_async_thread, io_priority, cancellable);
  g_object_unref (res);
}

static gssize
g_output_stream_real_splice_finish (GOutputStream  *stream,
                                    GAsyncResult   *result,
                                    GError        **error)
{
  GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
  SpliceData *op;

  g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_output_stream_real_splice_async);
  op = g_simple_async_result_get_op_res_gpointer (simple);
  return op->bytes_copied;
}


static void
flush_async_thread (GSimpleAsyncResult *res,
                    GObject            *object,
                    GCancellable       *cancellable)
{
  GOutputStreamClass *class;
  gboolean result;
  GError *error = NULL;

  class = G_OUTPUT_STREAM_GET_CLASS (object);
  result = TRUE;
  if (class->flush)
    result = class->flush (G_OUTPUT_STREAM (object), cancellable, &error);

  if (!result)
    g_simple_async_result_take_error (res, error);
}

static void
g_output_stream_real_flush_async (GOutputStream       *stream,
                                  int                  io_priority,
                                  GCancellable        *cancellable,
                                  GAsyncReadyCallback  callback,
                                  gpointer             user_data)
{
  GSimpleAsyncResult *res;

  res = g_simple_async_result_new (G_OBJECT (stream), callback, user_data, g_output_stream_real_write_async);
  
  g_simple_async_result_run_in_thread (res, flush_async_thread, io_priority, cancellable);
  g_object_unref (res);
}

static gboolean
g_output_stream_real_flush_finish (GOutputStream  *stream,
                                   GAsyncResult   *result,
                                   GError        **error)
{
  return TRUE;
}

static void
close_async_thread (GSimpleAsyncResult *res,
                    GObject            *object,
                    GCancellable       *cancellable)
{
  GOutputStreamClass *class;
  GError *error = NULL;
  gboolean result = TRUE;

  class = G_OUTPUT_STREAM_GET_CLASS (object);

  /* Do a flush here if there is a flush function, and we did not have to do
     an async flush before (see g_output_stream_close_async) */
  if (class->flush != NULL &&
      (class->flush_async == NULL ||
       class->flush_async == g_output_stream_real_flush_async))
    {
      result = class->flush (G_OUTPUT_STREAM (object), cancellable, &error);
    }

  /* Auto handling of cancelation disabled, and ignore
     cancellation, since we want to close things anyway, although
     possibly in a quick-n-dirty way. At least we never want to leak
     open handles */
  
  if (class->close_fn)
    {
      /* Make sure to close, even if the flush failed (see sync close) */
      if (!result)
        class->close_fn (G_OUTPUT_STREAM (object), cancellable, NULL);
      else
        result = class->close_fn (G_OUTPUT_STREAM (object), cancellable, &error);

      if (!result)
        g_simple_async_result_take_error (res, error);
    }
}

static void
g_output_stream_real_close_async (GOutputStream       *stream,
                                  int                  io_priority,
                                  GCancellable        *cancellable,
                                  GAsyncReadyCallback  callback,
                                  gpointer             user_data)
{
  GSimpleAsyncResult *res;
  
  res = g_simple_async_result_new (G_OBJECT (stream), callback, user_data, g_output_stream_real_close_async);

  g_simple_async_result_set_handle_cancellation (res, FALSE);
  
  g_simple_async_result_run_in_thread (res, close_async_thread, io_priority, cancellable);
  g_object_unref (res);
}

static gboolean
g_output_stream_real_close_finish (GOutputStream  *stream,
                                   GAsyncResult   *result,
                                   GError        **error)
{
  GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
  g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_output_stream_real_close_async);
  return TRUE;
}
