/* GIO - GLib Input, Output and Streaming Library
 *
 * Copyright (C) 2010 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.1 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/>.
 */

#include "config.h"

#include <errno.h>

#include "gpollableoutputstream.h"
#include "gasynchelper.h"
#include "gfiledescriptorbased.h"
#include "glibintl.h"

/**
 * SECTION:gpollableoutputstream
 * @short_description: Interface for pollable output streams
 * @include: gio/gio.h
 * @see_also: #GOutputStream, #GFileDescriptorBased, #GPollableInputStream
 *
 * #GPollableOutputStream is implemented by #GOutputStreams that
 * can be polled for readiness to write. This can be used when
 * interfacing with a non-GIO API that expects
 * UNIX-file-descriptor-style asynchronous I/O rather than GIO-style.
 *
 * Since: 2.28
 */

G_DEFINE_INTERFACE (GPollableOutputStream, g_pollable_output_stream, G_TYPE_OUTPUT_STREAM)

static gboolean g_pollable_output_stream_default_can_poll           (GPollableOutputStream *stream);
static gssize   g_pollable_output_stream_default_write_nonblocking  (GPollableOutputStream  *stream,
								     const void             *buffer,
								     gsize                   count,
								     GError                **error);
static GPollableReturn g_pollable_output_stream_default_writev_nonblocking (GPollableOutputStream  *stream,
									    const GOutputVector    *vectors,
									    gsize                   n_vectors,
									    gsize                  *bytes_written,
									    GError                **error);

static void
g_pollable_output_stream_default_init (GPollableOutputStreamInterface *iface)
{
  iface->can_poll           = g_pollable_output_stream_default_can_poll;
  iface->write_nonblocking  = g_pollable_output_stream_default_write_nonblocking;
  iface->writev_nonblocking = g_pollable_output_stream_default_writev_nonblocking;
}

static gboolean
g_pollable_output_stream_default_can_poll (GPollableOutputStream *stream)
{
  return TRUE;
}

/**
 * g_pollable_output_stream_can_poll:
 * @stream: a #GPollableOutputStream.
 *
 * Checks if @stream is actually pollable. Some classes may implement
 * #GPollableOutputStream but have only certain instances of that
 * class be pollable. If this method returns %FALSE, then the behavior
 * of other #GPollableOutputStream methods is undefined.
 *
 * For any given stream, the value returned by this method is constant;
 * a stream cannot switch from pollable to non-pollable or vice versa.
 *
 * Returns: %TRUE if @stream is pollable, %FALSE if not.
 *
 * Since: 2.28
 */
gboolean
g_pollable_output_stream_can_poll (GPollableOutputStream *stream)
{
  g_return_val_if_fail (G_IS_POLLABLE_OUTPUT_STREAM (stream), FALSE);

  return G_POLLABLE_OUTPUT_STREAM_GET_INTERFACE (stream)->can_poll (stream);
}

/**
 * g_pollable_output_stream_is_writable:
 * @stream: a #GPollableOutputStream.
 *
 * Checks if @stream can be written.
 *
 * Note that some stream types may not be able to implement this 100%
 * reliably, and it is possible that a call to g_output_stream_write()
 * after this returns %TRUE would still block. To guarantee
 * non-blocking behavior, you should always use
 * g_pollable_output_stream_write_nonblocking(), which will return a
 * %G_IO_ERROR_WOULD_BLOCK error rather than blocking.
 *
 * Returns: %TRUE if @stream is writable, %FALSE if not. If an error
 *   has occurred on @stream, this will result in
 *   g_pollable_output_stream_is_writable() returning %TRUE, and the
 *   next attempt to write will return the error.
 *
 * Since: 2.28
 */
gboolean
g_pollable_output_stream_is_writable (GPollableOutputStream *stream)
{
  g_return_val_if_fail (G_IS_POLLABLE_OUTPUT_STREAM (stream), FALSE);

  return G_POLLABLE_OUTPUT_STREAM_GET_INTERFACE (stream)->is_writable (stream);
}

/**
 * g_pollable_output_stream_create_source:
 * @stream: a #GPollableOutputStream.
 * @cancellable: (nullable): a #GCancellable, or %NULL
 *
 * Creates a #GSource that triggers when @stream can be written, or
 * @cancellable is triggered or an error occurs. The callback on the
 * source is of the #GPollableSourceFunc type.
 *
 * As with g_pollable_output_stream_is_writable(), it is possible that
 * the stream may not actually be writable even after the source
 * triggers, so you should use g_pollable_output_stream_write_nonblocking()
 * rather than g_output_stream_write() from the callback.
 *
 * Returns: (transfer full): a new #GSource
 *
 * Since: 2.28
 */
GSource *
g_pollable_output_stream_create_source (GPollableOutputStream *stream,
					GCancellable          *cancellable)
{
  g_return_val_if_fail (G_IS_POLLABLE_OUTPUT_STREAM (stream), NULL);

  return G_POLLABLE_OUTPUT_STREAM_GET_INTERFACE (stream)->
	  create_source (stream, cancellable);
}

static gssize
g_pollable_output_stream_default_write_nonblocking (GPollableOutputStream  *stream,
						    const void             *buffer,
						    gsize                   count,
						    GError                **error)
{
  if (!g_pollable_output_stream_is_writable (stream))
    {
      g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK,
                           g_strerror (EAGAIN));
      return -1;
    }

  return G_OUTPUT_STREAM_GET_CLASS (stream)->
    write_fn (G_OUTPUT_STREAM (stream), buffer, count, NULL, error);
}

static GPollableReturn
g_pollable_output_stream_default_writev_nonblocking (GPollableOutputStream  *stream,
						     const GOutputVector    *vectors,
						     gsize                   n_vectors,
						     gsize                  *bytes_written,
						     GError                **error)
{
  gsize _bytes_written = 0;
  GPollableOutputStreamInterface *iface = G_POLLABLE_OUTPUT_STREAM_GET_INTERFACE (stream);
  gsize i;
  GError *err = NULL;

  for (i = 0; i < n_vectors; i++)
    {
      gssize res;

      /* Would we overflow here? In that case simply return and let the caller
       * handle this like a short write */
      if (_bytes_written > G_MAXSIZE - vectors[i].size)
        break;

      res = iface->write_nonblocking (stream, vectors[i].buffer, vectors[i].size, &err);
      if (res == -1)
        {
          if (bytes_written)
            *bytes_written = _bytes_written;

          /* If something was written already we handle this like a short
           * write and assume that the next call would either give the same
           * error again or successfully finish writing without errors or data
           * loss
           */
          if (_bytes_written > 0)
            {
              g_clear_error (&err);
              return G_POLLABLE_RETURN_OK;
            }
          else if (g_error_matches (err, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK))
            {
              g_clear_error (&err);
              return G_POLLABLE_RETURN_WOULD_BLOCK;
            }
          else
            {
              g_propagate_error (error, err);
              return G_POLLABLE_RETURN_FAILED;
            }
        }

      _bytes_written += res;
      /* if we had a short write break the loop here */
      if (res < vectors[i].size)
        break;
    }

  if (bytes_written)
    *bytes_written = _bytes_written;

  return G_POLLABLE_RETURN_OK;
}

/**
 * g_pollable_output_stream_write_nonblocking:
 * @stream: a #GPollableOutputStream
 * @buffer: (array length=count) (element-type guint8): a buffer to write
 *     data from
 * @count: the number of bytes you want to write
 * @cancellable: (nullable): a #GCancellable, or %NULL
 * @error: #GError for error reporting, or %NULL to ignore.
 *
 * Attempts to write up to @count bytes from @buffer to @stream, as
 * with g_output_stream_write(). If @stream is not currently writable,
 * this will immediately return %G_IO_ERROR_WOULD_BLOCK, and you can
 * use g_pollable_output_stream_create_source() to create a #GSource
 * that will be triggered when @stream is writable.
 *
 * Note that since this method never blocks, you cannot actually
 * use @cancellable to cancel it. However, it will return an error
 * if @cancellable has already been cancelled when you call, which
 * may happen if you call this method after a source triggers due
 * to having been cancelled.
 *
 * Also note that if %G_IO_ERROR_WOULD_BLOCK is returned some underlying
 * transports like D/TLS require that you re-send the same @buffer and
 * @count in the next write call.
 *
 * Virtual: write_nonblocking
 * Returns: the number of bytes written, or -1 on error (including
 *   %G_IO_ERROR_WOULD_BLOCK).
 */
gssize
g_pollable_output_stream_write_nonblocking (GPollableOutputStream  *stream,
					    const void             *buffer,
					    gsize                   count,
					    GCancellable           *cancellable,
					    GError                **error)
{
  gssize res;

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

  if (g_cancellable_set_error_if_cancelled (cancellable, error))
    return -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;
    }

  if (cancellable)
    g_cancellable_push_current (cancellable);

  res = G_POLLABLE_OUTPUT_STREAM_GET_INTERFACE (stream)->
    write_nonblocking (stream, buffer, count, error);

  if (cancellable)
    g_cancellable_pop_current (cancellable);

  return res;
}

/**
 * g_pollable_output_stream_writev_nonblocking:
 * @stream: a #GPollableOutputStream
 * @vectors: (array length=n_vectors): the buffer containing the #GOutputVectors to write.
 * @n_vectors: the number of vectors to write
 * @bytes_written: (out) (optional): location to store the number of bytes that were
 *     written to the stream
 * @cancellable: (nullable): a #GCancellable, or %NULL
 * @error: #GError for error reporting, or %NULL to ignore.
 *
 * Attempts to write the bytes contained in the @n_vectors @vectors to @stream,
 * as with g_output_stream_writev(). If @stream is not currently writable,
 * this will immediately return %@G_POLLABLE_RETURN_WOULD_BLOCK, and you can
 * use g_pollable_output_stream_create_source() to create a #GSource
 * that will be triggered when @stream is writable. @error will *not* be
 * set in that case.
 *
 * Note that since this method never blocks, you cannot actually
 * use @cancellable to cancel it. However, it will return an error
 * if @cancellable has already been cancelled when you call, which
 * may happen if you call this method after a source triggers due
 * to having been cancelled.
 *
 * Also note that if %G_POLLABLE_RETURN_WOULD_BLOCK is returned some underlying
 * transports like D/TLS require that you re-send the same @vectors and
 * @n_vectors in the next write call.
 *
 * Virtual: writev_nonblocking
 *
 * Returns: %@G_POLLABLE_RETURN_OK on success, %G_POLLABLE_RETURN_WOULD_BLOCK
 * if the stream is not currently writable (and @error is *not* set), or
 * %G_POLLABLE_RETURN_FAILED if there was an error in which case @error will
 * be set.
 *
 * Since: 2.60
 */
GPollableReturn
g_pollable_output_stream_writev_nonblocking (GPollableOutputStream  *stream,
					     const GOutputVector    *vectors,
					     gsize                   n_vectors,
					     gsize                  *bytes_written,
					     GCancellable           *cancellable,
					     GError                **error)
{
  GPollableOutputStreamInterface *iface;
  GPollableReturn res;
  gsize _bytes_written = 0;

  if (bytes_written)
    *bytes_written = 0;

  g_return_val_if_fail (G_IS_POLLABLE_OUTPUT_STREAM (stream), G_POLLABLE_RETURN_FAILED);
  g_return_val_if_fail (vectors != NULL || n_vectors == 0, G_POLLABLE_RETURN_FAILED);
  g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), G_POLLABLE_RETURN_FAILED);
  g_return_val_if_fail (error == NULL || *error == NULL, G_POLLABLE_RETURN_FAILED);

  if (g_cancellable_set_error_if_cancelled (cancellable, error))
    return G_POLLABLE_RETURN_FAILED;

  if (n_vectors == 0)
    return G_POLLABLE_RETURN_OK;

  iface = G_POLLABLE_OUTPUT_STREAM_GET_INTERFACE (stream);
  g_return_val_if_fail (iface->writev_nonblocking != NULL, G_POLLABLE_RETURN_FAILED);

  if (cancellable)
    g_cancellable_push_current (cancellable);

  res = iface->
    writev_nonblocking (stream, vectors, n_vectors, &_bytes_written, error);

  if (cancellable)
    g_cancellable_pop_current (cancellable);

  if (res == G_POLLABLE_RETURN_FAILED)
    g_warn_if_fail (error == NULL || (*error != NULL && !g_error_matches (*error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK)));
  else if (res == G_POLLABLE_RETURN_WOULD_BLOCK)
    g_warn_if_fail (error == NULL || *error == NULL);

  /* in case of not-OK nothing must've been written */
  g_warn_if_fail (res == G_POLLABLE_RETURN_OK || _bytes_written == 0);

  if (bytes_written)
    *bytes_written = _bytes_written;

  return res;
}
